1pub mod hex_slice {
2 use std::fmt;
5
6 pub struct HexSlice<'a>(pub &'a [u8]);
10
11 impl<'a> fmt::Debug for HexSlice<'a> {
12 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13 for b in self.0.iter() {
14 write!(f, "{:0>2x}", *b)?;
15 }
16
17 Ok(())
18 }
19 }
20
21 impl<'a> fmt::Display for HexSlice<'a> {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 write!(f, "{self:?}")
24 }
25 }
26}
27
28pub mod chrono {
30 pub mod optional_duration {
31 use chrono::TimeDelta;
32 use serde::{Deserialize, Deserializer, Serializer};
33
34 pub fn serialize<S>(duration: &Option<TimeDelta>, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: Serializer,
37 {
38 match duration.as_ref() {
39 Some(duration) => {
40 serializer.serialize_some(fundu::Duration::from(*duration).to_string().as_str())
41 }
42 None => serializer.serialize_none(),
43 }
44 }
45 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<TimeDelta>, D::Error>
46 where
47 D: Deserializer<'de>,
48 {
49 Option::<&str>::deserialize(deserializer)?
50 .map(|s| {
51 fundu::DurationParser::new()
52 .parse(s)
53 .map_err(serde::de::Error::custom)?
54 .try_into()
55 .map_err(serde::de::Error::custom)
56 })
57 .transpose()
58 }
59 }
60
61 pub mod duration {
62 use chrono::TimeDelta;
63 use serde::{Deserialize, Deserializer, Serializer};
64
65 pub fn serialize<S>(duration: &TimeDelta, serializer: S) -> Result<S::Ok, S::Error>
66 where
67 S: Serializer,
68 {
69 serializer.serialize_str(fundu::Duration::from(*duration).to_string().as_str())
70 }
71
72 pub fn deserialize<'de, D>(deserializer: D) -> Result<TimeDelta, D::Error>
73 where
74 D: Deserializer<'de>,
75 {
76 String::deserialize(deserializer)
77 .map(|s| {
78 fundu::DurationParser::new()
79 .parse(&s)
80 .map_err(serde::de::Error::custom)?
81 .try_into()
82 .map_err(serde::de::Error::custom)
83 })
84 .and_then(|x| x)
86 }
87 }
88}