1use std::{
2 fmt::{self, Display},
3 ops::RangeInclusive,
4};
5
6use ordered_float::OrderedFloat;
7
8use super::*;
9
10const MAX_JS_INT: i64 = 0x001F_FFFF_FFFF_FFFF;
11const MIN_JS_INT: i64 = -MAX_JS_INT;
13pub const JS_INT_RANGE: RangeInclusive<i64> = MIN_JS_INT..=MAX_JS_INT;
14
15#[derive(Debug, Clone, PartialEq)]
16#[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))]
17#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
18pub enum Any {
19 Undefined,
20 Null,
21 Integer(i32),
22 Float32(OrderedFloat<f32>),
23 Float64(OrderedFloat<f64>),
24 BigInt64(i64),
25 False,
26 True,
27 String(String),
28 #[cfg_attr(test, proptest(skip))]
30 Object(HashMap<String, Any>),
31 #[cfg_attr(test, proptest(skip))]
32 Array(Vec<Any>),
33 Binary(Vec<u8>),
34}
35
36impl<R: CrdtReader> CrdtRead<R> for Any {
37 fn read(reader: &mut R) -> JwstCodecResult<Self> {
38 let index = reader.read_u8()?;
39 match 127u8.overflowing_sub(index).0 {
40 0 => Ok(Any::Undefined),
41 1 => Ok(Any::Null),
42 2 => Ok(Any::Integer(reader.read_var_i32()?)), 3 => Ok(Any::Float32(reader.read_f32_be()?.into())), 4 => Ok(Any::Float64(reader.read_f64_be()?.into())), 5 => Ok(Any::BigInt64(reader.read_i64_be()?)), 6 => Ok(Any::False),
48 7 => Ok(Any::True),
49 8 => Ok(Any::String(reader.read_var_string()?)), 9 => {
51 let len = reader.read_var_u64()?;
52 let object = (0..len)
53 .map(|_| Self::read_key_value(reader))
54 .collect::<Result<Vec<_>, _>>()?;
55
56 Ok(Any::Object(object.into_iter().collect()))
57 } 10 => {
59 let len = reader.read_var_u64()?;
60 let any = (0..len).map(|_| Self::read(reader)).collect::<Result<Vec<_>, _>>()?;
61
62 Ok(Any::Array(any))
63 } 11 => {
65 let binary = reader.read_var_buffer()?;
66 Ok(Any::Binary(binary.to_vec()))
67 } _ => Ok(Any::Undefined),
69 }
70 }
71}
72
73impl<W: CrdtWriter> CrdtWrite<W> for Any {
74 fn write(&self, writer: &mut W) -> JwstCodecResult {
75 match self {
76 Any::Undefined => writer.write_u8(127)?,
77 Any::Null => writer.write_u8(127 - 1)?,
78 Any::Integer(value) => {
79 writer.write_u8(127 - 2)?;
80 writer.write_var_i32(*value)?;
81 }
82 Any::Float32(value) => {
83 writer.write_u8(127 - 3)?;
84 writer.write_f32_be(value.into_inner())?;
85 }
86 Any::Float64(value) => {
87 writer.write_u8(127 - 4)?;
88 writer.write_f64_be(value.into_inner())?;
89 }
90 Any::BigInt64(value) => {
91 writer.write_u8(127 - 5)?;
92 writer.write_i64_be(*value)?;
93 }
94 Any::False => writer.write_u8(127 - 6)?,
95 Any::True => writer.write_u8(127 - 7)?,
96 Any::String(value) => {
97 writer.write_u8(127 - 8)?;
98 writer.write_var_string(value)?;
99 }
100 Any::Object(value) => {
101 writer.write_u8(127 - 9)?;
102 writer.write_var_u64(value.len() as u64)?;
103 for (key, value) in value {
104 Self::write_key_value(writer, key, value)?;
105 }
106 }
107 Any::Array(values) => {
108 writer.write_u8(127 - 10)?;
109 writer.write_var_u64(values.len() as u64)?;
110 for value in values {
111 value.write(writer)?;
112 }
113 }
114 Any::Binary(value) => {
115 writer.write_u8(127 - 11)?;
116 writer.write_var_buffer(value)?;
117 }
118 }
119
120 Ok(())
121 }
122}
123
124impl Any {
125 fn read_key_value<R: CrdtReader>(reader: &mut R) -> JwstCodecResult<(String, Any)> {
126 let key = reader.read_var_string()?;
127 let value = Self::read(reader)?;
128
129 Ok((key, value))
130 }
131
132 fn write_key_value<W: CrdtWriter>(writer: &mut W, key: &str, value: &Any) -> JwstCodecResult {
133 writer.write_var_string(key)?;
134 value.write(writer)?;
135
136 Ok(())
137 }
138
139 pub(crate) fn read_multiple<R: CrdtReader>(reader: &mut R) -> JwstCodecResult<Vec<Any>> {
140 let len = reader.read_var_u64()? as usize;
141 let mut vec = Vec::with_capacity(len);
142 for _ in 0..len {
143 vec.push(Any::read(reader)?);
144 }
145
146 Ok(vec)
147 }
148
149 pub(crate) fn write_multiple<W: CrdtWriter>(writer: &mut W, any: &[Any]) -> JwstCodecResult {
150 writer.write_var_u64(any.len() as u64)?;
151 for value in any {
152 value.write(writer)?;
153 }
154
155 Ok(())
156 }
157}
158
159macro_rules! impl_primitive_from {
160 (unsigned, $($ty: ty),*) => {
161 $(
162 impl From<$ty> for Any {
163 fn from(value: $ty) -> Self {
164 let int: i64 = value as i64;
167 if JS_INT_RANGE.contains(&int) {
169 if int <= i32::MAX as i64 {
170 Self::Integer(int as i32)
171 } else if int as f32 as i64 == int {
172 Self::Float32((int as f32).into())
173 } else {
174 Self::Float64((int as f64).into())
175 }
176 } else {
177 Self::BigInt64(int)
178 }
179 }
180 }
181 )*
182 };
183 (signed, $($ty: ty),*) => {
184 $(
185 impl From<$ty> for Any {
186 fn from(value: $ty) -> Self {
187 let int: i64 = value.into();
188 if JS_INT_RANGE.contains(&int) {
190 if int <= i32::MAX as i64 {
191 Self::Integer(int as i32)
192 } else if int as f32 as i64 == int {
193 Self::Float32((int as f32).into())
194 } else {
195 Self::Float64((int as f64).into())
196 }
197 } else {
198 Self::BigInt64(int)
199 }
200 }
201 }
202 )*
203 };
204 (string, $($ty: ty),*) => {
205 $(
206 impl From<$ty> for Any {
207 fn from(value: $ty) -> Self {
208 Self::String(value.into())
209 }
210 }
211 )*
212 };
213}
214
215impl_primitive_from!(unsigned, u8, u16, u32, u64);
216impl_primitive_from!(signed, i8, i16, i32, i64);
217impl_primitive_from!(string, String, &str);
218
219impl From<usize> for Any {
220 fn from(value: usize) -> Self {
221 (value as u64).into()
222 }
223}
224
225impl From<isize> for Any {
226 fn from(value: isize) -> Self {
227 (value as i64).into()
228 }
229}
230
231impl From<f32> for Any {
232 fn from(value: f32) -> Self {
233 Self::Float32(value.into())
234 }
235}
236
237impl From<f64> for Any {
238 fn from(value: f64) -> Self {
239 if value.trunc() == value {
240 (value as i64).into()
241 } else if value as f32 as f64 == value {
242 Self::Float32((value as f32).into())
243 } else {
244 Self::Float64(value.into())
245 }
246 }
247}
248
249impl From<bool> for Any {
250 fn from(value: bool) -> Self {
251 if value { Self::True } else { Self::False }
252 }
253}
254
255impl TryFrom<Any> for String {
256 type Error = JwstCodecError;
257
258 fn try_from(value: Any) -> Result<Self, Self::Error> {
259 match value {
260 Any::String(s) => Ok(s),
261 _ => Err(JwstCodecError::UnexpectedType("String")),
262 }
263 }
264}
265
266impl TryFrom<Any> for HashMap<String, Any> {
267 type Error = JwstCodecError;
268
269 fn try_from(value: Any) -> Result<Self, Self::Error> {
270 match value {
271 Any::Object(map) => Ok(map),
272 _ => Err(JwstCodecError::UnexpectedType("Object")),
273 }
274 }
275}
276
277impl TryFrom<Any> for Vec<Any> {
278 type Error = JwstCodecError;
279
280 fn try_from(value: Any) -> Result<Self, Self::Error> {
281 match value {
282 Any::Array(vec) => Ok(vec),
283 _ => Err(JwstCodecError::UnexpectedType("Array")),
284 }
285 }
286}
287
288impl TryFrom<Any> for bool {
289 type Error = JwstCodecError;
290
291 fn try_from(value: Any) -> Result<Self, Self::Error> {
292 match value {
293 Any::True => Ok(true),
294 Any::False => Ok(false),
295 _ => Err(JwstCodecError::UnexpectedType("Boolean")),
296 }
297 }
298}
299
300impl FromIterator<Any> for Any {
301 fn from_iter<I: IntoIterator<Item = Any>>(iter: I) -> Self {
302 Self::Array(iter.into_iter().collect())
303 }
304}
305
306impl<'a> FromIterator<&'a Any> for Any {
307 fn from_iter<I: IntoIterator<Item = &'a Any>>(iter: I) -> Self {
308 Self::Array(iter.into_iter().cloned().collect())
309 }
310}
311
312impl FromIterator<(String, Any)> for Any {
313 fn from_iter<I: IntoIterator<Item = (String, Any)>>(iter: I) -> Self {
314 let mut map = HashMap::new();
315 map.extend(iter);
316 Self::Object(map)
317 }
318}
319
320impl From<HashMap<String, Any>> for Any {
321 fn from(value: HashMap<String, Any>) -> Self {
322 Self::Object(value)
323 }
324}
325
326impl From<Vec<u8>> for Any {
327 fn from(value: Vec<u8>) -> Self {
328 Self::Binary(value)
329 }
330}
331
332impl From<&[u8]> for Any {
333 fn from(value: &[u8]) -> Self {
334 Self::Binary(value.into())
335 }
336}
337
338impl<T: Into<Any>> From<Option<T>> for Any {
340 fn from(value: Option<T>) -> Self {
341 if let Some(val) = value { val.into() } else { Any::Null }
342 }
343}
344
345#[cfg(feature = "serde_json")]
346impl From<serde_json::Value> for Any {
347 fn from(value: serde_json::Value) -> Self {
348 match value {
349 serde_json::Value::Null => Self::Null,
350 serde_json::Value::Bool(b) => {
351 if b {
352 Self::True
353 } else {
354 Self::False
355 }
356 }
357 serde_json::Value::Number(n) => {
358 if n.is_f64() {
359 Self::Float64(n.as_f64().unwrap().into())
360 } else if n.is_i64() {
361 Self::Integer(n.as_i64().unwrap() as i32)
362 } else {
363 Self::Integer(n.as_u64().unwrap() as i32)
364 }
365 }
366 serde_json::Value::String(s) => Self::String(s),
367 serde_json::Value::Array(vec) => Self::Array(vec.into_iter().map(|v| v.into()).collect::<Vec<_>>()),
368 serde_json::Value::Object(obj) => Self::Object(obj.into_iter().map(|(k, v)| (k, v.into())).collect()),
369 }
370 }
371}
372
373impl<'de> serde::Deserialize<'de> for Any {
374 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
375 where
376 D: serde::Deserializer<'de>,
377 {
378 use serde::de::{Error, MapAccess, SeqAccess, Visitor};
379 struct ValueVisitor;
380
381 impl<'de> Visitor<'de> for ValueVisitor {
382 type Value = Any;
383
384 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
385 formatter.write_str("any valid JSON value")
386 }
387
388 #[inline]
389 fn visit_bool<E>(self, value: bool) -> Result<Any, E> {
390 Ok(if value { Any::True } else { Any::False })
391 }
392
393 #[inline]
394 fn visit_i64<E>(self, value: i64) -> Result<Any, E> {
395 Ok(Any::BigInt64(value))
396 }
397
398 #[inline]
399 fn visit_u64<E>(self, value: u64) -> Result<Any, E> {
400 Ok((value as i64).into())
401 }
402
403 #[inline]
404 fn visit_f64<E>(self, value: f64) -> Result<Any, E> {
405 Ok(Any::Float64(OrderedFloat(value)))
406 }
407
408 #[inline]
409 fn visit_str<E>(self, value: &str) -> Result<Any, E>
410 where
411 E: Error,
412 {
413 self.visit_string(String::from(value))
414 }
415
416 #[inline]
417 fn visit_string<E>(self, value: String) -> Result<Any, E> {
418 Ok(Any::String(value))
419 }
420
421 #[inline]
422 fn visit_none<E>(self) -> Result<Any, E> {
423 Ok(Any::Null)
424 }
425
426 #[inline]
427 fn visit_some<D>(self, deserializer: D) -> Result<Any, D::Error>
428 where
429 D: serde::Deserializer<'de>,
430 {
431 serde::Deserialize::deserialize(deserializer)
432 }
433
434 #[inline]
435 fn visit_unit<E>(self) -> Result<Any, E> {
436 Ok(Any::Null)
437 }
438
439 #[inline]
440 fn visit_seq<V>(self, mut visitor: V) -> Result<Any, V::Error>
441 where
442 V: SeqAccess<'de>,
443 {
444 let mut vec = Vec::new();
445
446 while let Some(elem) = visitor.next_element()? {
447 vec.push(elem);
448 }
449
450 Ok(Any::Array(vec))
451 }
452
453 fn visit_map<V>(self, mut visitor: V) -> Result<Any, V::Error>
454 where
455 V: MapAccess<'de>,
456 {
457 match visitor.next_key::<String>()? {
458 Some(k) => {
459 let mut values = HashMap::new();
460
461 values.insert(k, visitor.next_value()?);
462 while let Some((key, value)) = visitor.next_entry()? {
463 values.insert(key, value);
464 }
465
466 Ok(Any::Object(values))
467 }
468 None => Ok(Any::Object(HashMap::new())),
469 }
470 }
471 }
472
473 deserializer.deserialize_any(ValueVisitor)
474 }
475}
476
477impl serde::Serialize for Any {
478 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
479 where
480 S: serde::Serializer,
481 {
482 use serde::ser::{SerializeMap, SerializeSeq};
483
484 match self {
485 Any::Null => serializer.serialize_none(),
486 Any::Undefined => serializer.serialize_none(),
487 Any::True => serializer.serialize_bool(true),
488 Any::False => serializer.serialize_bool(false),
489 Any::Float32(value) => serializer.serialize_f32(value.0),
490 Any::Float64(value) => serializer.serialize_f64(value.0),
491 Any::Integer(value) => serializer.serialize_i32(*value),
492 Any::BigInt64(value) => serializer.serialize_i64(*value),
493 Any::String(value) => serializer.serialize_str(value.as_ref()),
494 Any::Array(values) => {
495 let mut seq = serializer.serialize_seq(Some(values.len()))?;
496 for value in values.iter() {
497 seq.serialize_element(value)?;
498 }
499 seq.end()
500 }
501 Any::Object(entries) => {
502 let mut map = serializer.serialize_map(Some(entries.len()))?;
503 for (key, value) in entries.iter() {
504 map.serialize_entry(key, value)?;
505 }
506 map.end()
507 }
508 Any::Binary(buf) => serializer.serialize_bytes(buf),
509 }
510 }
511}
512
513impl Display for Any {
514 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
515 match self {
516 Self::True => write!(f, "true"),
517 Self::False => write!(f, "false"),
518 Self::String(s) => write!(f, "\"{}\"", s),
519 Self::Integer(i) => write!(f, "{}", i),
520 Self::Float32(v) => write!(f, "{}", v),
521 Self::Float64(v) => write!(f, "{}", v),
522 Self::BigInt64(v) => write!(f, "{}", v),
523 Self::Object(map) => {
524 write!(f, "{{")?;
525 for (i, (key, value)) in map.iter().enumerate() {
526 if i > 0 {
527 write!(f, ", ")?;
528 }
529 write!(f, "{}: {}", key, value)?;
530 }
531 write!(f, "}}")
532 }
533 Self::Array(vec) => {
534 write!(f, "[")?;
535 for (i, value) in vec.iter().enumerate() {
536 if i > 0 {
537 write!(f, ", ")?;
538 }
539 write!(f, "{}", value)?;
540 }
541 write!(f, "]")
542 }
543 Self::Binary(buf) => write!(f, "{:?}", buf),
544 Self::Undefined => write!(f, "undefined"),
545 Self::Null => write!(f, "null"),
546 }
547 }
548}
549
550#[cfg(test)]
551mod tests {
552 use proptest::{collection::vec, prelude::*};
553
554 use super::*;
555
556 #[test]
557 fn test_any_codec() {
558 let any = Any::Object(
559 vec![
560 ("name".to_string(), Any::String("Alice".to_string())),
561 ("age".to_string(), Any::Integer(25)),
562 (
563 "contacts".to_string(),
564 Any::Array(vec![
565 Any::Object(
566 vec![
567 ("type".to_string(), Any::String("Mobile".to_string())),
568 ("number".to_string(), Any::String("1234567890".to_string())),
569 ]
570 .into_iter()
571 .collect(),
572 ),
573 Any::Object(
574 vec![
575 ("type".to_string(), Any::String("Email".to_string())),
576 ("address".to_string(), Any::String("alice@example.com".to_string())),
577 ]
578 .into_iter()
579 .collect(),
580 ),
581 Any::Undefined,
582 ]),
583 ),
584 (
585 "standard_data".to_string(),
586 Any::Array(vec![
587 Any::Undefined,
588 Any::Null,
589 Any::Integer(114514),
590 Any::Float32(114.514.into()),
591 Any::Float64(115.514.into()),
592 Any::BigInt64(-1145141919810),
593 Any::False,
594 Any::True,
595 Any::Object(
596 vec![
597 ("name".to_string(), Any::String("tadokoro".to_string())),
598 ("age".to_string(), Any::String("24".to_string())),
599 ("profession".to_string(), Any::String("student".to_string())),
600 ]
601 .into_iter()
602 .collect(),
603 ),
604 Any::Binary(vec![1, 2, 3, 4, 5]),
605 ]),
606 ),
607 ]
608 .into_iter()
609 .collect(),
610 );
611
612 let mut encoder = RawEncoder::default();
613 any.write(&mut encoder).unwrap();
614 let encoded = encoder.into_inner();
615
616 let mut decoder = RawDecoder::new(&encoded);
617 let decoded = Any::read(&mut decoder).unwrap();
618
619 assert_eq!(any, decoded);
620 }
621
622 proptest! {
623 #[test]
624 #[cfg_attr(miri, ignore)]
625 fn test_random_any(any in vec(any::<Any>(), 0..100)) {
626 for any in &any {
627 let mut encoder = RawEncoder::default();
628 any.write(&mut encoder).unwrap();
629 let encoded = encoder.into_inner();
630
631 let mut decoder = RawDecoder::new(&encoded);
632 let decoded = Any::read(&mut decoder).unwrap();
633
634 assert_eq!(any, &decoded);
635 }
636 }
637 }
638
639 #[test]
640 fn test_convert_to_any() {
641 let any: Vec<Any> = vec![
642 42u8.into(),
643 42u16.into(),
644 42u32.into(),
645 42u64.into(),
646 114.514f32.into(),
647 1919.810f64.into(),
648 (-42i8).into(),
649 (-42i16).into(),
650 (-42i32).into(),
651 (-42i64).into(),
652 false.into(),
653 true.into(),
654 "JWST".to_string().into(),
655 "OctoBase".into(),
656 vec![1u8, 9, 1, 9].into(),
657 (&[8u8, 1, 0][..]).into(),
658 [Any::True, 42u8.into()].iter().collect(),
659 ];
660 assert_eq!(
661 any,
662 vec![
663 Any::Integer(42),
664 Any::Integer(42),
665 Any::Integer(42),
666 Any::Integer(42),
667 Any::Float32(114.514.into()),
668 Any::Float64(1919.810.into()),
669 Any::Integer(-42),
670 Any::Integer(-42),
671 Any::Integer(-42),
672 Any::Integer(-42),
673 Any::False,
674 Any::True,
675 Any::String("JWST".to_string()),
676 Any::String("OctoBase".to_string()),
677 Any::Binary(vec![1, 9, 1, 9]),
678 Any::Binary(vec![8, 1, 0]),
679 Any::Array(vec![Any::True, Any::Integer(42)])
680 ]
681 );
682
683 assert_eq!(
684 vec![("key".to_string(), 10u64.into())].into_iter().collect::<Any>(),
685 Any::Object(HashMap::from_iter(vec![("key".to_string(), Any::Integer(10))]))
686 );
687
688 let any: Any = 10u64.into();
689 assert_eq!([any].iter().collect::<Any>(), Any::Array(vec![Any::Integer(10)]));
690 }
691}