1use std::{collections::BTreeMap, convert::TryFrom, iter::FromIterator};
2
3use ordered_float::OrderedFloat;
4use rkyv::{
5 ser::{ScratchSpace, Serializer},
6 Serialize,
7};
8use rkyv::{Archive, Archived, Deserialize, Fallible};
9
10use crate::{IArray, INumber, IObject, IString};
11
12use super::value::IValue;
13
14#[derive(
15 Debug, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, PartialOrd, PartialEq, Eq, Ord,
16)]
17#[archive(bound(serialize = "__S: rkyv::ser::ScratchSpace + rkyv::ser::Serializer"))]
18#[archive(check_bytes)]
19#[archive_attr(check_bytes(
20 bound = "__C: rkyv::validation::ArchiveContext, <__C as rkyv::Fallible>::Error: rkyv::bytecheck::Error"
21))]
22#[archive_attr(derive(PartialEq, Eq, PartialOrd, Ord))]
23pub enum ArchivableJson {
24 Null,
25 Bool(bool),
26 Number(JsonNumber),
27 String(String),
28 Array(
29 #[omit_bounds]
30 #[archive_attr(omit_bounds)]
31 Vec<ArchivableJson>,
32 ),
33 Object(
34 #[omit_bounds]
35 #[archive_attr(omit_bounds)]
36 BTreeMap<String, ArchivableJson>,
37 ),
38}
39
40#[derive(Archive, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord)]
41#[archive(check_bytes)]
42#[archive_attr(derive(PartialEq, Eq, PartialOrd, Ord))]
43pub enum JsonNumber {
44 PosInt(u64),
45 NegInt(i64),
46 Float(OrderedFloat<f64>),
47}
48
49impl From<&IValue> for ArchivableJson {
50 fn from(value: &IValue) -> Self {
51 match value.destructure_ref() {
52 crate::DestructuredRef::Null => ArchivableJson::Null,
53 crate::DestructuredRef::Bool(b) => ArchivableJson::Bool(b),
54 crate::DestructuredRef::Number(n) => ArchivableJson::Number({
55 if n.has_decimal_point() {
56 JsonNumber::Float(n.to_f64().unwrap().into())
57 } else if let Some(v) = n.to_i64() {
58 JsonNumber::NegInt(v)
59 } else {
60 JsonNumber::PosInt(n.to_u64().unwrap())
61 }
62 }),
63 crate::DestructuredRef::String(s) => ArchivableJson::String(s.to_string()),
64 crate::DestructuredRef::Array(a) => {
65 ArchivableJson::Array(a.into_iter().map(ArchivableJson::from).collect())
66 }
67 crate::DestructuredRef::Object(obj) => ArchivableJson::Object(
68 obj.into_iter()
69 .map(|(k, v)| (k.to_string(), ArchivableJson::from(v)))
70 .collect(),
71 ),
72 }
73 }
74}
75
76impl From<IValue> for ArchivableJson {
77 fn from(value: IValue) -> Self {
78 ArchivableJson::from(&value)
79 }
80}
81
82impl From<ArchivableJson> for IValue {
83 fn from(value: ArchivableJson) -> Self {
84 match value {
85 ArchivableJson::Null => IValue::NULL,
86 ArchivableJson::Bool(b) => {
87 if b {
88 IValue::TRUE
89 } else {
90 IValue::FALSE
91 }
92 }
93 ArchivableJson::Number(n) => match n {
94 JsonNumber::PosInt(u) => INumber::from(u).into(),
95 JsonNumber::NegInt(neg) => INumber::from(neg).into(),
96 JsonNumber::Float(f) => INumber::try_from(f.into_inner())
97 .expect("unexpected float")
98 .into(),
99 },
100 ArchivableJson::String(s) => IString::from(s).into(),
101 ArchivableJson::Array(arr) => {
102 let new: Vec<IValue> = arr.into_iter().map(IValue::from).collect();
103 IArray::from(new).into()
104 }
105 ArchivableJson::Object(obj) => IObject::from_iter(obj).into(),
106 }
107 }
108}
109
110impl<S: Serializer + ScratchSpace> Serialize<S> for IValue {
111 fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
112 ArchivableJson::from(self).serialize(serializer)
113 }
114}
115
116impl Archive for IValue {
117 type Archived = <ArchivableJson as Archive>::Archived;
118 type Resolver = <ArchivableJson as Archive>::Resolver;
119
120 unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
121 ArchivableJson::from(self).resolve(pos, resolver, out)
122 }
123}
124
125impl<D: Fallible + ?Sized> Deserialize<IValue, D> for Archived<IValue> {
126 fn deserialize(&self, deserializer: &mut D) -> Result<IValue, D::Error> {
127 let r: ArchivableJson = rkyv::Deserialize::deserialize(self, deserializer)?;
128
129 Ok(IValue::from(r))
130 }
131}
132
133impl<S: Serializer + ScratchSpace> Serialize<S> for IString {
134 fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
135 self.to_string().serialize(serializer)
136 }
137}
138
139impl Archive for IString {
140 type Archived = <String as Archive>::Archived;
141 type Resolver = <String as Archive>::Resolver;
142
143 unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
144 self.to_string().resolve(pos, resolver, out)
145 }
146}
147
148impl<D: Fallible + ?Sized> Deserialize<IString, D> for Archived<IString> {
149 fn deserialize(&self, deserializer: &mut D) -> Result<IString, D::Error> {
150 let r: String = rkyv::Deserialize::deserialize(self, deserializer)?;
151
152 Ok(IString::from(r))
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use rkyv::Deserialize;
159
160 use crate::{IString, IValue};
161
162 use super::ArchivableJson;
163
164 #[test]
165 fn test_serialization() {
166 let x: IValue = serde_json::from_str(
167 r#"
168 {
169 "songs": [
170 {
171 "title": "Fairies Wear Boots",
172 "artist": "Black Sabbath",
173 "album": "Paranoid",
174 "release_year": 1970,
175 "genre": ["Heavy Metal", "Hard Rock"]
176 },
177 {
178 "title": "Whole Lotta Love",
179 "artist": "Led Zeppelin",
180 "album": "Led Zeppelin II",
181 "release_year": 1969,
182 "genre": ["Hard Rock", "Blues Rock"]
183 },
184 {
185 "title": "Hysteria",
186 "artist": "Muse",
187 "album": "Absolution",
188 "release_year": 2003,
189 "genre": ["Alternative Rock", "Art Rock"]
190 },
191 {
192 "title": "Bohemian Rhapsody",
193 "artist": "Queen",
194 "album": "A Night at the Opera",
195 "release_year": 1975,
196 "genre": ["Progressive Rock", "Symphonic Rock"]
197 },
198 {
199 "title": "Hotel California",
200 "artist": "Eagles",
201 "album": "Hotel California",
202 "release_year": 1976,
203 "genre": ["Rock", "Soft Rock"]
204 },
205 {
206 "title": "Smells Like Teen Spirit",
207 "artist": "Nirvana",
208 "album": "Nevermind",
209 "release_year": 1991,
210 "genre": ["Grunge", "Alternative Rock"]
211 },
212 {
213 "title": "Stairway to Heaven",
214 "artist": "Led Zeppelin",
215 "album": "Led Zeppelin IV",
216 "release_year": 1971,
217 "genre": ["Hard Rock", "Folk Rock"]
218 },
219 {
220 "title": "Imagine",
221 "artist": "John Lennon",
222 "album": "Imagine",
223 "release_year": 1971,
224 "genre": ["Soft Rock", "Pop"]
225 },
226 {
227 "title": "Yesterday",
228 "artist": "The Beatles",
229 "album": "Help!",
230 "release_year": 1965,
231 "genre": ["Folk Rock", "Baroque Pop"]
232 }
233 ]
234 }
235 "#,
236 )
237 .unwrap();
238
239 let encoded = rkyv::to_bytes::<_, 256>(&x).unwrap();
240 let archived = unsafe { rkyv::archived_root::<ArchivableJson>(&encoded[..]) };
241 let decoded: IValue = archived.deserialize(&mut rkyv::Infallible).unwrap();
242
243 assert_eq!(x, decoded);
244 }
245
246 #[test]
247 fn test_string_serialization() {
248 let s = "hello".to_string();
249
250 let encoded = rkyv::to_bytes::<_, 256>(&s).unwrap();
251 let archived = unsafe { rkyv::archived_root::<String>(&encoded[..]) };
252 let decoded: IString = archived.deserialize(&mut rkyv::Infallible).unwrap();
253
254 assert_eq!(s, decoded);
255 }
256}