1use crate::Error;
2use serde::{Deserialize, Deserializer, Serializer};
3use std::str::FromStr;
4use std::sync::atomic;
5use std::sync::Arc;
6use std::time::Duration;
7
8#[inline]
9pub fn get_eva_dir() -> String {
10 std::env::var("EVA_DIR").unwrap_or_else(|_| "/opt/eva4".to_owned())
11}
12
13#[inline]
14pub fn atomic_true() -> atomic::AtomicBool {
15 atomic::AtomicBool::new(true)
16}
17
18#[inline]
19pub fn arc_atomic_true() -> Arc<atomic::AtomicBool> {
20 Arc::new(atomic::AtomicBool::new(true))
21}
22
23#[derive(Debug)]
24pub enum SocketPath {
25 Tcp(String),
26 Udp(String),
27 Unix(String),
28}
29
30impl FromStr for SocketPath {
31 type Err = Error;
32
33 fn from_str(s: &str) -> Result<Self, Self::Err> {
37 Ok(if s.starts_with("tcp://") {
38 SocketPath::Tcp(s.strip_prefix("tcp://").unwrap().to_owned())
39 } else if s.starts_with("udp://") {
40 SocketPath::Udp(s.strip_prefix("udp://").unwrap().to_owned())
41 } else {
42 SocketPath::Unix(s.to_owned())
43 })
44 }
45}
46
47pub fn format_path(base: &str, path: Option<&str>, default: Option<&str>) -> String {
51 if let Some(p) = path {
52 if p.starts_with('/') {
53 p.to_owned()
54 } else {
55 format!("{}/{}", base, p)
56 }
57 } else if let Some(d) = default {
58 format!("{}/{}", base, d)
59 } else {
60 panic!("unable to format, neither path nor default specified");
61 }
62}
63
64#[macro_export]
65macro_rules! err_logger {
66 () => {
67 pub trait ErrLogger {
68 fn log_ef(self);
70 fn log_efd(self);
72 fn log_err(self) -> Self;
74 fn log_ed(self) -> Self;
76 fn log_ef_with(self, msg: impl ::std::fmt::Display);
78 fn log_efd_with(self, msg: impl ::std::fmt::Display);
80 fn log_err_with(self, msg: impl ::std::fmt::Display) -> Self;
82 fn log_ed_with(self, msg: impl ::std::fmt::Display) -> Self;
84 }
85
86 impl<R, E> ErrLogger for Result<R, E>
87 where
88 E: ::std::fmt::Display,
89 {
90 #[inline]
91 fn log_ef(self) {
92 if let Err(ref e) = self {
93 ::log::error!("{}", e);
94 }
95 }
96 #[inline]
97 fn log_efd(self) {
98 if let Err(ref e) = self {
99 ::log::debug!("{}", e);
100 }
101 }
102 #[inline]
103 fn log_err(self) -> Self {
104 if let Err(ref e) = self {
105 ::log::error!("{}", e);
106 }
107 self
108 }
109 #[inline]
110 fn log_ed(self) -> Self {
111 if let Err(ref e) = self {
112 ::log::debug!("{}", e);
113 }
114 self
115 }
116 #[inline]
117 fn log_ef_with(self, msg: impl ::std::fmt::Display) {
118 if let Err(ref e) = self {
119 ::log::error!("{}: {}", msg, e);
120 }
121 }
122 #[inline]
123 fn log_efd_with(self, msg: impl ::std::fmt::Display) {
124 if let Err(ref e) = self {
125 ::log::debug!("{}: {}", msg, e);
126 }
127 }
128 #[inline]
129 fn log_err_with(self, msg: impl ::std::fmt::Display) -> Self {
130 if let Err(ref e) = self {
131 ::log::error!("{}: {}", msg, e);
132 }
133 self
134 }
135 #[inline]
136 fn log_ed_with(self, msg: impl ::std::fmt::Display) -> Self {
137 if let Err(ref e) = self {
138 ::log::debug!("{}: {}", msg, e);
139 }
140 self
141 }
142 }
143 };
144}
145
146pub fn serialize_atomic_bool<S>(
148 value: &atomic::AtomicBool,
149 serializer: S,
150) -> Result<S::Ok, S::Error>
151where
152 S: Serializer,
153{
154 serializer.serialize_bool(value.load(atomic::Ordering::SeqCst))
155}
156
157pub fn deserialize_atomic_bool<'de, D>(deserializer: D) -> Result<atomic::AtomicBool, D::Error>
158where
159 D: Deserializer<'de>,
160{
161 let val = bool::deserialize(deserializer)?;
162 Ok(atomic::AtomicBool::new(val))
163}
164
165pub fn deserialize_arc_atomic_bool<'de, D>(
166 deserializer: D,
167) -> Result<Arc<atomic::AtomicBool>, D::Error>
168where
169 D: Deserializer<'de>,
170{
171 let val = bool::deserialize(deserializer)?;
172 Ok(Arc::new(atomic::AtomicBool::new(val)))
173}
174
175pub fn serialize_atomic_u64<S>(value: &atomic::AtomicU64, serializer: S) -> Result<S::Ok, S::Error>
176where
177 S: Serializer,
178{
179 serializer.serialize_u64(value.load(atomic::Ordering::SeqCst))
180}
181
182pub fn deserialize_atomic_u64<'de, D>(deserializer: D) -> Result<atomic::AtomicU64, D::Error>
183where
184 D: Deserializer<'de>,
185{
186 let val = u64::deserialize(deserializer)?;
187 Ok(atomic::AtomicU64::new(val))
188}
189
190pub fn deserialize_arc_atomic_u64<'de, D>(
191 deserializer: D,
192) -> Result<Arc<atomic::AtomicU64>, D::Error>
193where
194 D: Deserializer<'de>,
195{
196 let val = u64::deserialize(deserializer)?;
197 Ok(Arc::new(atomic::AtomicU64::new(val)))
198}
199
200pub fn serialize_duration_as_f64<S>(t: &Duration, s: S) -> Result<S::Ok, S::Error>
201where
202 S: Serializer,
203{
204 s.serialize_f64(t.as_secs_f64())
205}
206
207pub fn serialize_duration_as_u64<S>(t: &Duration, s: S) -> Result<S::Ok, S::Error>
208where
209 S: Serializer,
210{
211 s.serialize_u64(t.as_secs())
212}
213
214#[allow(clippy::cast_possible_truncation)]
215pub fn serialize_duration_as_micros<S>(t: &Duration, s: S) -> Result<S::Ok, S::Error>
216where
217 S: Serializer,
218{
219 s.serialize_u64(t.as_micros() as u64)
220}
221
222#[allow(clippy::cast_possible_truncation)]
223pub fn serialize_opt_duration_as_micros<S>(t: &Option<Duration>, s: S) -> Result<S::Ok, S::Error>
224where
225 S: Serializer,
226{
227 if let Some(ref dur) = t {
228 s.serialize_u64(dur.as_micros() as u64)
229 } else {
230 s.serialize_none()
231 }
232}
233
234#[allow(clippy::cast_possible_truncation)]
235pub fn serialize_duration_as_nanos<S>(t: &Duration, s: S) -> Result<S::Ok, S::Error>
236where
237 S: Serializer,
238{
239 s.serialize_u64(t.as_nanos() as u64)
240}
241
242#[allow(clippy::cast_possible_truncation)]
243pub fn serialize_opt_duration_as_nanos<S>(t: &Option<Duration>, s: S) -> Result<S::Ok, S::Error>
244where
245 S: Serializer,
246{
247 if let Some(ref dur) = t {
248 s.serialize_u64(dur.as_nanos() as u64)
249 } else {
250 s.serialize_none()
251 }
252}
253
254pub fn serialize_opt_duration_as_f64<S>(t: &Option<Duration>, s: S) -> Result<S::Ok, S::Error>
255where
256 S: Serializer,
257{
258 if let Some(ref dur) = t {
259 s.serialize_f64(dur.as_secs_f64())
260 } else {
261 s.serialize_none()
262 }
263}
264
265pub fn deserialize_duration_from_micros<'de, D>(deserializer: D) -> Result<Duration, D::Error>
266where
267 D: Deserializer<'de>,
268{
269 Ok(Duration::from_micros(u64::deserialize(deserializer)?))
270}
271
272pub fn deserialize_duration_from_nanos<'de, D>(deserializer: D) -> Result<Duration, D::Error>
273where
274 D: Deserializer<'de>,
275{
276 Ok(Duration::from_nanos(u64::deserialize(deserializer)?))
277}
278
279pub fn de_float_as_duration<'de, D>(deserializer: D) -> Result<Duration, D::Error>
280where
281 D: Deserializer<'de>,
282{
283 Ok(Duration::from_secs_f64(f64::deserialize(deserializer)?))
284}
285
286pub fn de_opt_float_as_duration<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
287where
288 D: Deserializer<'de>,
289{
290 let t: Option<f64> = Option::deserialize(deserializer)?;
291 Ok(t.map(Duration::from_secs_f64))
292}
293
294#[allow(clippy::cast_possible_truncation)]
295#[allow(clippy::cast_sign_loss)]
296pub fn de_float_as_duration_us<'de, D>(deserializer: D) -> Result<Duration, D::Error>
297where
298 D: Deserializer<'de>,
299{
300 Ok(Duration::from_nanos(
301 (f64::deserialize(deserializer)? * 1000.0) as u64,
302 ))
303}
304
305#[allow(clippy::cast_possible_truncation)]
306#[allow(clippy::cast_sign_loss)]
307pub fn de_opt_float_as_duration_us<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
308where
309 D: Deserializer<'de>,
310{
311 let t: Option<f64> = Option::deserialize(deserializer)?;
312 Ok(t.map(|v| Duration::from_nanos((v * 1000.0) as u64)))
313}
314
315#[inline]
316pub fn default_true() -> bool {
317 true
318}
319
320#[inline]
321pub fn is_true(b: &bool) -> bool {
322 *b
323}