1use serde::de::{self, DeserializeOwned, Deserializer, MapAccess, SeqAccess, Visitor};
30use spate_core::hash::QualitySet;
31use std::borrow::Cow;
32use std::fmt;
33
34#[cfg(feature = "simd")]
39pub const BACKEND_ID: &str = "simd-json";
40#[cfg(not(feature = "simd"))]
42pub const BACKEND_ID: &str = "serde_json";
43
44#[derive(Debug)]
53pub(crate) struct DecodeError {
54 pub(crate) is_data: bool,
59 msg: String,
60}
61
62impl fmt::Display for DecodeError {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 f.write_str(&self.msg)
65 }
66}
67
68impl From<serde_json::Error> for DecodeError {
69 fn from(e: serde_json::Error) -> Self {
70 DecodeError {
71 is_data: e.is_data(),
72 msg: e.to_string(),
73 }
74 }
75}
76
77#[cfg(not(feature = "simd"))]
81#[inline]
82pub(crate) fn decode_one<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, DecodeError> {
83 serde_json::from_slice(bytes).map_err(DecodeError::from)
84}
85
86#[cfg(feature = "simd")]
93thread_local! {
94 static SIMD: std::cell::RefCell<(Vec<u8>, simd_json::Buffers)> =
95 std::cell::RefCell::new((Vec::new(), simd_json::Buffers::new(0)));
96}
97
98#[cfg(feature = "simd")]
106#[inline]
107pub(crate) fn decode_one<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, DecodeError> {
108 SIMD.with(|cell| {
109 let (buf, buffers) = &mut *cell.borrow_mut();
110 buf.clear();
111 buf.extend_from_slice(bytes);
112 simd_json::serde::from_slice_with_buffers::<T>(buf.as_mut_slice(), buffers).map_err(|e| {
113 DecodeError {
114 is_data: false,
115 msg: e.to_string(),
116 }
117 })
118 })
119}
120
121pub(crate) fn check_no_duplicate_keys(bytes: &[u8]) -> Result<(), DecodeError> {
129 serde_json::from_slice::<DupGuard>(bytes)
132 .map(|_| ())
133 .map_err(DecodeError::from)
134}
135
136struct DupGuard;
140
141impl<'de> serde::Deserialize<'de> for DupGuard {
142 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
143 where
144 D: Deserializer<'de>,
145 {
146 deserializer.deserialize_any(DupVisitor)
147 }
148}
149
150struct DupVisitor;
151
152struct Key<'de>(Cow<'de, str>);
155
156impl<'de> serde::Deserialize<'de> for Key<'de> {
157 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
158 where
159 D: Deserializer<'de>,
160 {
161 deserializer.deserialize_str(KeyVisitor)
162 }
163}
164
165struct KeyVisitor;
166
167impl<'de> Visitor<'de> for KeyVisitor {
168 type Value = Key<'de>;
169
170 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 f.write_str("an object key")
172 }
173
174 fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
175 Ok(Key(Cow::Borrowed(v)))
176 }
177
178 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
181 Ok(Key(Cow::Owned(v.to_owned())))
182 }
183}
184
185impl<'de> Visitor<'de> for DupVisitor {
186 type Value = DupGuard;
187
188 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 f.write_str("any JSON value with unique object keys")
190 }
191
192 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
193 where
194 A: MapAccess<'de>,
195 {
196 let mut seen: QualitySet<Cow<'de, str>> = QualitySet::default();
199 while let Some(Key(key)) = map.next_key::<Key<'de>>()? {
200 if let Some(dup) = seen.replace(key) {
201 return Err(de::Error::custom(format!("duplicate object key `{dup}`")));
202 }
203 map.next_value::<DupGuard>()?;
205 }
206 Ok(DupGuard)
207 }
208
209 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
210 where
211 A: SeqAccess<'de>,
212 {
213 while seq.next_element::<DupGuard>()?.is_some() {}
214 Ok(DupGuard)
215 }
216
217 fn visit_bool<E>(self, _v: bool) -> Result<Self::Value, E> {
219 Ok(DupGuard)
220 }
221 fn visit_i64<E>(self, _v: i64) -> Result<Self::Value, E> {
222 Ok(DupGuard)
223 }
224 fn visit_u64<E>(self, _v: u64) -> Result<Self::Value, E> {
225 Ok(DupGuard)
226 }
227 fn visit_f64<E>(self, _v: f64) -> Result<Self::Value, E> {
228 Ok(DupGuard)
229 }
230 fn visit_str<E>(self, _v: &str) -> Result<Self::Value, E> {
231 Ok(DupGuard)
232 }
233 fn visit_none<E>(self) -> Result<Self::Value, E> {
234 Ok(DupGuard)
235 }
236 fn visit_unit<E>(self) -> Result<Self::Value, E> {
237 Ok(DupGuard)
238 }
239 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
240 where
241 D: Deserializer<'de>,
242 {
243 deserializer.deserialize_any(DupVisitor)
244 }
245}
246
247#[cfg(test)]
248mod tests {
249 use super::{Key, check_no_duplicate_keys};
250 use serde::Deserialize;
251 use serde::de::{IgnoredAny, MapAccess, Visitor};
252 use std::borrow::Cow;
253 use std::fmt;
254
255 struct ObjectKeys<'de>(Vec<Cow<'de, str>>);
256
257 impl<'de> Deserialize<'de> for ObjectKeys<'de> {
258 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
259 where
260 D: serde::Deserializer<'de>,
261 {
262 deserializer.deserialize_map(ObjectKeysVisitor)
263 }
264 }
265
266 struct ObjectKeysVisitor;
267
268 impl<'de> Visitor<'de> for ObjectKeysVisitor {
269 type Value = ObjectKeys<'de>;
270
271 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
272 f.write_str("a JSON object")
273 }
274
275 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
276 where
277 A: MapAccess<'de>,
278 {
279 let mut keys = Vec::new();
280 while let Some(Key(key)) = map.next_key::<Key<'de>>()? {
281 map.next_value::<IgnoredAny>()?;
282 keys.push(key);
283 }
284 Ok(ObjectKeys(keys))
285 }
286 }
287
288 #[test]
289 fn an_unescaped_key_borrows_from_the_payload() {
290 let ObjectKeys(keys) = serde_json::from_slice(br#"{"abc":1,"\u0061bc":2}"#).unwrap();
291 assert!(matches!(keys[0], Cow::Borrowed("abc")));
292 assert!(matches!(keys[1], Cow::Owned(_)));
293 }
294
295 #[test]
296 fn duplicate_key_names_the_key() {
297 let err = check_no_duplicate_keys(br#"{"id":1,"id":2}"#).unwrap_err();
298 assert!(err.is_data, "{err}");
299 assert_eq!(
300 err.to_string(),
301 "duplicate object key `id` at line 1 column 12"
302 );
303 }
304
305 #[test]
306 fn escaped_spelling_is_the_same_key() {
307 let err = check_no_duplicate_keys(br#"{"\u0061":1,"a":2}"#).unwrap_err();
308 assert!(err.is_data, "{err}");
309 assert!(
310 err.to_string().starts_with("duplicate object key `a`"),
311 "{err}"
312 );
313 }
314
315 #[test]
319 fn plain_spelling_matches_an_escaped_duplicate() {
320 let err = check_no_duplicate_keys(br#"{"a":1,"\u0061":2}"#).unwrap_err();
321 assert!(err.is_data, "{err}");
322 assert!(
323 err.to_string().starts_with("duplicate object key `a`"),
324 "{err}"
325 );
326 }
327
328 #[test]
329 fn same_key_in_sibling_scopes_is_clean() {
330 check_no_duplicate_keys(br#"{"a":{"a":1},"b":[{"a":1},{"a":2}]}"#).unwrap();
331 }
332}