loro_common/
value.rs

1use std::{collections::HashMap, hash::Hash, ops::Index, sync::Arc};
2
3use arbitrary::Arbitrary;
4use enum_as_inner::EnumAsInner;
5use fxhash::FxHashMap;
6use serde::{de::VariantAccess, Deserialize, Serialize};
7
8use crate::ContainerID;
9
10/// [LoroValue] is used to represents the state of CRDT at a given version.
11///
12/// This struct is cheap to clone, the time complexity is O(1).
13#[derive(Debug, PartialEq, Clone, EnumAsInner, Default)]
14pub enum LoroValue {
15    #[default]
16    Null,
17    Bool(bool),
18    Double(f64),
19    I64(i64),
20    // i64?
21    Binary(LoroBinaryValue),
22    String(LoroStringValue),
23    List(LoroListValue),
24    // PERF We can use InternalString as key
25    Map(LoroMapValue),
26    Container(ContainerID),
27}
28
29#[derive(Default, Debug, PartialEq, Clone, Arbitrary)]
30pub struct LoroBinaryValue(Arc<Vec<u8>>);
31#[derive(Default, Debug, PartialEq, Clone, Arbitrary)]
32pub struct LoroStringValue(Arc<String>);
33#[derive(Default, Debug, PartialEq, Clone, Arbitrary)]
34pub struct LoroListValue(Arc<Vec<LoroValue>>);
35#[derive(Default, Debug, PartialEq, Clone, Arbitrary)]
36pub struct LoroMapValue(Arc<FxHashMap<String, LoroValue>>);
37
38impl From<Vec<u8>> for LoroBinaryValue {
39    fn from(value: Vec<u8>) -> Self {
40        LoroBinaryValue(Arc::new(value))
41    }
42}
43
44impl From<String> for LoroStringValue {
45    fn from(value: String) -> Self {
46        LoroStringValue(Arc::new(value))
47    }
48}
49
50impl From<&str> for LoroStringValue {
51    fn from(value: &str) -> Self {
52        LoroStringValue(Arc::new(value.to_string()))
53    }
54}
55
56impl From<Vec<LoroValue>> for LoroListValue {
57    fn from(value: Vec<LoroValue>) -> Self {
58        LoroListValue(Arc::new(value))
59    }
60}
61
62impl From<FxHashMap<String, LoroValue>> for LoroMapValue {
63    fn from(value: FxHashMap<String, LoroValue>) -> Self {
64        LoroMapValue(Arc::new(value))
65    }
66}
67
68impl From<HashMap<String, LoroValue>> for LoroMapValue {
69    fn from(value: HashMap<String, LoroValue>) -> Self {
70        LoroMapValue(Arc::new(FxHashMap::from_iter(value)))
71    }
72}
73
74impl From<Vec<(String, LoroValue)>> for LoroMapValue {
75    fn from(value: Vec<(String, LoroValue)>) -> Self {
76        LoroMapValue(Arc::new(FxHashMap::from_iter(value)))
77    }
78}
79
80impl std::ops::Deref for LoroBinaryValue {
81    type Target = Vec<u8>;
82    fn deref(&self) -> &Self::Target {
83        &self.0
84    }
85}
86
87impl std::ops::Deref for LoroStringValue {
88    type Target = String;
89    fn deref(&self) -> &Self::Target {
90        &self.0
91    }
92}
93
94impl std::ops::Deref for LoroListValue {
95    type Target = Vec<LoroValue>;
96    fn deref(&self) -> &Self::Target {
97        &self.0
98    }
99}
100
101impl std::ops::Deref for LoroMapValue {
102    type Target = FxHashMap<String, LoroValue>;
103    fn deref(&self) -> &Self::Target {
104        &self.0
105    }
106}
107
108impl LoroBinaryValue {
109    pub fn make_mut(&mut self) -> &mut Vec<u8> {
110        Arc::make_mut(&mut self.0)
111    }
112}
113
114impl LoroStringValue {
115    pub fn make_mut(&mut self) -> &mut String {
116        Arc::make_mut(&mut self.0)
117    }
118}
119
120impl LoroListValue {
121    pub fn make_mut(&mut self) -> &mut Vec<LoroValue> {
122        Arc::make_mut(&mut self.0)
123    }
124}
125
126impl LoroMapValue {
127    pub fn make_mut(&mut self) -> &mut FxHashMap<String, LoroValue> {
128        Arc::make_mut(&mut self.0)
129    }
130}
131
132impl LoroBinaryValue {
133    pub fn unwrap(self) -> Vec<u8> {
134        match Arc::try_unwrap(self.0) {
135            Ok(v) => v,
136            Err(arc) => (*arc).clone(),
137        }
138    }
139}
140
141impl LoroStringValue {
142    pub fn unwrap(self) -> String {
143        match Arc::try_unwrap(self.0) {
144            Ok(v) => v,
145            Err(arc) => (*arc).clone(),
146        }
147    }
148}
149
150impl LoroListValue {
151    pub fn unwrap(self) -> Vec<LoroValue> {
152        match Arc::try_unwrap(self.0) {
153            Ok(v) => v,
154            Err(arc) => (*arc).clone(),
155        }
156    }
157}
158
159impl LoroMapValue {
160    pub fn unwrap(self) -> FxHashMap<String, LoroValue> {
161        match Arc::try_unwrap(self.0) {
162            Ok(v) => v,
163            Err(arc) => (*arc).clone(),
164        }
165    }
166}
167
168impl FromIterator<LoroValue> for LoroListValue {
169    fn from_iter<T: IntoIterator<Item = LoroValue>>(iter: T) -> Self {
170        LoroListValue(Arc::new(iter.into_iter().collect()))
171    }
172}
173
174impl FromIterator<(String, LoroValue)> for LoroMapValue {
175    fn from_iter<T: IntoIterator<Item = (String, LoroValue)>>(iter: T) -> Self {
176        let map: FxHashMap<_, _> = iter.into_iter().collect();
177        LoroMapValue(Arc::new(map))
178    }
179}
180
181impl AsRef<str> for LoroStringValue {
182    fn as_ref(&self) -> &str {
183        &self.0
184    }
185}
186
187impl AsRef<[LoroValue]> for LoroListValue {
188    fn as_ref(&self) -> &[LoroValue] {
189        &self.0
190    }
191}
192
193impl AsRef<FxHashMap<String, LoroValue>> for LoroMapValue {
194    fn as_ref(&self) -> &FxHashMap<String, LoroValue> {
195        &self.0
196    }
197}
198
199const MAX_DEPTH: usize = 128;
200impl<'a> arbitrary::Arbitrary<'a> for LoroValue {
201    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
202        let value = match u.int_in_range(0..=7).unwrap() {
203            0 => LoroValue::Null,
204            1 => LoroValue::Bool(u.arbitrary()?),
205            2 => LoroValue::Double(u.arbitrary()?),
206            3 => LoroValue::I64(u.arbitrary()?),
207            4 => LoroValue::Binary(LoroBinaryValue::arbitrary(u)?),
208            5 => LoroValue::String(LoroStringValue::arbitrary(u)?),
209            6 => LoroValue::List(LoroListValue::arbitrary(u)?),
210            7 => LoroValue::Map(LoroMapValue::arbitrary(u)?),
211            _ => unreachable!(),
212        };
213
214        if value.get_depth() > MAX_DEPTH {
215            Err(arbitrary::Error::IncorrectFormat)
216        } else {
217            Ok(value)
218        }
219    }
220}
221
222impl LoroValue {
223    pub fn get_by_key(&self, key: &str) -> Option<&LoroValue> {
224        match self {
225            LoroValue::Map(map) => map.get(key),
226            _ => None,
227        }
228    }
229
230    pub fn get_by_index(&self, index: isize) -> Option<&LoroValue> {
231        match self {
232            LoroValue::List(list) => {
233                if index < 0 {
234                    list.get(list.len() - (-index) as usize)
235                } else {
236                    list.get(index as usize)
237                }
238            }
239            _ => None,
240        }
241    }
242
243    pub fn is_false(&self) -> bool {
244        match self {
245            LoroValue::Bool(b) => !*b,
246            _ => false,
247        }
248    }
249
250    pub fn get_depth(&self) -> usize {
251        let mut max_depth = 0;
252        let mut value_depth_pairs = vec![(self, 0)];
253        while let Some((value, depth)) = value_depth_pairs.pop() {
254            match value {
255                LoroValue::List(arr) => {
256                    for v in arr.iter() {
257                        value_depth_pairs.push((v, depth + 1));
258                    }
259                    max_depth = max_depth.max(depth + 1);
260                }
261                LoroValue::Map(map) => {
262                    for (_, v) in map.iter() {
263                        value_depth_pairs.push((v, depth + 1));
264                    }
265
266                    max_depth = max_depth.max(depth + 1);
267                }
268                _ => {}
269            }
270        }
271
272        max_depth
273    }
274
275    // TODO: add checks for too deep value, and return err if users
276    // try to insert such value into a container
277    pub fn is_too_deep(&self) -> bool {
278        self.get_depth() > MAX_DEPTH
279    }
280
281    /// Visit the all list items or map's values
282    pub fn visit_children(&self, f: &mut dyn FnMut(&LoroValue)) {
283        match self {
284            LoroValue::List(list) => {
285                for v in list.iter() {
286                    f(v);
287                }
288            }
289            LoroValue::Map(m) => {
290                for (_k, v) in m.iter() {
291                    f(v)
292                }
293            }
294            _ => {}
295        }
296    }
297
298    pub fn is_empty_collection(&self) -> bool {
299        match self {
300            LoroValue::Null => false,
301            LoroValue::Bool(_) => false,
302            LoroValue::Double(_) => false,
303            LoroValue::I64(_) => false,
304            LoroValue::Binary(loro_binary_value) => loro_binary_value.is_empty(),
305            LoroValue::String(loro_string_value) => loro_string_value.is_empty(),
306            LoroValue::List(loro_list_value) => loro_list_value.is_empty(),
307            LoroValue::Map(loro_map_value) => loro_map_value.is_empty(),
308            LoroValue::Container(_) => false,
309        }
310    }
311}
312
313impl Index<&str> for LoroValue {
314    type Output = LoroValue;
315
316    fn index(&self, index: &str) -> &Self::Output {
317        match self {
318            LoroValue::Map(map) => map.get(index).unwrap_or(&LoroValue::Null),
319            _ => &LoroValue::Null,
320        }
321    }
322}
323
324impl Index<usize> for LoroValue {
325    type Output = LoroValue;
326
327    fn index(&self, index: usize) -> &Self::Output {
328        match self {
329            LoroValue::List(list) => list.get(index).unwrap_or(&LoroValue::Null),
330            _ => &LoroValue::Null,
331        }
332    }
333}
334
335impl TryFrom<LoroValue> for bool {
336    type Error = &'static str;
337
338    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
339        match value {
340            LoroValue::Bool(v) => Ok(v),
341            _ => Err("not a bool"),
342        }
343    }
344}
345
346impl TryFrom<LoroValue> for f64 {
347    type Error = &'static str;
348
349    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
350        match value {
351            LoroValue::Double(v) => Ok(v),
352            _ => Err("not a double"),
353        }
354    }
355}
356
357impl TryFrom<LoroValue> for i32 {
358    type Error = &'static str;
359
360    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
361        match value {
362            LoroValue::I64(v) => Ok(v as i32),
363            _ => Err("not a i32"),
364        }
365    }
366}
367
368impl TryFrom<LoroValue> for Arc<Vec<u8>> {
369    type Error = &'static str;
370
371    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
372        match value {
373            LoroValue::Binary(v) => Ok(Arc::clone(&v.0)),
374            _ => Err("not a binary"),
375        }
376    }
377}
378
379impl TryFrom<LoroValue> for Arc<String> {
380    type Error = &'static str;
381
382    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
383        match value {
384            LoroValue::String(v) => Ok(Arc::clone(&v.0)),
385            _ => Err("not a string"),
386        }
387    }
388}
389
390impl TryFrom<LoroValue> for Arc<Vec<LoroValue>> {
391    type Error = &'static str;
392
393    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
394        match value {
395            LoroValue::List(v) => Ok(Arc::clone(&v.0)),
396            _ => Err("not a list"),
397        }
398    }
399}
400
401impl TryFrom<LoroValue> for Arc<FxHashMap<String, LoroValue>> {
402    type Error = &'static str;
403
404    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
405        match value {
406            LoroValue::Map(v) => Ok(Arc::clone(&v.0)),
407            _ => Err("not a map"),
408        }
409    }
410}
411
412impl TryFrom<LoroValue> for ContainerID {
413    type Error = &'static str;
414
415    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
416        match value {
417            LoroValue::Container(v) => Ok(v),
418            _ => Err("not a container"),
419        }
420    }
421}
422
423impl Hash for LoroValue {
424    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
425        std::mem::discriminant(self).hash(state);
426        match self {
427            LoroValue::Null => {}
428            LoroValue::Bool(v) => {
429                state.write_u8(*v as u8);
430            }
431            LoroValue::Double(v) => {
432                state.write_u64(v.to_bits());
433            }
434            LoroValue::I64(v) => {
435                state.write_i64(*v);
436            }
437            LoroValue::Binary(v) => {
438                v.hash(state);
439            }
440            LoroValue::String(v) => {
441                v.hash(state);
442            }
443            LoroValue::List(v) => {
444                v.hash(state);
445            }
446            LoroValue::Map(v) => {
447                state.write_usize(v.len());
448                for (k, v) in v.iter() {
449                    k.hash(state);
450                    v.hash(state);
451                }
452            }
453            LoroValue::Container(v) => {
454                v.hash(state);
455            }
456        }
457    }
458}
459
460impl Eq for LoroValue {}
461
462impl<S: Into<String>, M> From<HashMap<S, LoroValue, M>> for LoroValue {
463    fn from(map: HashMap<S, LoroValue, M>) -> Self {
464        let mut new_map = FxHashMap::default();
465        for (k, v) in map {
466            new_map.insert(k.into(), v);
467        }
468
469        LoroValue::Map(new_map.into())
470    }
471}
472
473impl From<Vec<u8>> for LoroValue {
474    fn from(vec: Vec<u8>) -> Self {
475        LoroValue::Binary(vec.into())
476    }
477}
478
479impl From<&'_ [u8]> for LoroValue {
480    fn from(vec: &[u8]) -> Self {
481        LoroValue::Binary(vec.to_vec().into())
482    }
483}
484
485impl<const N: usize> From<&'_ [u8; N]> for LoroValue {
486    fn from(vec: &[u8; N]) -> Self {
487        LoroValue::Binary(vec.to_vec().into())
488    }
489}
490
491impl From<i32> for LoroValue {
492    fn from(v: i32) -> Self {
493        LoroValue::I64(v as i64)
494    }
495}
496
497impl From<u32> for LoroValue {
498    fn from(v: u32) -> Self {
499        LoroValue::I64(v as i64)
500    }
501}
502
503impl From<i64> for LoroValue {
504    fn from(v: i64) -> Self {
505        LoroValue::I64(v)
506    }
507}
508
509impl From<u16> for LoroValue {
510    fn from(v: u16) -> Self {
511        LoroValue::I64(v as i64)
512    }
513}
514
515impl From<i16> for LoroValue {
516    fn from(v: i16) -> Self {
517        LoroValue::I64(v as i64)
518    }
519}
520
521impl From<f64> for LoroValue {
522    fn from(v: f64) -> Self {
523        LoroValue::Double(v)
524    }
525}
526
527impl From<bool> for LoroValue {
528    fn from(v: bool) -> Self {
529        LoroValue::Bool(v)
530    }
531}
532
533impl<T: Into<LoroValue>> From<Vec<T>> for LoroValue {
534    fn from(value: Vec<T>) -> Self {
535        let vec: Vec<LoroValue> = value.into_iter().map(|x| x.into()).collect();
536        LoroValue::List(vec.into())
537    }
538}
539
540impl From<&str> for LoroValue {
541    fn from(v: &str) -> Self {
542        LoroValue::String(v.to_string().into())
543    }
544}
545
546impl From<String> for LoroValue {
547    fn from(v: String) -> Self {
548        LoroValue::String(v.into())
549    }
550}
551
552impl<'a> From<&'a [LoroValue]> for LoroValue {
553    fn from(v: &'a [LoroValue]) -> Self {
554        LoroValue::List(v.to_vec().into())
555    }
556}
557
558impl From<ContainerID> for LoroValue {
559    fn from(v: ContainerID) -> Self {
560        LoroValue::Container(v)
561    }
562}
563
564#[cfg(feature = "wasm")]
565pub mod wasm {
566    use fxhash::FxHashMap;
567    use js_sys::{Array, Object, Uint8Array};
568    use wasm_bindgen::{JsCast, JsValue, __rt::IntoJsResult};
569
570    use crate::{ContainerID, LoroError, LoroValue};
571
572    pub fn convert(value: LoroValue) -> JsValue {
573        match value {
574            LoroValue::Null => JsValue::NULL,
575            LoroValue::Bool(b) => JsValue::from_bool(b),
576            LoroValue::Double(f) => JsValue::from_f64(f),
577            LoroValue::I64(i) => JsValue::from_f64(i as f64),
578            LoroValue::String(s) => JsValue::from_str(&s),
579            LoroValue::Binary(binary) => {
580                let binary = binary.unwrap();
581                let arr = Uint8Array::new_with_length(binary.len() as u32);
582                for (i, v) in binary.into_iter().enumerate() {
583                    arr.set_index(i as u32, v);
584                }
585                arr.into_js_result().unwrap()
586            }
587            LoroValue::List(list) => {
588                let list = list.unwrap();
589                let arr = Array::new_with_length(list.len() as u32);
590                for (i, v) in list.into_iter().enumerate() {
591                    arr.set(i as u32, convert(v));
592                }
593                arr.into_js_result().unwrap()
594            }
595            LoroValue::Map(m) => {
596                let m = m.unwrap();
597                let map = Object::new();
598                for (k, v) in m.into_iter() {
599                    let str: &str = &k;
600                    js_sys::Reflect::set(&map, &JsValue::from_str(str), &convert(v)).unwrap();
601                }
602
603                map.into_js_result().unwrap()
604            }
605            LoroValue::Container(container_id) => JsValue::from(&container_id),
606        }
607    }
608
609    impl From<LoroValue> for JsValue {
610        fn from(value: LoroValue) -> Self {
611            convert(value)
612        }
613    }
614
615    impl From<JsValue> for LoroValue {
616        fn from(js_value: JsValue) -> Self {
617            if js_value.is_null() || js_value.is_undefined() {
618                LoroValue::Null
619            } else if js_value.as_bool().is_some() {
620                LoroValue::Bool(js_value.as_bool().unwrap())
621            } else if js_value.as_f64().is_some() {
622                let num = js_value.as_f64().unwrap();
623                if num.fract() == 0.0 && num <= i64::MAX as f64 && num >= i64::MIN as f64 {
624                    LoroValue::I64(num as i64)
625                } else {
626                    LoroValue::Double(num)
627                }
628            } else if js_value.is_string() {
629                LoroValue::String(js_value.as_string().unwrap().into())
630            } else if js_value.has_type::<Array>() {
631                let array = js_value.unchecked_into::<Array>();
632                let mut list = Vec::new();
633                for i in 0..array.length() {
634                    list.push(LoroValue::from(array.get(i)));
635                }
636
637                LoroValue::List(list.into())
638            } else if js_value.is_instance_of::<Uint8Array>() {
639                let array = js_value.unchecked_into::<Uint8Array>();
640                let mut binary = Vec::new();
641                for i in 0..array.length() {
642                    binary.push(array.get_index(i));
643                }
644
645                LoroValue::Binary(binary.into())
646            } else if js_value.is_object() {
647                let object = js_value.unchecked_into::<Object>();
648                let mut map = FxHashMap::default();
649                for key in js_sys::Reflect::own_keys(&object).unwrap().iter() {
650                    let key = key.as_string().unwrap();
651                    map.insert(
652                        key.clone(),
653                        LoroValue::from(js_sys::Reflect::get(&object, &key.into()).unwrap()),
654                    );
655                }
656
657                LoroValue::Map(map.into())
658            } else {
659                panic!("Fail to convert JsValue {:?} to LoroValue ", js_value)
660            }
661        }
662    }
663
664    impl From<&ContainerID> for JsValue {
665        fn from(id: &ContainerID) -> Self {
666            JsValue::from_str(id.to_string().as_str())
667        }
668    }
669
670    impl TryFrom<JsValue> for ContainerID {
671        type Error = LoroError;
672
673        fn try_from(value: JsValue) -> Result<Self, Self::Error> {
674            if !value.is_string() {
675                return Err(LoroError::DecodeError(
676                    "Given ContainerId is not string".into(),
677                ));
678            }
679
680            let s = value.as_string().unwrap();
681            ContainerID::try_from(s.as_str()).map_err(|_| {
682                LoroError::DecodeError(
683                    format!("Given ContainerId is not a valid ContainerID: {}", s).into(),
684                )
685            })
686        }
687    }
688}
689
690const LORO_CONTAINER_ID_PREFIX: &str = "🦜:";
691
692impl Serialize for LoroValue {
693    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
694    where
695        S: serde::Serializer,
696    {
697        if serializer.is_human_readable() {
698            // json type
699            match self {
700                LoroValue::Null => serializer.serialize_unit(),
701                LoroValue::Bool(b) => serializer.serialize_bool(*b),
702                LoroValue::Double(d) => serializer.serialize_f64(*d),
703                LoroValue::I64(i) => serializer.serialize_i64(*i),
704                LoroValue::String(s) => serializer.serialize_str(s),
705                LoroValue::Binary(b) => serializer.collect_seq(b.iter()),
706                LoroValue::List(l) => serializer.collect_seq(l.iter()),
707                LoroValue::Map(m) => serializer.collect_map(m.iter()),
708                LoroValue::Container(id) => {
709                    serializer.serialize_str(&format!("{}{}", LORO_CONTAINER_ID_PREFIX, id))
710                }
711            }
712        } else {
713            // binary type
714            match self {
715                LoroValue::Null => serializer.serialize_unit_variant("LoroValue", 0, "Null"),
716                LoroValue::Bool(b) => {
717                    serializer.serialize_newtype_variant("LoroValue", 1, "Bool", b)
718                }
719                LoroValue::Double(d) => {
720                    serializer.serialize_newtype_variant("LoroValue", 2, "Double", d)
721                }
722                LoroValue::I64(i) => serializer.serialize_newtype_variant("LoroValue", 3, "I32", i),
723                LoroValue::String(s) => {
724                    serializer.serialize_newtype_variant("LoroValue", 4, "String", &**s)
725                }
726
727                LoroValue::List(l) => {
728                    serializer.serialize_newtype_variant("LoroValue", 5, "List", &**l)
729                }
730                LoroValue::Map(m) => {
731                    serializer.serialize_newtype_variant("LoroValue", 6, "Map", &**m)
732                }
733                LoroValue::Container(id) => {
734                    serializer.serialize_newtype_variant("LoroValue", 7, "Container", id)
735                }
736                LoroValue::Binary(b) => {
737                    serializer.serialize_newtype_variant("LoroValue", 8, "Binary", &**b)
738                }
739            }
740        }
741    }
742}
743
744impl<'de> Deserialize<'de> for LoroValue {
745    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
746    where
747        D: serde::Deserializer<'de>,
748    {
749        if deserializer.is_human_readable() {
750            deserializer.deserialize_any(LoroValueVisitor)
751        } else {
752            deserializer.deserialize_enum(
753                "LoroValue",
754                &[
755                    "Null",
756                    "Bool",
757                    "Double",
758                    "I32",
759                    "String",
760                    "List",
761                    "Map",
762                    "Container",
763                    "Binary",
764                ],
765                LoroValueEnumVisitor,
766            )
767        }
768    }
769}
770
771struct LoroValueVisitor;
772
773impl<'de> serde::de::Visitor<'de> for LoroValueVisitor {
774    type Value = LoroValue;
775
776    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
777        formatter.write_str("a LoroValue")
778    }
779
780    fn visit_unit<E>(self) -> Result<Self::Value, E>
781    where
782        E: serde::de::Error,
783    {
784        Ok(LoroValue::Null)
785    }
786
787    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
788    where
789        E: serde::de::Error,
790    {
791        Ok(LoroValue::Bool(v))
792    }
793
794    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
795    where
796        E: serde::de::Error,
797    {
798        Ok(LoroValue::I64(v))
799    }
800
801    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
802    where
803        E: serde::de::Error,
804    {
805        Ok(LoroValue::I64(v as i64))
806    }
807
808    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
809    where
810        E: serde::de::Error,
811    {
812        Ok(LoroValue::Double(v))
813    }
814
815    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
816    where
817        E: serde::de::Error,
818    {
819        if let Some(id) = v.strip_prefix(LORO_CONTAINER_ID_PREFIX) {
820            return Ok(LoroValue::Container(
821                ContainerID::try_from(id)
822                    .map_err(|_| serde::de::Error::custom("Invalid container id"))?,
823            ));
824        }
825        Ok(LoroValue::String(v.to_owned().into()))
826    }
827
828    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
829    where
830        E: serde::de::Error,
831    {
832        if let Some(id) = v.strip_prefix(LORO_CONTAINER_ID_PREFIX) {
833            return Ok(LoroValue::Container(
834                ContainerID::try_from(id)
835                    .map_err(|_| serde::de::Error::custom("Invalid container id"))?,
836            ));
837        }
838
839        Ok(LoroValue::String(v.into()))
840    }
841
842    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
843    where
844        E: serde::de::Error,
845    {
846        let binary = Vec::from_iter(v.iter().copied());
847        Ok(LoroValue::Binary(binary.into()))
848    }
849
850    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
851    where
852        E: serde::de::Error,
853    {
854        let binary = Vec::from_iter(v.iter().copied());
855        Ok(LoroValue::Binary(binary.into()))
856    }
857
858    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
859    where
860        A: serde::de::SeqAccess<'de>,
861    {
862        let mut list = Vec::new();
863        while let Some(value) = seq.next_element()? {
864            list.push(value);
865        }
866        Ok(LoroValue::List(list.into()))
867    }
868
869    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
870    where
871        A: serde::de::MapAccess<'de>,
872    {
873        let mut ans: FxHashMap<String, _> = FxHashMap::default();
874        while let Some((key, value)) = map.next_entry::<String, _>()? {
875            ans.insert(key, value);
876        }
877
878        Ok(LoroValue::Map(ans.into()))
879    }
880}
881
882#[derive(Deserialize)]
883enum LoroValueFields {
884    Null,
885    Bool,
886    Double,
887    I32,
888    String,
889    List,
890    Map,
891    Container,
892    Binary,
893}
894
895struct LoroValueEnumVisitor;
896impl<'de> serde::de::Visitor<'de> for LoroValueEnumVisitor {
897    type Value = LoroValue;
898    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
899        formatter.write_str("a loro value")
900    }
901
902    fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
903    where
904        A: serde::de::EnumAccess<'de>,
905    {
906        match data.variant()? {
907            (LoroValueFields::Null, v) => {
908                v.unit_variant()?;
909                Ok(LoroValue::Null)
910            }
911            (LoroValueFields::Bool, v) => v.newtype_variant().map(LoroValue::Bool),
912            (LoroValueFields::Double, v) => v.newtype_variant().map(LoroValue::Double),
913            (LoroValueFields::I32, v) => v.newtype_variant().map(LoroValue::I64),
914            (LoroValueFields::String, v) => v
915                .newtype_variant()
916                .map(|x: String| LoroValue::String(x.into())),
917            (LoroValueFields::List, v) => v
918                .newtype_variant()
919                .map(|x: Vec<LoroValue>| LoroValue::List(x.into())),
920            (LoroValueFields::Map, v) => v
921                .newtype_variant()
922                .map(|x: FxHashMap<String, LoroValue>| LoroValue::Map(x.into())),
923            (LoroValueFields::Container, v) => v.newtype_variant().map(LoroValue::Container),
924            (LoroValueFields::Binary, v) => v
925                .newtype_variant()
926                .map(|x: Vec<u8>| LoroValue::Binary(x.into())),
927        }
928    }
929}
930
931pub fn to_value<T: Into<LoroValue>>(value: T) -> LoroValue {
932    value.into()
933}
934
935#[cfg(feature = "serde_json")]
936mod serde_json_impl {
937    use serde_json::{Number, Value};
938
939    use super::LoroValue;
940
941    impl From<Value> for LoroValue {
942        fn from(value: Value) -> Self {
943            match value {
944                Value::Null => LoroValue::Null,
945                Value::Bool(b) => LoroValue::Bool(b),
946                Value::Number(n) => {
947                    if let Some(i) = n.as_i64() {
948                        LoroValue::I64(i)
949                    } else {
950                        LoroValue::Double(n.as_f64().unwrap())
951                    }
952                }
953                Value::String(s) => LoroValue::String(s.into()),
954                Value::Array(arr) => {
955                    LoroValue::List(arr.into_iter().map(LoroValue::from).collect())
956                }
957                Value::Object(obj) => LoroValue::Map(
958                    obj.into_iter()
959                        .map(|(k, v)| (k, LoroValue::from(v)))
960                        .collect(),
961                ),
962            }
963        }
964    }
965
966    use super::LORO_CONTAINER_ID_PREFIX;
967    impl From<LoroValue> for Value {
968        fn from(value: LoroValue) -> Self {
969            match value {
970                LoroValue::Null => Value::Null,
971                LoroValue::Bool(b) => Value::Bool(b),
972                LoroValue::Double(d) => Value::Number(Number::from_f64(d).unwrap()),
973                LoroValue::I64(i) => Value::Number(Number::from(i)),
974                LoroValue::String(s) => Value::String(s.to_string()),
975                LoroValue::List(l) => Value::Array(l.iter().cloned().map(Value::from).collect()),
976                LoroValue::Map(m) => Value::Object(
977                    m.iter()
978                        .map(|(k, v)| (k.clone(), Value::from(v.clone())))
979                        .collect(),
980                ),
981                LoroValue::Container(id) => {
982                    Value::String(format!("{}{}", LORO_CONTAINER_ID_PREFIX, id))
983                }
984                LoroValue::Binary(b) => Value::Array(b.iter().copied().map(Value::from).collect()),
985            }
986        }
987    }
988}