loro_ffi/
lib.rs

1mod value;
2
3pub use loro::{
4    cursor::{PosType, Side},
5    undo::UndoOrRedo,
6    CannotFindRelativePosition, ChangeTravelError, Counter, CounterSpan, EventTriggerKind,
7    ExpandType, IdLp, IdSpan, JsonChange, JsonFutureOp, JsonFutureOpWrapper, JsonListOp, JsonMapOp,
8    JsonMovableListOp, JsonOp, JsonOpContent, JsonSchema, JsonTextOp, JsonTreeOp, Lamport,
9    LoroEncodeError, LoroError, PeerID, StyleConfig, TreeID, UpdateOptions, UpdateTimeoutError, ID,
10    LORO_VERSION,
11};
12
13pub use loro::jsonpath::{jsonpath_impl::JsonPathError, SubscribeJsonPathCallback};
14use loro::{Container, ContainerTrait};
15pub use std::cmp::Ordering;
16use std::sync::Arc;
17pub use value::*;
18mod doc;
19pub use doc::*;
20mod container;
21pub use container::*;
22mod event;
23pub use event::*;
24mod undo;
25pub use undo::*;
26mod config;
27pub use config::*;
28mod version;
29pub use version::*;
30mod awareness;
31pub use awareness::*;
32mod ephemeral;
33pub use ephemeral::*;
34mod fractional_index;
35pub use fractional_index::*;
36
37// https://github.com/mozilla/uniffi-rs/issues/1372
38pub trait ValueOrContainer: Send + Sync {
39    fn is_value(&self) -> bool;
40    fn is_container(&self) -> bool;
41    fn as_value(&self) -> Option<LoroValue>;
42    fn container_type(&self) -> Option<ContainerType>;
43    fn as_container(&self) -> Option<ContainerID>;
44    fn as_loro_list(&self) -> Option<Arc<LoroList>>;
45    fn as_loro_text(&self) -> Option<Arc<LoroText>>;
46    fn as_loro_map(&self) -> Option<Arc<LoroMap>>;
47    fn as_loro_movable_list(&self) -> Option<Arc<LoroMovableList>>;
48    fn as_loro_tree(&self) -> Option<Arc<LoroTree>>;
49    fn as_loro_counter(&self) -> Option<Arc<LoroCounter>>;
50    fn as_loro_unknown(&self) -> Option<Arc<LoroUnknown>>;
51}
52
53impl ValueOrContainer for loro::ValueOrContainer {
54    fn is_value(&self) -> bool {
55        loro::ValueOrContainer::is_value(self)
56    }
57
58    fn is_container(&self) -> bool {
59        loro::ValueOrContainer::is_container(self)
60    }
61
62    fn container_type(&self) -> Option<ContainerType> {
63        loro::ValueOrContainer::as_container(self).map(|c| c.id().container_type().into())
64    }
65
66    fn as_value(&self) -> Option<LoroValue> {
67        loro::ValueOrContainer::as_value(self)
68            .cloned()
69            .map(LoroValue::from)
70    }
71
72    // TODO: pass Container to Swift
73    fn as_container(&self) -> Option<ContainerID> {
74        loro::ValueOrContainer::as_container(self).map(|c| c.id().into())
75    }
76
77    fn as_loro_list(&self) -> Option<Arc<LoroList>> {
78        match self {
79            loro::ValueOrContainer::Container(Container::List(list)) => Some(Arc::new(LoroList {
80                inner: list.clone(),
81            })),
82            _ => None,
83        }
84    }
85
86    fn as_loro_text(&self) -> Option<Arc<LoroText>> {
87        match self {
88            loro::ValueOrContainer::Container(Container::Text(c)) => {
89                Some(Arc::new(LoroText { inner: c.clone() }))
90            }
91            _ => None,
92        }
93    }
94
95    fn as_loro_map(&self) -> Option<Arc<LoroMap>> {
96        match self {
97            loro::ValueOrContainer::Container(Container::Map(c)) => {
98                Some(Arc::new(LoroMap { inner: c.clone() }))
99            }
100            _ => None,
101        }
102    }
103
104    fn as_loro_movable_list(&self) -> Option<Arc<LoroMovableList>> {
105        match self {
106            loro::ValueOrContainer::Container(Container::MovableList(c)) => {
107                Some(Arc::new(LoroMovableList { inner: c.clone() }))
108            }
109            _ => None,
110        }
111    }
112
113    fn as_loro_tree(&self) -> Option<Arc<LoroTree>> {
114        match self {
115            loro::ValueOrContainer::Container(Container::Tree(c)) => {
116                Some(Arc::new(LoroTree { inner: c.clone() }))
117            }
118            _ => None,
119        }
120    }
121
122    fn as_loro_counter(&self) -> Option<Arc<LoroCounter>> {
123        match self {
124            loro::ValueOrContainer::Container(Container::Counter(c)) => {
125                Some(Arc::new(LoroCounter { inner: c.clone() }))
126            }
127            _ => None,
128        }
129    }
130
131    fn as_loro_unknown(&self) -> Option<Arc<LoroUnknown>> {
132        match self {
133            loro::ValueOrContainer::Container(Container::Unknown(c)) => {
134                Some(Arc::new(LoroUnknown { inner: c.clone() }))
135            }
136            _ => None,
137        }
138    }
139}
140
141fn convert_trait_to_v_or_container<T: AsRef<dyn ValueOrContainer>>(i: T) -> loro::ValueOrContainer {
142    let v = i.as_ref();
143    if v.is_value() {
144        loro::ValueOrContainer::Value(v.as_value().unwrap().into())
145    } else {
146        let container = match v.container_type().unwrap() {
147            ContainerType::List => Container::List((*v.as_loro_list().unwrap()).clone().inner),
148            ContainerType::Text => Container::Text((*v.as_loro_text().unwrap()).clone().inner),
149            ContainerType::Map => Container::Map((*v.as_loro_map().unwrap()).clone().inner),
150            ContainerType::MovableList => {
151                Container::MovableList((*v.as_loro_movable_list().unwrap()).clone().inner)
152            }
153            ContainerType::Tree => Container::Tree((*v.as_loro_tree().unwrap()).clone().inner),
154            ContainerType::Counter => {
155                Container::Counter((*v.as_loro_counter().unwrap()).clone().inner)
156            }
157            ContainerType::Unknown { kind: _ } => {
158                Container::Unknown((*v.as_loro_unknown().unwrap()).clone().inner)
159            }
160        };
161        loro::ValueOrContainer::Container(container)
162    }
163}
164
165pub fn get_version() -> String {
166    LORO_VERSION.to_string()
167}
168
169uniffi::include_scaffolding!("loro");