axum_bootstrap/util/
json.rs1use std::fmt::Display;
2use std::str::FromStr;
3use std::{borrow::Cow, fmt};
4
5use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
6
7#[allow(dead_code)]
9fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
10where
11 D: Deserializer<'de>,
12 T: FromStr,
13 T::Err: fmt::Display,
14{
15 let opt = Option::<String>::deserialize(de)?;
16 match opt.as_deref() {
17 None | Some("") => Ok(None),
18 Some(s) => FromStr::from_str(s).map_err(de::Error::custom).map(Some),
19 }
20}
21
22#[derive(Debug, Clone, Default, PartialEq, Eq)]
23pub struct StupidValue<T>(pub T);
24
25impl<T> Serialize for StupidValue<T>
26where
27 T: ToString,
28{
29 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
30 where
31 S: Serializer,
32 {
33 self.0.to_string().serialize(serializer)
34 }
35}
36
37impl<'de, T> Deserialize<'de> for StupidValue<T>
38where
39 T: FromStr + Deserialize<'de>,
40 T::Err: Display,
41{
42 fn deserialize<D>(deserializer: D) -> Result<StupidValue<T>, D::Error>
43 where
44 D: Deserializer<'de>,
45 {
46 #[derive(Deserialize)]
47 #[serde(untagged)]
48 enum StrOrValue<'a, T> {
49 Str(Cow<'a, str>),
50 Value(T),
51 }
52
53 let str_or_val = StrOrValue::<T>::deserialize(deserializer)?;
54 Ok(StupidValue(match str_or_val {
55 StrOrValue::Value(val) => val,
56 StrOrValue::Str(s) => s.parse().map_err(serde::de::Error::custom)?,
57 }))
58 }
59}
60
61impl<T> From<T> for StupidValue<T> {
62 fn from(val: T) -> Self {
63 StupidValue(val)
64 }
65}
66
67pub mod my_date_format {
68 use chrono::NaiveDateTime;
69 use serde::{self, Deserialize, Deserializer, Serializer};
70
71 const FORMAT: &str = "%Y-%m-%d %H:%M:%S";
72
73 pub fn serialize<S>(date: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
74 where
75 S: Serializer,
76 {
77 let s = format!("{}", date.format(FORMAT));
78 serializer.serialize_str(&s)
79 }
80
81 pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
82 where
83 D: Deserializer<'de>,
84 {
85 let s = String::deserialize(deserializer)?;
86 let dt = NaiveDateTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)?;
87 Ok(dt)
88 }
89}
90
91pub mod my_date_format_option {
92 use super::my_date_format;
93 use chrono::NaiveDateTime;
94 use serde::{self, Deserialize, Deserializer, Serializer};
95
96 const FORMAT: &str = "%Y-%m-%d %H:%M:%S";
97
98 pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
99 where
100 S: Serializer,
101 {
102 match *opt {
103 Some(ref dt) => my_date_format::serialize(dt, serializer),
104 None => serializer.serialize_none(),
105 }
106 }
107
108 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<NaiveDateTime>, D::Error>
109 where
110 D: Deserializer<'de>,
111 {
112 match Option::<String>::deserialize(deserializer)? {
113 Some(s) => {
114 let dt = NaiveDateTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)?;
115 Ok(Some(dt))
116 }
117 None => Ok(None),
118 }
119 }
120}