loro_ffi/container/
list.rs1use std::{ops::Deref, sync::Arc};
2
3use loro::{cursor::Side, ContainerTrait, LoroError, LoroList as InnerLoroList, LoroResult, ID};
4
5use crate::{
6 ContainerID, DiffEvent, LoroDoc, LoroValue, LoroValueLike, Subscriber, Subscription,
7 ValueOrContainer,
8};
9
10use super::{LoroCounter, LoroMap, LoroMovableList, LoroText, LoroTree};
11
12#[derive(Debug, Clone)]
13pub struct LoroList {
14 pub(crate) inner: InnerLoroList,
15}
16
17impl LoroList {
18 pub fn new() -> Self {
19 Self {
20 inner: InnerLoroList::new(),
21 }
22 }
23
24 pub fn is_attached(&self) -> bool {
29 self.inner.is_attached()
30 }
31
32 pub fn get_attached(&self) -> Option<Arc<LoroList>> {
34 self.inner
35 .get_attached()
36 .map(|x| Arc::new(LoroList { inner: x }))
37 }
38
39 pub fn insert(&self, pos: u32, v: Arc<dyn LoroValueLike>) -> LoroResult<()> {
41 self.inner.insert(pos as usize, v.as_loro_value())
42 }
43
44 #[inline]
46 pub fn delete(&self, pos: u32, len: u32) -> LoroResult<()> {
47 self.inner.delete(pos as usize, len as usize)
48 }
49
50 #[inline]
52 pub fn get(&self, index: u32) -> Option<Arc<dyn ValueOrContainer>> {
53 self.inner
54 .get(index as usize)
55 .map(|v| Arc::new(v) as Arc<dyn ValueOrContainer>)
56 }
57
58 #[inline]
60 pub fn get_deep_value(&self) -> LoroValue {
61 self.inner.get_deep_value().into()
62 }
63
64 #[inline]
68 pub fn get_value(&self) -> LoroValue {
69 self.inner.get_value().into()
70 }
71
72 #[inline]
74 pub fn id(&self) -> ContainerID {
75 self.inner.id().into()
76 }
77
78 #[inline]
79 pub fn len(&self) -> u32 {
80 self.inner.len() as u32
81 }
82
83 #[inline]
84 pub fn is_empty(&self) -> bool {
85 self.inner.is_empty()
86 }
87
88 #[inline]
90 pub fn pop(&self) -> LoroResult<Option<LoroValue>> {
91 self.inner.pop().map(|v| v.map(|v| v.into()))
92 }
93
94 #[inline]
95 pub fn push(&self, v: Arc<dyn LoroValueLike>) -> LoroResult<()> {
96 self.inner.push(v.as_loro_value())
97 }
98
99 pub fn for_each<I>(&self, f: I)
102 where
103 I: FnMut(loro::ValueOrContainer),
104 {
105 self.inner.for_each(f)
106 }
107
108 #[inline]
116 pub fn insert_list_container(
117 &self,
118 pos: u32,
119 child: Arc<LoroList>,
120 ) -> LoroResult<Arc<LoroList>> {
121 let c = self
122 .inner
123 .insert_container(pos as usize, child.as_ref().clone().inner)?;
124 Ok(Arc::new(LoroList { inner: c }))
125 }
126
127 #[inline]
128 pub fn insert_map_container(&self, pos: u32, child: Arc<LoroMap>) -> LoroResult<Arc<LoroMap>> {
129 let c = self
130 .inner
131 .insert_container(pos as usize, child.as_ref().clone().inner)?;
132 Ok(Arc::new(LoroMap { inner: c }))
133 }
134
135 #[inline]
136 pub fn insert_text_container(
137 &self,
138 pos: u32,
139 child: Arc<LoroText>,
140 ) -> LoroResult<Arc<LoroText>> {
141 let c = self
142 .inner
143 .insert_container(pos as usize, child.as_ref().clone().inner)?;
144 Ok(Arc::new(LoroText { inner: c }))
145 }
146
147 #[inline]
148 pub fn insert_tree_container(
149 &self,
150 pos: u32,
151 child: Arc<LoroTree>,
152 ) -> LoroResult<Arc<LoroTree>> {
153 let c = self
154 .inner
155 .insert_container(pos as usize, child.as_ref().clone().inner)?;
156 Ok(Arc::new(LoroTree { inner: c }))
157 }
158
159 #[inline]
160 pub fn insert_movable_list_container(
161 &self,
162 pos: u32,
163 child: Arc<LoroMovableList>,
164 ) -> LoroResult<Arc<LoroMovableList>> {
165 let c = self
166 .inner
167 .insert_container(pos as usize, child.as_ref().clone().inner)?;
168 Ok(Arc::new(LoroMovableList { inner: c }))
169 }
170
171 #[inline]
172 pub fn insert_counter_container(
173 &self,
174 pos: u32,
175 child: Arc<LoroCounter>,
176 ) -> LoroResult<Arc<LoroCounter>> {
177 let c = self
178 .inner
179 .insert_container(pos as usize, child.as_ref().clone().inner)?;
180 Ok(Arc::new(LoroCounter { inner: c }))
181 }
182
183 pub fn get_cursor(&self, pos: u32, side: Side) -> Option<Arc<Cursor>> {
184 self.inner
185 .get_cursor(pos as usize, side)
186 .map(|v| Arc::new(v.into()))
187 }
188
189 pub fn is_deleted(&self) -> bool {
190 self.inner.is_deleted()
191 }
192
193 pub fn to_vec(&self) -> Vec<LoroValue> {
194 self.inner.to_vec().into_iter().map(|v| v.into()).collect()
195 }
196
197 pub fn clear(&self) -> LoroResult<()> {
198 self.inner.clear()
199 }
200
201 pub fn get_id_at(&self, index: u32) -> Option<ID> {
202 self.inner.get_id_at(index as usize)
203 }
204
205 pub fn doc(&self) -> Option<Arc<LoroDoc>> {
206 self.inner.doc().map(|x| Arc::new(LoroDoc { doc: x }))
207 }
208
209 pub fn subscribe(&self, subscriber: Arc<dyn Subscriber>) -> Option<Arc<Subscription>> {
210 self.inner
211 .subscribe(Arc::new(move |e| {
212 subscriber.on_diff(DiffEvent::from(e));
213 }))
214 .map(|x| Arc::new(x.into()))
215 }
216}
217
218impl Default for LoroList {
219 fn default() -> Self {
220 Self::new()
221 }
222}
223
224#[derive(Debug, Clone)]
225pub struct Cursor(loro::cursor::Cursor);
226
227impl Cursor {
228 pub fn new(id: Option<ID>, container: ContainerID, side: Side, origin_pos: u32) -> Self {
229 Self(loro::cursor::Cursor::new(
230 id,
231 container.into(),
232 side,
233 origin_pos as usize,
234 ))
235 }
236
237 pub fn encode(&self) -> Vec<u8> {
238 self.0.encode()
239 }
240
241 pub fn decode(data: &[u8]) -> LoroResult<Self> {
242 Ok(Self(loro::cursor::Cursor::decode(data).map_err(|e| {
243 LoroError::DecodeError(e.to_string().into_boxed_str())
244 })?))
245 }
246}
247
248impl Deref for Cursor {
249 type Target = loro::cursor::Cursor;
250
251 fn deref(&self) -> &Self::Target {
252 &self.0
253 }
254}
255
256impl From<loro::cursor::Cursor> for Cursor {
257 fn from(c: loro::cursor::Cursor) -> Self {
258 Self(c)
259 }
260}
261
262impl From<Cursor> for loro::cursor::Cursor {
263 fn from(c: Cursor) -> Self {
264 c.0
265 }
266}