java_string/
serde.rs

1use std::fmt::Formatter;
2
3use serde::de::value::SeqAccessDeserializer;
4use serde::de::{Error, SeqAccess, Unexpected, Visitor};
5use serde::ser::SerializeSeq;
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8use crate::{JavaCodePoint, JavaStr, JavaString};
9
10impl Serialize for JavaString {
11    #[inline]
12    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
13    where
14        S: Serializer,
15    {
16        match self.as_str() {
17            Ok(str) => str.serialize(serializer),
18            Err(_) => {
19                let mut seq = serializer.serialize_seq(None)?;
20                for ch in self.chars() {
21                    seq.serialize_element(&ch.as_u32())?;
22                }
23                seq.end()
24            }
25        }
26    }
27}
28
29impl<'de> Deserialize<'de> for JavaString {
30    #[inline]
31    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
32    where
33        D: Deserializer<'de>,
34    {
35        deserializer.deserialize_any(JavaStringVisitor)
36    }
37}
38
39struct JavaStringVisitor;
40
41impl<'de> Visitor<'de> for JavaStringVisitor {
42    type Value = JavaString;
43
44    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
45        formatter.write_str("a JavaString")
46    }
47
48    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
49    where
50        E: Error,
51    {
52        Ok(JavaString::from(v))
53    }
54
55    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
56    where
57        E: Error,
58    {
59        Ok(JavaString::from(v))
60    }
61
62    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
63    where
64        E: Error,
65    {
66        match JavaStr::from_semi_utf8(v) {
67            Ok(str) => Ok(str.to_owned()),
68            Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
69        }
70    }
71
72    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
73    where
74        E: Error,
75    {
76        JavaString::from_semi_utf8(v)
77            .map_err(|err| Error::invalid_value(Unexpected::Bytes(&err.into_bytes()), &self))
78    }
79
80    fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
81    where
82        A: SeqAccess<'de>,
83    {
84        let vec = Vec::<u8>::deserialize(SeqAccessDeserializer::new(seq))?;
85        JavaString::from_semi_utf8(vec).map_err(|_| Error::invalid_value(Unexpected::Seq, &self))
86    }
87}
88
89impl Serialize for JavaStr {
90    #[inline]
91    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
92    where
93        S: Serializer,
94    {
95        match self.as_str() {
96            Ok(str) => str.serialize(serializer),
97            Err(_) => {
98                let mut seq = serializer.serialize_seq(None)?;
99                for ch in self.chars() {
100                    seq.serialize_element(&ch.as_u32())?;
101                }
102                seq.end()
103            }
104        }
105    }
106}
107
108impl<'de: 'a, 'a> Deserialize<'de> for &'a JavaStr {
109    #[inline]
110    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
111    where
112        D: Deserializer<'de>,
113    {
114        deserializer.deserialize_any(JavaStrVisitor)
115    }
116}
117
118struct JavaStrVisitor;
119
120impl<'de> Visitor<'de> for JavaStrVisitor {
121    type Value = &'de JavaStr;
122
123    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
124        formatter.write_str("a borrowed JavaStr")
125    }
126
127    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
128    where
129        E: Error,
130    {
131        Ok(JavaStr::from_str(v))
132    }
133
134    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
135    where
136        E: Error,
137    {
138        JavaStr::from_semi_utf8(v).map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self))
139    }
140}
141
142impl Serialize for JavaCodePoint {
143    #[inline]
144    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
145    where
146        S: Serializer,
147    {
148        match self.as_char() {
149            Some(ch) => ch.serialize(serializer),
150            None => self.as_u32().serialize(serializer),
151        }
152    }
153}
154
155impl<'de> Deserialize<'de> for JavaCodePoint {
156    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
157    where
158        D: Deserializer<'de>,
159    {
160        deserializer.deserialize_any(JavaCodePointVisitor)
161    }
162}
163
164struct JavaCodePointVisitor;
165
166impl Visitor<'_> for JavaCodePointVisitor {
167    type Value = JavaCodePoint;
168
169    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
170        formatter.write_str("a character")
171    }
172
173    #[inline]
174    fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
175    where
176        E: Error,
177    {
178        self.visit_i32(v.into())
179    }
180
181    #[inline]
182    fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
183    where
184        E: Error,
185    {
186        self.visit_i32(v.into())
187    }
188
189    fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
190    where
191        E: Error,
192    {
193        if v < 0 {
194            Err(Error::invalid_value(Unexpected::Signed(v.into()), &self))
195        } else {
196            self.visit_u32(v as u32)
197        }
198    }
199
200    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
201    where
202        E: Error,
203    {
204        if v < 0 {
205            Err(Error::invalid_value(Unexpected::Signed(v), &self))
206        } else {
207            self.visit_u64(v as u64)
208        }
209    }
210
211    #[inline]
212    fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
213    where
214        E: Error,
215    {
216        self.visit_u32(v.into())
217    }
218
219    #[inline]
220    fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
221    where
222        E: Error,
223    {
224        self.visit_u32(v.into())
225    }
226
227    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
228    where
229        E: Error,
230    {
231        JavaCodePoint::from_u32(v)
232            .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v.into()), &self))
233    }
234
235    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
236    where
237        E: Error,
238    {
239        match u32::try_from(v) {
240            Ok(v) => self.visit_u32(v),
241            Err(_) => Err(Error::invalid_value(Unexpected::Unsigned(v), &self)),
242        }
243    }
244
245    fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
246    where
247        E: Error,
248    {
249        Ok(JavaCodePoint::from_char(v))
250    }
251
252    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
253    where
254        E: Error,
255    {
256        let mut iter = v.chars();
257        match (iter.next(), iter.next()) {
258            (Some(c), None) => Ok(JavaCodePoint::from_char(c)),
259            _ => Err(Error::invalid_value(Unexpected::Str(v), &self)),
260        }
261    }
262}