serde_cs/
vec.rs

1use serde::de;
2use serde::ser;
3
4use std::str::FromStr;
5use std::{fmt, vec};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct CS<T>(pub Vec<T>);
9
10impl<T> Default for CS<T> {
11    #[inline]
12    fn default() -> Self {
13        Self(Default::default())
14    }
15}
16
17impl<T> AsRef<[T]> for CS<T> {
18    #[inline]
19    fn as_ref(&self) -> &[T] {
20        &self.0
21    }
22}
23
24impl<T> From<Vec<T>> for CS<T> {
25    #[inline]
26    fn from(v: Vec<T>) -> Self {
27        Self(v)
28    }
29}
30
31impl<T> CS<T> {
32    #[inline]
33    pub fn into_inner(self) -> Vec<T> {
34        self.0
35    }
36
37    #[inline]
38    pub fn to_inner(&self) -> &Vec<T> {
39        &self.0
40    }
41
42    #[inline]
43    pub fn to_inner_mut(&mut self) -> &mut Vec<T> {
44        &mut self.0
45    }
46}
47
48impl<T: FromStr> FromStr for CS<T> {
49    type Err = T::Err;
50
51    fn from_str(s: &str) -> Result<Self, Self::Err> {
52        s.split(',')
53            .filter(|s| !s.is_empty())
54            .map(T::from_str)
55            .collect::<Result<Vec<_>, _>>()
56            .map(Self)
57    }
58}
59
60impl<T> IntoIterator for CS<T> {
61    type Item = T;
62    type IntoIter = vec::IntoIter<T>;
63
64    fn into_iter(self) -> Self::IntoIter {
65        self.0.into_iter()
66    }
67}
68
69impl<T: fmt::Display> fmt::Display for CS<T> {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        let mut it = self.0.iter();
72        if let Some(v) = it.next() {
73            <T as fmt::Display>::fmt(v, f)?;
74        }
75
76        for v in it {
77            write!(f, ",{}", v)?
78        }
79
80        Ok(())
81    }
82}
83
84impl<T: fmt::Display> ser::Serialize for CS<T> {
85    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86    where
87        S: ser::Serializer,
88    {
89        serializer.serialize_str(&self.to_string())
90    }
91}
92
93impl<'de, T> de::Deserialize<'de> for CS<T>
94where
95    T: FromStr,
96    T::Err: fmt::Display,
97{
98    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
99    where
100        D: de::Deserializer<'de>,
101    {
102        use std::marker::PhantomData;
103
104        struct CsVisitor<T>(PhantomData<T>);
105
106        impl<'de, T> de::Visitor<'de> for CsVisitor<T>
107        where
108            T: FromStr,
109            T::Err: fmt::Display,
110        {
111            type Value = CS<T>;
112
113            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
114                formatter.write_str("comma separeted list")
115            }
116
117            fn visit_str<E>(self, values: &str) -> Result<Self::Value, E>
118            where
119                E: de::Error,
120            {
121                values.parse().map_err(de::Error::custom)
122            }
123        }
124
125        deserializer.deserialize_str(CsVisitor(PhantomData))
126    }
127}
128
129#[cfg(test)]
130mod tests {
131    use super::CS;
132    type CsTest = CS<u32>;
133
134    fn assert_ok_from_str(s: &str, expected: Vec<u32>) {
135        let cs: Result<CsTest, _> = s.parse();
136        assert!(matches!(cs, Ok(v) if v == CS(expected)))
137    }
138
139    fn assert_err_from_str(s: &str) {
140        let cs: Result<CsTest, _> = s.parse();
141        assert!(cs.is_err())
142    }
143
144    #[test]
145    fn from_str() {
146        assert_ok_from_str("", vec![]);
147        assert_ok_from_str(",,,,", vec![]);
148
149        assert_ok_from_str("1", vec![1]);
150        assert_ok_from_str(",1", vec![1]);
151        assert_ok_from_str("1,", vec![1]);
152        assert_ok_from_str(",,,1,", vec![1]);
153
154        assert_ok_from_str("1,2", vec![1, 2]);
155        assert_ok_from_str("1,2,3,4,5", vec![1, 2, 3, 4, 5]);
156        assert_ok_from_str("1,,,,,2", vec![1, 2]);
157        assert_ok_from_str(",,,1,,,,,2,,,,,", vec![1, 2]);
158
159        assert_err_from_str("-1");
160        assert_err_from_str("1,a,");
161    }
162
163    fn assert_to_string(values: Vec<u32>, expected: &str) {
164        let cs = CS(values).to_string();
165        assert_eq!(cs, expected);
166    }
167
168    #[test]
169    fn to_string() {
170        assert_to_string(vec![], "");
171        assert_to_string(vec![1], "1");
172        assert_to_string(vec![1, 2], "1,2");
173        assert_to_string(vec![1, 2, 3, 4, 5], "1,2,3,4,5");
174    }
175
176    fn assert_ok_des(s: &str, expected: Vec<u32>) {
177        let cs: Result<CsTest, _> = serde_json::from_str(s);
178        assert!(matches!(cs, Ok(v) if v == CS(expected)))
179    }
180
181    fn assert_err_des(s: &str) {
182        let cs: Result<CsTest, _> = serde_json::from_str(s);
183        assert!(cs.is_err())
184    }
185
186    #[test]
187    fn deserialize() {
188        assert_ok_des(r#""""#, vec![]);
189        assert_ok_des(r#"",,,,""#, vec![]);
190
191        assert_ok_des(r#""1""#, vec![1]);
192        assert_ok_des(r#"",1""#, vec![1]);
193        assert_ok_des(r#""1,""#, vec![1]);
194        assert_ok_des(r#"",,,1,""#, vec![1]);
195
196        assert_ok_des(r#""1,2""#, vec![1, 2]);
197        assert_ok_des(r#""1,2,3,4,5""#, vec![1, 2, 3, 4, 5]);
198        assert_ok_des(r#""1,,,,,2""#, vec![1, 2]);
199        assert_ok_des(r#"",,,1,,,,,2,,,,,""#, vec![1, 2]);
200
201        assert_err_des(r#""-1""#);
202        assert_err_des(r#""1,a,""#);
203    }
204
205    fn assert_ser(values: Vec<u32>, expected: &str) {
206        let cs = serde_json::to_string(&CS(values));
207        assert!(matches!(cs, Ok(v) if v == expected))
208    }
209
210    #[test]
211    fn serialize() {
212        assert_ser(vec![], r#""""#);
213        assert_ser(vec![1], r#""1""#);
214        assert_ser(vec![1, 2], r#""1,2""#);
215        assert_ser(vec![1, 2, 3, 4, 5], r#""1,2,3,4,5""#);
216    }
217}