Skip to main content

matchmaker/utils/
serde.rs

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