1use std::fmt::Display;
17use std::str::FromStr;
18
19use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
20
21#[derive(Clone, Copy, Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd)]
24pub struct SerdeStr<T> {
25 pub value: T,
27}
28
29impl<T> SerdeStr<T> {
30 #[inline]
32 pub fn value(&self) -> &T {
33 &self.value
34 }
35
36 #[inline]
38 pub fn value_mut(&mut self) -> &mut T {
39 &mut self.value
40 }
41
42 #[inline]
44 pub fn set_value(&mut self, t: T) {
45 self.value = t;
46 }
47
48 #[inline]
50 pub fn unwrap(self) -> T {
51 self.value
52 }
53}
54
55impl<T> From<T> for SerdeStr<T> {
57 #[inline]
58 fn from(value: T) -> Self {
59 Self { value }
60 }
61}
62
63impl<'de, T: FromStr> Deserialize<'de> for SerdeStr<T>
64where
65 T: FromStr,
66 <T as FromStr>::Err: Display,
67{
68 #[inline]
69 fn deserialize<D>(de: D) -> Result<Self, D::Error>
70 where
71 D: Deserializer<'de>,
72 {
73 Ok(Self {
74 value: String::deserialize(de)?
75 .parse()
76 .map_err(|err| Error::custom(err))?,
77 })
78 }
79}
80
81impl<T> Serialize for SerdeStr<T>
82where
83 T: Display,
84{
85 #[inline]
86 fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
87 where
88 S: Serializer,
89 {
90 self.value.to_string().serialize(ser)
91 }
92}
93
94#[cfg(test)]
95mod test_de {
96 use std::collections::HashMap;
97
98 use serde_derive::Deserialize;
99
100 use crate::SerdeStr;
101
102 #[derive(Debug, PartialEq)]
103 struct IsParsed(i32);
104
105 impl std::str::FromStr for IsParsed {
106 type Err = &'static str;
107
108 fn from_str(str: &str) -> Result<Self, Self::Err> {
109 Ok(IsParsed(str.len() as i32))
110 }
111 }
112
113 #[derive(Debug, Deserialize, PartialEq)]
114 struct Schema {
115 data: SerdeStr<IsParsed>,
116 }
117
118 #[test]
119 fn test_parse() {
120 let mut map = HashMap::new();
121 map.insert("data", "abc");
122 let json = serde_json::to_string(&map).unwrap();
123 let parsed = serde_json::from_str::<Schema>(&json);
124 assert_eq!(
125 parsed.unwrap(),
126 Schema {
127 data: SerdeStr { value: IsParsed(3) }
128 }
129 );
130 }
131}
132
133#[cfg(test)]
134mod test_ser {
135 use std::fmt::{Display, Formatter, Result};
136
137 use serde_derive::Serialize;
138
139 use crate::SerdeStr;
140
141 #[derive(Debug)]
142 struct CanDisplay(&'static str);
143
144 impl Display for CanDisplay {
145 fn fmt(&self, f: &mut Formatter) -> Result {
146 write!(f, "{}", self.0.len())
147 }
148 }
149
150 #[derive(Debug, Serialize)]
151 struct Schema {
152 data: SerdeStr<CanDisplay>,
153 }
154
155 #[test]
156 fn test_display() {
157 let json = serde_json::to_string(&Schema {
158 data: SerdeStr {
159 value: CanDisplay("abc"),
160 },
161 });
162 assert_eq!(json.unwrap(), r##"{"data":"3"}"##);
163 }
164}