y_octo/doc/types/
array.rs1use super::*;
2
3impl_type!(Array);
4
5impl ListType for Array {}
6
7pub struct ArrayIter(ListIterator);
8
9impl Iterator for ArrayIter {
10 type Item = Value;
11
12 fn next(&mut self) -> Option<Self::Item> {
13 for item in self.0.by_ref() {
14 if let Some(item) = item.get() {
15 if item.countable() {
16 return Some(item.content.as_ref().try_into().unwrap());
17 }
18 }
19 }
20
21 None
22 }
23}
24
25impl Array {
26 #[inline]
27 pub fn len(&self) -> u64 {
28 self.content_len()
29 }
30
31 #[inline]
32 pub fn is_empty(&self) -> bool {
33 self.len() == 0
34 }
35
36 pub fn get(&self, index: u64) -> Option<Value> {
37 let (item, offset) = self.get_item_at(index)?;
38 debug_assert!(offset == 0);
40 if let Some(item) = item.get() {
41 return match item.content.as_ref() {
43 Content::Any(any) => return any.first().map(|any| Value::Any(any.clone())),
44 _ => item.content.as_ref().try_into().map_or_else(|_| None, Some),
45 };
46 }
47
48 None
49 }
50
51 pub fn iter(&self) -> ArrayIter {
52 ArrayIter(self.iter_item())
53 }
54
55 pub fn push<V: Into<Value>>(&mut self, val: V) -> JwstCodecResult {
56 self.insert(self.len(), val)
57 }
58
59 pub fn insert<V: Into<Value>>(&mut self, idx: u64, val: V) -> JwstCodecResult {
60 self.insert_at(idx, val.into().into())
61 }
62
63 pub fn remove(&mut self, idx: u64, len: u64) -> JwstCodecResult {
64 self.remove_at(idx, len)
65 }
66}
67
68impl serde::Serialize for Array {
69 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70 where
71 S: serde::Serializer,
72 {
73 use serde::ser::SerializeSeq;
74
75 let mut seq = serializer.serialize_seq(Some(self.len() as usize))?;
76
77 for item in self.iter() {
78 seq.serialize_element(&item)?;
79 }
80 seq.end()
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use yrs::{Array, Options, Text, Transact};
87
88 use super::*;
89
90 #[test]
91 fn test_yarray_insert() {
92 let options = DocOptions {
93 client: Some(rand::random()),
94 guid: Some(nanoid::nanoid!()),
95 };
96
97 loom_model!({
98 let doc = Doc::with_options(options.clone());
99 let mut array = doc.get_or_create_array("abc").unwrap();
100
101 array.insert(0, " ").unwrap();
102 array.insert(0, "Hello").unwrap();
103 array.insert(2, "World").unwrap();
104
105 assert_eq!(array.get(0).unwrap(), Value::Any(Any::String("Hello".into())));
106 assert_eq!(array.get(1).unwrap(), Value::Any(Any::String(" ".into())));
107 assert_eq!(array.get(2).unwrap(), Value::Any(Any::String("World".into())));
108 });
109 }
110
111 #[test]
112 #[cfg_attr(miri, ignore)]
113 fn test_ytext_equal() {
114 let options = DocOptions {
115 client: Some(rand::random()),
116 guid: Some(nanoid::nanoid!()),
117 };
118 let yrs_options = Options {
119 client_id: rand::random(),
120 guid: nanoid::nanoid!().into(),
121 ..Default::default()
122 };
123
124 loom_model!({
125 let doc = yrs::Doc::with_options(yrs_options.clone());
126 let array = doc.get_or_insert_text("abc");
127
128 let mut trx = doc.transact_mut();
129 array.insert(&mut trx, 0, " ").unwrap();
130 array.insert(&mut trx, 0, "Hello").unwrap();
131 array.insert(&mut trx, 6, "World").unwrap();
132 array.insert(&mut trx, 11, "!").unwrap();
133 let buffer = trx.encode_update_v1().unwrap();
134
135 let mut decoder = RawDecoder::new(buffer);
136 let update = Update::read(&mut decoder).unwrap();
137
138 let mut doc = Doc::with_options(options.clone());
139 doc.apply_update(update).unwrap();
140 let array = doc.get_or_create_array("abc").unwrap();
141
142 assert_eq!(array.get(0).unwrap(), Value::Any(Any::String("Hello".into())));
143 assert_eq!(array.get(5).unwrap(), Value::Any(Any::String(" ".into())));
144 assert_eq!(array.get(6).unwrap(), Value::Any(Any::String("World".into())));
145 assert_eq!(array.get(11).unwrap(), Value::Any(Any::String("!".into())));
146 });
147
148 let options = DocOptions {
149 client: Some(rand::random()),
150 guid: Some(nanoid::nanoid!()),
151 };
152 let yrs_options = Options {
153 client_id: rand::random(),
154 guid: nanoid::nanoid!().into(),
155 ..Default::default()
156 };
157 loom_model!({
158 let doc = yrs::Doc::with_options(yrs_options.clone());
159 let array = doc.get_or_insert_text("abc");
160
161 let mut trx = doc.transact_mut();
162 array.insert(&mut trx, 0, "Hello").unwrap();
163 array.insert(&mut trx, 5, " ").unwrap();
164 array.insert(&mut trx, 6, "World").unwrap();
165 array.insert(&mut trx, 11, "!").unwrap();
166 let buffer = trx.encode_update_v1().unwrap();
167
168 let mut decoder = RawDecoder::new(buffer);
169 let update = Update::read(&mut decoder).unwrap();
170
171 let mut doc = Doc::with_options(options.clone());
172 doc.apply_update(update).unwrap();
173 let array = doc.get_or_create_array("abc").unwrap();
174
175 assert_eq!(array.get(0).unwrap(), Value::Any(Any::String("Hello".into())));
176 assert_eq!(array.get(5).unwrap(), Value::Any(Any::String(" ".into())));
177 assert_eq!(array.get(6).unwrap(), Value::Any(Any::String("World".into())));
178 assert_eq!(array.get(11).unwrap(), Value::Any(Any::String("!".into())));
179 });
180 }
181
182 #[test]
183 #[cfg_attr(miri, ignore)]
184 fn test_yrs_array_decode() {
185 let update = {
186 let doc = yrs::Doc::new();
187 let array = doc.get_or_insert_array("abc");
188 let mut trx = doc.transact_mut();
189
190 array.insert(&mut trx, 0, "hello").unwrap();
191 array.insert(&mut trx, 1, "world").unwrap();
192 array.insert(&mut trx, 1, " ").unwrap();
193
194 trx.encode_update_v1().unwrap()
195 };
196
197 loom_model!({
198 let doc = Doc::new_from_binary_with_options(
199 update.clone(),
200 DocOptions {
201 guid: Some(String::from("1")),
202 client: Some(1),
203 },
204 )
205 .unwrap();
206 let arr = doc.get_or_create_array("abc").unwrap();
207
208 assert_eq!(arr.get(2).unwrap(), Value::Any(Any::String("world".to_string())))
209 });
210 }
211}