matchmaker/utils/
serde.rs1#![allow(unused)]
2use cli_boilerplate_automation::wbog;
3use serde::{Deserialize, Deserializer, Serialize, de};
4
5use crate::utils::text::parse_escapes;
6
7pub mod fromstr {
8 use serde::{Deserialize, Deserializer, Serializer, de};
9 use std::fmt::Display;
10 use std::str::FromStr;
11
12 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
13 where
14 T: Display,
15 S: Serializer,
16 {
17 serializer.serialize_str(&value.to_string())
18 }
19
20 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
21 where
22 T: FromStr,
23 T::Err: Display,
24 D: Deserializer<'de>,
25 {
26 let s = String::deserialize(deserializer)?;
27 T::from_str(&s).map_err(de::Error::custom)
28 }
29}
30
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32#[serde(untagged)]
33pub enum StringOrVec {
34 String(String),
35 Vec(Vec<String>),
36}
37impl Default for StringOrVec {
38 fn default() -> Self {
39 StringOrVec::String(String::new())
40 }
41}
42
43pub fn bounded_usize<'de, const MAX: usize, D>(d: D) -> Result<usize, D::Error>
44where
45 D: Deserializer<'de>,
46{
47 let v = usize::deserialize(d)?;
48 if v > MAX {
49 wbog!("{} exceeded the the limit of {} and was clamped.", v, MAX);
50 Ok(MAX)
51 } else {
52 Ok(v)
53 }
55}
56
57pub fn escaped_opt_string<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
58where
59 D: serde::Deserializer<'de>,
60{
61 let opt = Option::<String>::deserialize(deserializer)?;
62 Ok(opt.map(|s| parse_escapes(&s)))
63}
64
65pub fn escaped_opt_char<'de, D>(deserializer: D) -> Result<Option<char>, D::Error>
66where
67 D: serde::Deserializer<'de>,
68{
69 let opt = Option::<String>::deserialize(deserializer)?;
70 match opt {
71 Some(s) => {
72 let parsed = parse_escapes(&s);
73 let mut chars = parsed.chars();
74 let first = chars
75 .next()
76 .ok_or_else(|| serde::de::Error::custom("escaped string is empty"))?;
77 if chars.next().is_some() {
78 return Err(serde::de::Error::custom(
79 "escaped string must be exactly one character",
80 ));
81 }
82 Ok(Some(first))
83 }
84 None => Ok(None),
85 }
86}
87
88pub mod serde_duration_ms {
89 use serde::{Deserialize, Deserializer, Serializer};
90 use std::time::Duration;
91
92 pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: Serializer,
95 {
96 let ms = duration.as_millis() as u64;
97 serializer.serialize_u64(ms)
98 }
99
100 pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
101 where
102 D: Deserializer<'de>,
103 {
104 let ms = u64::deserialize(deserializer)?;
105 Ok(Duration::from_millis(ms))
106 }
107}