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
299impl Index<&str> for LoroValue {
300    type Output = LoroValue;
301
302    fn index(&self, index: &str) -> &Self::Output {
303        match self {
304            LoroValue::Map(map) => map.get(index).unwrap_or(&LoroValue::Null),
305            _ => &LoroValue::Null,
306        }
307    }
308}
309
310impl Index<usize> for LoroValue {
311    type Output = LoroValue;
312
313    fn index(&self, index: usize) -> &Self::Output {
314        match self {
315            LoroValue::List(list) => list.get(index).unwrap_or(&LoroValue::Null),
316            _ => &LoroValue::Null,
317        }
318    }
319}
320
321impl TryFrom<LoroValue> for bool {
322    type Error = &'static str;
323
324    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
325        match value {
326            LoroValue::Bool(v) => Ok(v),
327            _ => Err("not a bool"),
328        }
329    }
330}
331
332impl TryFrom<LoroValue> for f64 {
333    type Error = &'static str;
334
335    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
336        match value {
337            LoroValue::Double(v) => Ok(v),
338            _ => Err("not a double"),
339        }
340    }
341}
342
343impl TryFrom<LoroValue> for i32 {
344    type Error = &'static str;
345
346    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
347        match value {
348            LoroValue::I64(v) => Ok(v as i32),
349            _ => Err("not a i32"),
350        }
351    }
352}
353
354impl TryFrom<LoroValue> for Arc<Vec<u8>> {
355    type Error = &'static str;
356
357    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
358        match value {
359            LoroValue::Binary(v) => Ok(Arc::clone(&v.0)),
360            _ => Err("not a binary"),
361        }
362    }
363}
364
365impl TryFrom<LoroValue> for Arc<String> {
366    type Error = &'static str;
367
368    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
369        match value {
370            LoroValue::String(v) => Ok(Arc::clone(&v.0)),
371            _ => Err("not a string"),
372        }
373    }
374}
375
376impl TryFrom<LoroValue> for Arc<Vec<LoroValue>> {
377    type Error = &'static str;
378
379    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
380        match value {
381            LoroValue::List(v) => Ok(Arc::clone(&v.0)),
382            _ => Err("not a list"),
383        }
384    }
385}
386
387impl TryFrom<LoroValue> for Arc<FxHashMap<String, LoroValue>> {
388    type Error = &'static str;
389
390    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
391        match value {
392            LoroValue::Map(v) => Ok(Arc::clone(&v.0)),
393            _ => Err("not a map"),
394        }
395    }
396}
397
398impl TryFrom<LoroValue> for ContainerID {
399    type Error = &'static str;
400
401    fn try_from(value: LoroValue) -> Result<Self, Self::Error> {
402        match value {
403            LoroValue::Container(v) => Ok(v),
404            _ => Err("not a container"),
405        }
406    }
407}
408
409impl Hash for LoroValue {
410    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
411        std::mem::discriminant(self).hash(state);
412        match self {
413            LoroValue::Null => {}
414            LoroValue::Bool(v) => {
415                state.write_u8(*v as u8);
416            }
417            LoroValue::Double(v) => {
418                state.write_u64(v.to_bits());
419            }
420            LoroValue::I64(v) => {
421                state.write_i64(*v);
422            }
423            LoroValue::Binary(v) => {
424                v.hash(state);
425            }
426            LoroValue::String(v) => {
427                v.hash(state);
428            }
429            LoroValue::List(v) => {
430                v.hash(state);
431            }
432            LoroValue::Map(v) => {
433                state.write_usize(v.len());
434                for (k, v) in v.iter() {
435                    k.hash(state);
436                    v.hash(state);
437                }
438            }
439            LoroValue::Container(v) => {
440                v.hash(state);
441            }
442        }
443    }
444}
445
446impl Eq for LoroValue {}
447
448impl<S: Into<String>, M> From<HashMap<S, LoroValue, M>> for LoroValue {
449    fn from(map: HashMap<S, LoroValue, M>) -> Self {
450        let mut new_map = FxHashMap::default();
451        for (k, v) in map {
452            new_map.insert(k.into(), v);
453        }
454
455        LoroValue::Map(new_map.into())
456    }
457}
458
459impl From<Vec<u8>> for LoroValue {
460    fn from(vec: Vec<u8>) -> Self {
461        LoroValue::Binary(vec.into())
462    }
463}
464
465impl From<&'_ [u8]> for LoroValue {
466    fn from(vec: &[u8]) -> Self {
467        LoroValue::Binary(vec.to_vec().into())
468    }
469}
470
471impl<const N: usize> From<&'_ [u8; N]> for LoroValue {
472    fn from(vec: &[u8; N]) -> Self {
473        LoroValue::Binary(vec.to_vec().into())
474    }
475}
476
477impl From<i32> for LoroValue {
478    fn from(v: i32) -> Self {
479        LoroValue::I64(v as i64)
480    }
481}
482
483impl From<u32> for LoroValue {
484    fn from(v: u32) -> Self {
485        LoroValue::I64(v as i64)
486    }
487}
488
489impl From<i64> for LoroValue {
490    fn from(v: i64) -> Self {
491        LoroValue::I64(v)
492    }
493}
494
495impl From<u16> for LoroValue {
496    fn from(v: u16) -> Self {
497        LoroValue::I64(v as i64)
498    }
499}
500
501impl From<i16> for LoroValue {
502    fn from(v: i16) -> Self {
503        LoroValue::I64(v as i64)
504    }
505}
506
507impl From<f64> for LoroValue {
508    fn from(v: f64) -> Self {
509        LoroValue::Double(v)
510    }
511}
512
513impl From<bool> for LoroValue {
514    fn from(v: bool) -> Self {
515        LoroValue::Bool(v)
516    }
517}
518
519impl<T: Into<LoroValue>> From<Vec<T>> for LoroValue {
520    fn from(value: Vec<T>) -> Self {
521        let vec: Vec<LoroValue> = value.into_iter().map(|x| x.into()).collect();
522        LoroValue::List(vec.into())
523    }
524}
525
526impl From<&str> for LoroValue {
527    fn from(v: &str) -> Self {
528        LoroValue::String(v.to_string().into())
529    }
530}
531
532impl From<String> for LoroValue {
533    fn from(v: String) -> Self {
534        LoroValue::String(v.into())
535    }
536}
537
538impl<'a> From<&'a [LoroValue]> for LoroValue {
539    fn from(v: &'a [LoroValue]) -> Self {
540        LoroValue::List(v.to_vec().into())
541    }
542}
543
544impl From<ContainerID> for LoroValue {
545    fn from(v: ContainerID) -> Self {
546        LoroValue::Container(v)
547    }
548}
549
550#[cfg(feature = "wasm")]
551pub mod wasm {
552    use fxhash::FxHashMap;
553    use js_sys::{Array, Object, Uint8Array};
554    use wasm_bindgen::{JsCast, JsValue, __rt::IntoJsResult};
555
556    use crate::{ContainerID, LoroError, LoroValue};
557
558    pub fn convert(value: LoroValue) -> JsValue {
559        match value {
560            LoroValue::Null => JsValue::NULL,
561            LoroValue::Bool(b) => JsValue::from_bool(b),
562            LoroValue::Double(f) => JsValue::from_f64(f),
563            LoroValue::I64(i) => JsValue::from_f64(i as f64),
564            LoroValue::String(s) => JsValue::from_str(&s),
565            LoroValue::Binary(binary) => {
566                let binary = binary.unwrap();
567                let arr = Uint8Array::new_with_length(binary.len() as u32);
568                for (i, v) in binary.into_iter().enumerate() {
569                    arr.set_index(i as u32, v);
570                }
571                arr.into_js_result().unwrap()
572            }
573            LoroValue::List(list) => {
574                let list = list.unwrap();
575                let arr = Array::new_with_length(list.len() as u32);
576                for (i, v) in list.into_iter().enumerate() {
577                    arr.set(i as u32, convert(v));
578                }
579                arr.into_js_result().unwrap()
580            }
581            LoroValue::Map(m) => {
582                let m = m.unwrap();
583                let map = Object::new();
584                for (k, v) in m.into_iter() {
585                    let str: &str = &k;
586                    js_sys::Reflect::set(&map, &JsValue::from_str(str), &convert(v)).unwrap();
587                }
588
589                map.into_js_result().unwrap()
590            }
591            LoroValue::Container(container_id) => JsValue::from(&container_id),
592        }
593    }
594
595    impl From<LoroValue> for JsValue {
596        fn from(value: LoroValue) -> Self {
597            convert(value)
598        }
599    }
600
601    impl From<JsValue> for LoroValue {
602        fn from(js_value: JsValue) -> Self {
603            if js_value.is_null() || js_value.is_undefined() {
604                LoroValue::Null
605            } else if js_value.as_bool().is_some() {
606                LoroValue::Bool(js_value.as_bool().unwrap())
607            } else if js_value.as_f64().is_some() {
608                let num = js_value.as_f64().unwrap();
609                if num.fract() == 0.0 && num <= i64::MAX as f64 && num >= i64::MIN as f64 {
610                    LoroValue::I64(num as i64)
611                } else {
612                    LoroValue::Double(num)
613                }
614            } else if js_value.is_string() {
615                LoroValue::String(js_value.as_string().unwrap().into())
616            } else if js_value.has_type::<Array>() {
617                let array = js_value.unchecked_into::<Array>();
618                let mut list = Vec::new();
619                for i in 0..array.length() {
620                    list.push(LoroValue::from(array.get(i)));
621                }
622
623                LoroValue::List(list.into())
624            } else if js_value.is_instance_of::<Uint8Array>() {
625                let array = js_value.unchecked_into::<Uint8Array>();
626                let mut binary = Vec::new();
627                for i in 0..array.length() {
628                    binary.push(array.get_index(i));
629                }
630
631                LoroValue::Binary(binary.into())
632            } else if js_value.is_object() {
633                let object = js_value.unchecked_into::<Object>();
634                let mut map = FxHashMap::default();
635                for key in js_sys::Reflect::own_keys(&object).unwrap().iter() {
636                    let key = key.as_string().unwrap();
637                    map.insert(
638                        key.clone(),
639                        LoroValue::from(js_sys::Reflect::get(&object, &key.into()).unwrap()),
640                    );
641                }
642
643                LoroValue::Map(map.into())
644            } else {
645                panic!("Fail to convert JsValue {:?} to LoroValue ", js_value)
646            }
647        }
648    }
649
650    impl From<&ContainerID> for JsValue {
651        fn from(id: &ContainerID) -> Self {
652            JsValue::from_str(id.to_string().as_str())
653        }
654    }
655
656    impl TryFrom<JsValue> for ContainerID {
657        type Error = LoroError;
658
659        fn try_from(value: JsValue) -> Result<Self, Self::Error> {
660            if !value.is_string() {
661                return Err(LoroError::DecodeError(
662                    "Given ContainerId is not string".into(),
663                ));
664            }
665
666            let s = value.as_string().unwrap();
667            ContainerID::try_from(s.as_str()).map_err(|_| {
668                LoroError::DecodeError(
669                    format!("Given ContainerId is not a valid ContainerID: {}", s).into(),
670                )
671            })
672        }
673    }
674}
675
676const LORO_CONTAINER_ID_PREFIX: &str = "🦜:";
677
678impl Serialize for LoroValue {
679    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
680    where
681        S: serde::Serializer,
682    {
683        if serializer.is_human_readable() {
684            // json type
685            match self {
686                LoroValue::Null => serializer.serialize_unit(),
687                LoroValue::Bool(b) => serializer.serialize_bool(*b),
688                LoroValue::Double(d) => serializer.serialize_f64(*d),
689                LoroValue::I64(i) => serializer.serialize_i64(*i),
690                LoroValue::String(s) => serializer.serialize_str(s),
691                LoroValue::Binary(b) => serializer.collect_seq(b.iter()),
692                LoroValue::List(l) => serializer.collect_seq(l.iter()),
693                LoroValue::Map(m) => serializer.collect_map(m.iter()),
694                LoroValue::Container(id) => {
695                    serializer.serialize_str(&format!("{}{}", LORO_CONTAINER_ID_PREFIX, id))
696                }
697            }
698        } else {
699            // binary type
700            match self {
701                LoroValue::Null => serializer.serialize_unit_variant("LoroValue", 0, "Null"),
702                LoroValue::Bool(b) => {
703                    serializer.serialize_newtype_variant("LoroValue", 1, "Bool", b)
704                }
705                LoroValue::Double(d) => {
706                    serializer.serialize_newtype_variant("LoroValue", 2, "Double", d)
707                }
708                LoroValue::I64(i) => serializer.serialize_newtype_variant("LoroValue", 3, "I32", i),
709                LoroValue::String(s) => {
710                    serializer.serialize_newtype_variant("LoroValue", 4, "String", &**s)
711                }
712
713                LoroValue::List(l) => {
714                    serializer.serialize_newtype_variant("LoroValue", 5, "List", &**l)
715                }
716                LoroValue::Map(m) => {
717                    serializer.serialize_newtype_variant("LoroValue", 6, "Map", &**m)
718                }
719                LoroValue::Container(id) => {
720                    serializer.serialize_newtype_variant("LoroValue", 7, "Container", id)
721                }
722                LoroValue::Binary(b) => {
723                    serializer.serialize_newtype_variant("LoroValue", 8, "Binary", &**b)
724                }
725            }
726        }
727    }
728}
729
730impl<'de> Deserialize<'de> for LoroValue {
731    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
732    where
733        D: serde::Deserializer<'de>,
734    {
735        if deserializer.is_human_readable() {
736            deserializer.deserialize_any(LoroValueVisitor)
737        } else {
738            deserializer.deserialize_enum(
739                "LoroValue",
740                &[
741                    "Null",
742                    "Bool",
743                    "Double",
744                    "I32",
745                    "String",
746                    "List",
747                    "Map",
748                    "Container",
749                    "Binary",
750                ],
751                LoroValueEnumVisitor,
752            )
753        }
754    }
755}
756
757struct LoroValueVisitor;
758
759impl<'de> serde::de::Visitor<'de> for LoroValueVisitor {
760    type Value = LoroValue;
761
762    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
763        formatter.write_str("a LoroValue")
764    }
765
766    fn visit_unit<E>(self) -> Result<Self::Value, E>
767    where
768        E: serde::de::Error,
769    {
770        Ok(LoroValue::Null)
771    }
772
773    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
774    where
775        E: serde::de::Error,
776    {
777        Ok(LoroValue::Bool(v))
778    }
779
780    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
781    where
782        E: serde::de::Error,
783    {
784        Ok(LoroValue::I64(v))
785    }
786
787    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
788    where
789        E: serde::de::Error,
790    {
791        Ok(LoroValue::I64(v as i64))
792    }
793
794    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
795    where
796        E: serde::de::Error,
797    {
798        Ok(LoroValue::Double(v))
799    }
800
801    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
802    where
803        E: serde::de::Error,
804    {
805        if let Some(id) = v.strip_prefix(LORO_CONTAINER_ID_PREFIX) {
806            return Ok(LoroValue::Container(
807                ContainerID::try_from(id)
808                    .map_err(|_| serde::de::Error::custom("Invalid container id"))?,
809            ));
810        }
811        Ok(LoroValue::String(v.to_owned().into()))
812    }
813
814    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
815    where
816        E: serde::de::Error,
817    {
818        if let Some(id) = v.strip_prefix(LORO_CONTAINER_ID_PREFIX) {
819            return Ok(LoroValue::Container(
820                ContainerID::try_from(id)
821                    .map_err(|_| serde::de::Error::custom("Invalid container id"))?,
822            ));
823        }
824
825        Ok(LoroValue::String(v.into()))
826    }
827
828    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
829    where
830        E: serde::de::Error,
831    {
832        let binary = Vec::from_iter(v.iter().copied());
833        Ok(LoroValue::Binary(binary.into()))
834    }
835
836    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
837    where
838        E: serde::de::Error,
839    {
840        let binary = Vec::from_iter(v.iter().copied());
841        Ok(LoroValue::Binary(binary.into()))
842    }
843
844    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
845    where
846        A: serde::de::SeqAccess<'de>,
847    {
848        let mut list = Vec::new();
849        while let Some(value) = seq.next_element()? {
850            list.push(value);
851        }
852        Ok(LoroValue::List(list.into()))
853    }
854
855    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
856    where
857        A: serde::de::MapAccess<'de>,
858    {
859        let mut ans: FxHashMap<String, _> = FxHashMap::default();
860        while let Some((key, value)) = map.next_entry::<String, _>()? {
861            ans.insert(key, value);
862        }
863
864        Ok(LoroValue::Map(ans.into()))
865    }
866}
867
868#[derive(Deserialize)]
869enum LoroValueFields {
870    Null,
871    Bool,
872    Double,
873    I32,
874    String,
875    List,
876    Map,
877    Container,
878    Binary,
879}
880
881struct LoroValueEnumVisitor;
882impl<'de> serde::de::Visitor<'de> for LoroValueEnumVisitor {
883    type Value = LoroValue;
884    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
885        formatter.write_str("a loro value")
886    }
887
888    fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
889    where
890        A: serde::de::EnumAccess<'de>,
891    {
892        match data.variant()? {
893            (LoroValueFields::Null, v) => {
894                v.unit_variant()?;
895                Ok(LoroValue::Null)
896            }
897            (LoroValueFields::Bool, v) => v.newtype_variant().map(LoroValue::Bool),
898            (LoroValueFields::Double, v) => v.newtype_variant().map(LoroValue::Double),
899            (LoroValueFields::I32, v) => v.newtype_variant().map(LoroValue::I64),
900            (LoroValueFields::String, v) => v
901                .newtype_variant()
902                .map(|x: String| LoroValue::String(x.into())),
903            (LoroValueFields::List, v) => v
904                .newtype_variant()
905                .map(|x: Vec<LoroValue>| LoroValue::List(x.into())),
906            (LoroValueFields::Map, v) => v
907                .newtype_variant()
908                .map(|x: FxHashMap<String, LoroValue>| LoroValue::Map(x.into())),
909            (LoroValueFields::Container, v) => v.newtype_variant().map(LoroValue::Container),
910            (LoroValueFields::Binary, v) => v
911                .newtype_variant()
912                .map(|x: Vec<u8>| LoroValue::Binary(x.into())),
913        }
914    }
915}
916
917pub fn to_value<T: Into<LoroValue>>(value: T) -> LoroValue {
918    value.into()
919}
920
921#[cfg(feature = "serde_json")]
922mod serde_json_impl {
923    use serde_json::{Number, Value};
924
925    use super::LoroValue;
926
927    impl From<Value> for LoroValue {
928        fn from(value: Value) -> Self {
929            match value {
930                Value::Null => LoroValue::Null,
931                Value::Bool(b) => LoroValue::Bool(b),
932                Value::Number(n) => {
933                    if let Some(i) = n.as_i64() {
934                        LoroValue::I64(i)
935                    } else {
936                        LoroValue::Double(n.as_f64().unwrap())
937                    }
938                }
939                Value::String(s) => LoroValue::String(s.into()),
940                Value::Array(arr) => {
941                    LoroValue::List(arr.into_iter().map(LoroValue::from).collect())
942                }
943                Value::Object(obj) => LoroValue::Map(
944                    obj.into_iter()
945                        .map(|(k, v)| (k, LoroValue::from(v)))
946                        .collect(),
947                ),
948            }
949        }
950    }
951
952    use super::LORO_CONTAINER_ID_PREFIX;
953    impl From<LoroValue> for Value {
954        fn from(value: LoroValue) -> Self {
955            match value {
956                LoroValue::Null => Value::Null,
957                LoroValue::Bool(b) => Value::Bool(b),
958                LoroValue::Double(d) => Value::Number(Number::from_f64(d).unwrap()),
959                LoroValue::I64(i) => Value::Number(Number::from(i)),
960                LoroValue::String(s) => Value::String(s.to_string()),
961                LoroValue::List(l) => Value::Array(l.iter().cloned().map(Value::from).collect()),
962                LoroValue::Map(m) => Value::Object(
963                    m.iter()
964                        .map(|(k, v)| (k.clone(), Value::from(v.clone())))
965                        .collect(),
966                ),
967                LoroValue::Container(id) => {
968                    Value::String(format!("{}{}", LORO_CONTAINER_ID_PREFIX, id))
969                }
970                LoroValue::Binary(b) => Value::Array(b.iter().copied().map(Value::from).collect()),
971            }
972        }
973    }
974}