loro_ffi/container/
map.rs

1use std::sync::Arc;
2
3use loro::{ContainerTrait, LoroResult, PeerID};
4
5use crate::{
6    ContainerID, DiffEvent, LoroDoc, LoroValue, LoroValueLike, Subscriber, Subscription,
7    ValueOrContainer,
8};
9
10use super::{LoroCounter, LoroList, LoroMovableList, LoroText, LoroTree};
11
12#[derive(Debug, Clone)]
13pub struct LoroMap {
14    pub(crate) inner: loro::LoroMap,
15}
16
17impl LoroMap {
18    pub fn new() -> Self {
19        Self {
20            inner: loro::LoroMap::new(),
21        }
22    }
23
24    pub fn is_attached(&self) -> bool {
25        self.inner.is_attached()
26    }
27
28    /// If a detached container is attached, this method will return its corresponding attached handler.
29    pub fn get_attached(&self) -> Option<Arc<LoroMap>> {
30        self.inner
31            .get_attached()
32            .map(|x| Arc::new(LoroMap { inner: x }))
33    }
34
35    /// Delete a key-value pair from the map.
36    pub fn delete(&self, key: &str) -> LoroResult<()> {
37        self.inner.delete(key)
38    }
39
40    /// Iterate over the key-value pairs of the map.
41    // pub fn for_each<I>(&self, f: I)
42    // where
43    //     I: FnMut(&str, loro::ValueOrContainer),
44    // {
45    //     self.map.for_each(f)
46    // }
47    /// Insert a key-value pair into the map.
48    pub fn insert(&self, key: &str, value: Arc<dyn LoroValueLike>) -> LoroResult<()> {
49        self.inner.insert(key, value.as_loro_value())
50    }
51
52    /// Get the length of the map.
53    pub fn len(&self) -> u32 {
54        self.inner.len() as u32
55    }
56
57    /// Get the ID of the map.
58    pub fn id(&self) -> ContainerID {
59        self.inner.id().into()
60    }
61
62    /// Whether the map is empty.
63    pub fn is_empty(&self) -> bool {
64        self.inner.is_empty()
65    }
66
67    /// Get the value of the map with the given key.
68    pub fn get(&self, key: &str) -> Option<Arc<dyn ValueOrContainer>> {
69        self.inner
70            .get(key)
71            .map(|v| Arc::new(v) as Arc<dyn ValueOrContainer>)
72    }
73
74    // TODO: uniffi v0.29
75    pub fn get_or_create_text_container(
76        &self,
77        key: &str,
78        text: Arc<LoroText>,
79    ) -> LoroResult<Arc<LoroText>> {
80        let c = self
81            .inner
82            .get_or_create_container(key, text.as_ref().clone().inner)?;
83        Ok(Arc::new(LoroText { inner: c }))
84    }
85
86    pub fn get_or_create_map_container(
87        &self,
88        key: &str,
89        map: Arc<LoroMap>,
90    ) -> LoroResult<Arc<LoroMap>> {
91        let c = self
92            .inner
93            .get_or_create_container(key, map.as_ref().clone().inner)?;
94        Ok(Arc::new(LoroMap { inner: c }))
95    }
96
97    pub fn get_or_create_tree_container(
98        &self,
99        key: &str,
100        tree: Arc<LoroTree>,
101    ) -> LoroResult<Arc<LoroTree>> {
102        let c = self
103            .inner
104            .get_or_create_container(key, tree.as_ref().clone().inner)?;
105        Ok(Arc::new(LoroTree { inner: c }))
106    }
107
108    pub fn get_or_create_list_container(
109        &self,
110        key: &str,
111        list: Arc<LoroList>,
112    ) -> LoroResult<Arc<LoroList>> {
113        let c = self
114            .inner
115            .get_or_create_container(key, list.as_ref().clone().inner)?;
116        Ok(Arc::new(LoroList { inner: c }))
117    }
118
119    pub fn get_or_create_movable_list_container(
120        &self,
121        key: &str,
122        list: Arc<LoroMovableList>,
123    ) -> LoroResult<Arc<LoroMovableList>> {
124        let c = self
125            .inner
126            .get_or_create_container(key, list.as_ref().clone().inner)?;
127        Ok(Arc::new(LoroMovableList { inner: c }))
128    }
129
130    pub fn get_or_create_counter_container(
131        &self,
132        key: &str,
133        counter: Arc<LoroCounter>,
134    ) -> LoroResult<Arc<LoroCounter>> {
135        let c = self
136            .inner
137            .get_or_create_container(key, counter.as_ref().clone().inner)?;
138        Ok(Arc::new(LoroCounter { inner: c }))
139    }
140
141    #[inline]
142    pub fn insert_list_container(
143        &self,
144        key: &str,
145        child: Arc<LoroList>,
146    ) -> LoroResult<Arc<LoroList>> {
147        let c = self
148            .inner
149            .insert_container(key, child.as_ref().clone().inner)?;
150        Ok(Arc::new(LoroList { inner: c }))
151    }
152
153    #[inline]
154    pub fn insert_map_container(&self, key: &str, child: Arc<LoroMap>) -> LoroResult<Arc<LoroMap>> {
155        let c = self
156            .inner
157            .insert_container(key, child.as_ref().clone().inner)?;
158        Ok(Arc::new(LoroMap { inner: c }))
159    }
160
161    #[inline]
162    pub fn insert_text_container(
163        &self,
164        key: &str,
165        child: Arc<LoroText>,
166    ) -> LoroResult<Arc<LoroText>> {
167        let c = self
168            .inner
169            .insert_container(key, child.as_ref().clone().inner)?;
170        Ok(Arc::new(LoroText { inner: c }))
171    }
172
173    #[inline]
174    pub fn insert_tree_container(
175        &self,
176        key: &str,
177        child: Arc<LoroTree>,
178    ) -> LoroResult<Arc<LoroTree>> {
179        let c = self
180            .inner
181            .insert_container(key, child.as_ref().clone().inner)?;
182        Ok(Arc::new(LoroTree { inner: c }))
183    }
184
185    #[inline]
186    pub fn insert_movable_list_container(
187        &self,
188        key: &str,
189        child: Arc<LoroMovableList>,
190    ) -> LoroResult<Arc<LoroMovableList>> {
191        let c = self
192            .inner
193            .insert_container(key, child.as_ref().clone().inner)?;
194        Ok(Arc::new(LoroMovableList { inner: c }))
195    }
196
197    #[inline]
198    pub fn insert_counter_container(
199        &self,
200        key: &str,
201        child: Arc<LoroCounter>,
202    ) -> LoroResult<Arc<LoroCounter>> {
203        let c = self
204            .inner
205            .insert_container(key, child.as_ref().clone().inner)?;
206        Ok(Arc::new(LoroCounter { inner: c }))
207    }
208
209    /// Get the shallow value of the map.
210    ///
211    /// It will not convert the state of sub-containers, but represent them as [LoroValue::Container].
212    pub fn get_value(&self) -> LoroValue {
213        self.inner.get_value().into()
214    }
215
216    /// Get the deep value of the map.
217    ///
218    /// It will convert the state of sub-containers into a nested JSON value.
219    pub fn get_deep_value(&self) -> LoroValue {
220        self.inner.get_deep_value().into()
221    }
222
223    pub fn is_deleted(&self) -> bool {
224        self.inner.is_deleted()
225    }
226
227    pub fn get_last_editor(&self, key: &str) -> Option<PeerID> {
228        self.inner.get_last_editor(key)
229    }
230
231    pub fn clear(&self) -> LoroResult<()> {
232        self.inner.clear()
233    }
234
235    pub fn keys(&self) -> Vec<String> {
236        self.inner.keys().map(|k| k.to_string()).collect()
237    }
238
239    pub fn values(&self) -> Vec<Arc<dyn ValueOrContainer>> {
240        self.inner
241            .values()
242            .map(|v| Arc::new(v) as Arc<dyn ValueOrContainer>)
243            .collect()
244    }
245
246    pub fn doc(&self) -> Option<Arc<LoroDoc>> {
247        self.inner.doc().map(|x| Arc::new(LoroDoc { doc: x }))
248    }
249
250    pub fn subscribe(&self, subscriber: Arc<dyn Subscriber>) -> Option<Arc<Subscription>> {
251        self.inner
252            .subscribe(Arc::new(move |e| {
253                subscriber.on_diff(DiffEvent::from(e));
254            }))
255            .map(|x| Arc::new(x.into()))
256    }
257}
258
259impl Default for LoroMap {
260    fn default() -> Self {
261        Self::new()
262    }
263}