y-rb 0.1.4.beta.1-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ use crate::yvalue::YValue;
2
+ use crate::YTransaction;
3
+ use lib0::any::Any;
4
+ use magnus::block::Proc;
5
+ use magnus::value::Qnil;
6
+ use magnus::{Error, RArray, RHash, Symbol, Value};
7
+ use std::cell::RefCell;
8
+ use yrs::types::Change;
9
+ use yrs::Array;
10
+
11
+ #[magnus::wrap(class = "Y::Array")]
12
+ pub(crate) struct YArray(pub(crate) RefCell<Array>);
13
+
14
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
15
+ unsafe impl Send for YArray {}
16
+
17
+ impl YArray {
18
+ pub(crate) fn yarray_each(&self, block: Proc) -> () {
19
+ self.0.borrow_mut().iter().for_each(|val| {
20
+ let yvalue = YValue::from(val);
21
+ let args = (yvalue.into(),);
22
+ let _ = block.call::<(Value,), Qnil>(args);
23
+ });
24
+ }
25
+ pub(crate) fn yarray_get(&self, index: u32) -> Value {
26
+ let v = self.0.borrow().get(index).unwrap();
27
+ YValue::from(v).into()
28
+ }
29
+ pub(crate) fn yarray_insert(
30
+ &self,
31
+ transaction: &YTransaction,
32
+ index: u32,
33
+ value: Value
34
+ ) -> () {
35
+ let yvalue = YValue::from(value);
36
+ let avalue = Any::from(yvalue);
37
+ self.0.borrow_mut().insert(
38
+ &mut *transaction.0.borrow_mut(),
39
+ index,
40
+ avalue
41
+ );
42
+ }
43
+ pub(crate) fn yarray_insert_range(
44
+ &self,
45
+ transaction: &YTransaction,
46
+ index: u32,
47
+ values: RArray
48
+ ) -> () {
49
+ let arr: Vec<Any> = values
50
+ .each()
51
+ .into_iter()
52
+ .map(|value| YValue::from(value.unwrap()).into())
53
+ .collect();
54
+
55
+ self.0.borrow_mut().insert_range(
56
+ &mut *transaction.0.borrow_mut(),
57
+ index,
58
+ arr
59
+ );
60
+ }
61
+ pub(crate) fn yarray_length(&self) -> u32 {
62
+ return self.0.borrow().len();
63
+ }
64
+ pub(crate) fn yarray_observe(&self, block: Proc) -> Result<u32, Error> {
65
+ let change_added = Symbol::new("added").to_static();
66
+ let change_retain = Symbol::new("retain").to_static();
67
+ let change_removed = Symbol::new("removed").to_static();
68
+
69
+ // let mut error: Option<Error> = None;
70
+
71
+ let subscription_id = self
72
+ .0
73
+ .borrow_mut()
74
+ .observe(move |transaction, array_event| {
75
+ let delta = array_event.delta(transaction);
76
+ // let mut changes = RArray::with_capacity(delta.len());
77
+ let (changes, errors): (Vec<_>, Vec<_>) = delta
78
+ .iter()
79
+ .map(|change| {
80
+ let payload = RHash::new();
81
+ let result = match change {
82
+ Change::Added(v) => {
83
+ let values = v
84
+ .iter()
85
+ .map(|v| {
86
+ <YValue as Into<Value>>::into(
87
+ YValue::from(v.clone())
88
+ )
89
+ })
90
+ .collect::<RArray>();
91
+ payload.aset(change_added, values)
92
+ }
93
+ Change::Retain(position) => payload
94
+ .aset(change_retain, Value::from(*position)),
95
+ Change::Removed(position) => payload
96
+ .aset(change_removed, Value::from(*position))
97
+ };
98
+
99
+ match result {
100
+ Ok(()) => Ok(payload),
101
+ Err(e) => Err(e)
102
+ }
103
+ })
104
+ .partition(Result::is_ok);
105
+
106
+ if errors.len() == 0 {
107
+ let args = (RArray::from_vec(
108
+ changes.into_iter().map(Result::unwrap).collect()
109
+ ),);
110
+ let _ = block.call::<(RArray,), Qnil>(args);
111
+ // todo: make sure we respect the result and bubble up the
112
+ // error so that we can return as part of the Result
113
+ }
114
+
115
+ // todo: make sure we respect errors and let the method fail by
116
+ // by returning a Result containing an Error
117
+ })
118
+ .into();
119
+
120
+ Ok(subscription_id)
121
+ }
122
+ pub(crate) fn yarray_push_back(
123
+ &self,
124
+ transaction: &YTransaction,
125
+ value: Value
126
+ ) -> () {
127
+ let yvalue = YValue::from(value);
128
+ let avalue = Any::from(yvalue);
129
+ self.0
130
+ .borrow_mut()
131
+ .push_back(&mut *transaction.0.borrow_mut(), avalue)
132
+ }
133
+ pub(crate) fn yarray_push_front(
134
+ &self,
135
+ transaction: &YTransaction,
136
+ value: Value
137
+ ) -> () {
138
+ let yvalue = YValue::from(value);
139
+ let avalue = Any::from(yvalue);
140
+ self.0
141
+ .borrow_mut()
142
+ .push_front(&mut *transaction.0.borrow_mut(), avalue)
143
+ }
144
+ pub(crate) fn yarray_remove(
145
+ &self,
146
+ transaction: &YTransaction,
147
+ index: u32
148
+ ) -> () {
149
+ self.0
150
+ .borrow_mut()
151
+ .remove(&mut transaction.0.borrow_mut(), index)
152
+ }
153
+ pub(crate) fn yarray_remove_range(
154
+ &self,
155
+ transaction: &YTransaction,
156
+ index: u32,
157
+ len: u32
158
+ ) -> () {
159
+ self.0.borrow_mut().remove_range(
160
+ &mut transaction.0.borrow_mut(),
161
+ index,
162
+ len
163
+ )
164
+ }
165
+ pub(crate) fn yarray_to_a(&self) -> RArray {
166
+ let arr = self
167
+ .0
168
+ .borrow_mut()
169
+ .iter()
170
+ .map(|v| YValue::from(v).into())
171
+ .collect::<Vec<Value>>();
172
+
173
+ return RArray::from_vec(arr);
174
+ }
175
+ pub(crate) fn yarray_unobserve(&self, subscription_id: u32) -> () {
176
+ self.0.borrow_mut().unobserve(subscription_id);
177
+ }
178
+ }
@@ -0,0 +1,48 @@
1
+ use crate::yvalue::YValue;
2
+ use lib0::any::Any;
3
+ use magnus::r_hash::ForEach::Continue;
4
+ use magnus::{RHash, Value};
5
+ use std::ops::{Deref, DerefMut};
6
+ use std::rc::Rc;
7
+ use yrs::types::Attrs;
8
+
9
+ pub(crate) struct YAttrs(pub(crate) Attrs);
10
+
11
+ impl From<Attrs> for YAttrs {
12
+ fn from(value: Attrs) -> Self {
13
+ YAttrs { 0: value }
14
+ }
15
+ }
16
+
17
+ impl From<RHash> for YAttrs {
18
+ fn from(value: RHash) -> Self {
19
+ let mut attrs = Attrs::new();
20
+
21
+ value
22
+ .foreach(|key: Value, value: Value| {
23
+ let k = key.to_string();
24
+ let yvalue = YValue::from(value);
25
+ let avalue = Any::from(yvalue);
26
+ attrs.insert(Rc::from(k), avalue);
27
+
28
+ Ok(Continue)
29
+ })
30
+ .expect("cannot iterate attributes hash");
31
+
32
+ YAttrs { 0: attrs }
33
+ }
34
+ }
35
+
36
+ impl Deref for YAttrs {
37
+ type Target = Attrs;
38
+
39
+ fn deref(&self) -> &Self::Target {
40
+ &self.0
41
+ }
42
+ }
43
+
44
+ impl DerefMut for YAttrs {
45
+ fn deref_mut(&mut self) -> &mut Self::Target {
46
+ &mut self.0
47
+ }
48
+ }
@@ -0,0 +1,39 @@
1
+ use crate::YTransaction;
2
+ use magnus::{Error, Integer, Value};
3
+ use std::cell::RefCell;
4
+ use yrs::updates::decoder::Decode;
5
+ use yrs::{Doc, OffsetKind, Options, StateVector};
6
+
7
+ #[magnus::wrap(class = "Y::Doc")]
8
+ pub(crate) struct YDoc(pub(crate) RefCell<Doc>);
9
+
10
+ impl YDoc {
11
+ pub(crate) fn ydoc_new(client_id: &[Value]) -> Self {
12
+ let mut options = Options::default();
13
+
14
+ if client_id.len() == 1 {
15
+ let value = client_id.first().unwrap();
16
+ options.client_id =
17
+ Integer::from_value(*value).unwrap().to_u64().unwrap();
18
+ }
19
+
20
+ options.offset_kind = OffsetKind::Utf32;
21
+
22
+ let doc = Doc::with_options(options);
23
+ Self(RefCell::new(doc))
24
+ }
25
+
26
+ pub(crate) fn ydoc_transact(&self) -> YTransaction {
27
+ let transaction = self.0.borrow().transact();
28
+
29
+ return YTransaction(RefCell::new(transaction));
30
+ }
31
+ pub(crate) fn ydoc_encode_diff_v1(
32
+ &self,
33
+ state_vector: Vec<u8>,
34
+ ) -> Result<Vec<u8>, Error> {
35
+ return StateVector::decode_v1(&*state_vector)
36
+ .map(|sv| self.0.borrow().encode_state_as_update_v1(&sv))
37
+ .map_err(|_e| Error::runtime_error("cannot encode diff"));
38
+ }
39
+ }
@@ -0,0 +1,168 @@
1
+ use crate::utils::indifferent_hash_key;
2
+ use crate::yvalue::YValue;
3
+ use crate::YTransaction;
4
+ use lib0::any::Any;
5
+ use magnus::block::Proc;
6
+ use magnus::{Error, RArray, RHash, Symbol, Value};
7
+ use std::cell::RefCell;
8
+ use yrs::types::{EntryChange, Value as YrsValue};
9
+ use yrs::Map;
10
+
11
+ #[magnus::wrap(class = "Y::Map")]
12
+ pub(crate) struct YMap(pub(crate) RefCell<Map>);
13
+
14
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
15
+ unsafe impl Send for YMap {}
16
+
17
+ impl YMap {
18
+ pub(crate) fn ymap_clear(&self, transaction: &YTransaction) {
19
+ self.0.borrow_mut().clear(&mut *transaction.0.borrow_mut());
20
+ }
21
+ pub(crate) fn ymap_contains(&self, key: Value) -> bool {
22
+ match indifferent_hash_key(key) {
23
+ None => false,
24
+ Some(k) => self.0.borrow().contains(&*k)
25
+ }
26
+ }
27
+ pub(crate) fn ymap_each(&self, proc: Proc) {
28
+ self.0.borrow().iter().for_each(|(key, val)| {
29
+ let k = key.to_string();
30
+ let v = *YValue::from(val).0.borrow();
31
+ proc.call::<(String, Value), Value>((k, v))
32
+ .expect("cannot iterate map");
33
+ });
34
+ }
35
+ pub(crate) fn ymap_get(&self, key: Value) -> Option<Value> {
36
+ indifferent_hash_key(key)
37
+ .map(|k| self.0.borrow().get(&*k))
38
+ .map(|v| v.unwrap_or(YrsValue::Any(Any::Undefined)))
39
+ .map(|v| *YValue::from(v).0.borrow())
40
+ }
41
+ pub(crate) fn ymap_insert(
42
+ &self,
43
+ transaction: &YTransaction,
44
+ key: Value,
45
+ value: Value
46
+ ) -> Result<(), Error> {
47
+ match indifferent_hash_key(key) {
48
+ None => Err(Error::runtime_error(
49
+ "invalid key type, make sure it is either a Symbol or a String"
50
+ )),
51
+ Some(k) => {
52
+ let v = Any::from(YValue::from(value));
53
+ self.0.borrow_mut().insert(
54
+ &mut *transaction.0.borrow_mut(),
55
+ k,
56
+ v
57
+ );
58
+
59
+ Ok(())
60
+ }
61
+ }
62
+ }
63
+ pub(crate) fn ymap_observe(&self, block: Proc) -> u32 {
64
+ let change_inserted = Symbol::new("inserted").as_static();
65
+ let change_updated = Symbol::new("updated").as_static();
66
+ let change_removed = Symbol::new("removed").as_static();
67
+
68
+ self.0
69
+ .borrow_mut()
70
+ .observe(move |transaction, map_event| {
71
+ let delta = map_event.keys(transaction);
72
+ let changes = RArray::with_capacity(delta.len());
73
+
74
+ for (key, change) in delta {
75
+ match change {
76
+ EntryChange::Inserted(v) => {
77
+ let h = RHash::new();
78
+ h.aset(
79
+ Symbol::new(&key.to_string()),
80
+ *YValue::from(v.clone()).0.borrow()
81
+ )
82
+ .expect("cannot add change::inserted");
83
+
84
+ let payload = RHash::new();
85
+ payload
86
+ .aset(change_inserted, h)
87
+ .expect("cannot add change::inserted");
88
+
89
+ changes
90
+ .push(payload)
91
+ .expect("cannot push changes::payload");
92
+ }
93
+ EntryChange::Updated(old, new) => {
94
+ let values = RArray::with_capacity(2);
95
+ values
96
+ .push(*YValue::from(old.clone()).0.borrow())
97
+ .expect("cannot push change::updated");
98
+ values
99
+ .push(*YValue::from(new.clone()).0.borrow())
100
+ .expect("cannot push change::updated");
101
+
102
+ let h = RHash::new();
103
+ h.aset(Symbol::new(&key.to_string()), values)
104
+ .expect("cannot push change::updated");
105
+
106
+ let payload = RHash::new();
107
+ payload
108
+ .aset(change_updated, h)
109
+ .expect("cannot push change::updated");
110
+
111
+ changes
112
+ .push(payload)
113
+ .expect("cannot push changes::payload");
114
+ }
115
+ EntryChange::Removed(v) => {
116
+ let h = RHash::new();
117
+ h.aset(
118
+ Symbol::new(&key.to_string()),
119
+ *YValue::from(v.clone()).0.borrow()
120
+ )
121
+ .expect("cannot push change::removed");
122
+
123
+ let payload = RHash::new();
124
+ payload
125
+ .aset(change_removed, h)
126
+ .expect("cannot push change::removed");
127
+
128
+ changes
129
+ .push(payload)
130
+ .expect("cannot push changes::payload");
131
+ }
132
+ }
133
+ }
134
+
135
+ block
136
+ .call::<(RArray,), Value>((changes,))
137
+ .expect("cannot call block");
138
+ })
139
+ .into()
140
+ }
141
+ pub(crate) fn ymap_remove(
142
+ &self,
143
+ transaction: &YTransaction,
144
+ key: Value
145
+ ) -> Option<Value> {
146
+ indifferent_hash_key(key)
147
+ .map(|k| {
148
+ self.0
149
+ .borrow()
150
+ .remove(&mut *transaction.0.borrow_mut(), &*k)
151
+ })
152
+ .map(|v| v.unwrap_or(YrsValue::Any(Any::Undefined)))
153
+ .map(|v| *YValue::from(v).0.borrow())
154
+ }
155
+ pub(crate) fn ymap_size(&self) -> u32 {
156
+ self.0.borrow().len()
157
+ }
158
+ pub(crate) fn ymap_to_h(&self) -> RHash {
159
+ RHash::from_iter(
160
+ self.0.borrow().iter().map(move |(k, v)| {
161
+ (k.to_string(), *YValue::from(v).0.borrow())
162
+ })
163
+ )
164
+ }
165
+ pub(crate) fn ymap_unobserve(&self, subscription_id: u32) {
166
+ self.0.borrow_mut().unobserve(subscription_id);
167
+ }
168
+ }
@@ -0,0 +1,231 @@
1
+ use crate::yattrs::YAttrs;
2
+ use crate::yvalue::YValue;
3
+ use crate::YTransaction;
4
+ use lib0::any::Any;
5
+ use magnus::block::Proc;
6
+ use magnus::value::Qnil;
7
+ use magnus::{Error, RHash, Symbol, Value};
8
+ use std::cell::RefCell;
9
+ use yrs::types::Delta;
10
+ use yrs::Text;
11
+
12
+ #[magnus::wrap(class = "Y::Text")]
13
+ pub(crate) struct YText(pub(crate) RefCell<Text>);
14
+
15
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
16
+ unsafe impl Send for YText {}
17
+
18
+ impl YText {
19
+ pub(crate) fn ytext_format(
20
+ &self,
21
+ transaction: &YTransaction,
22
+ index: u32,
23
+ length: u32,
24
+ attrs: RHash
25
+ ) -> Result<(), Error> {
26
+ let a = YAttrs::from(attrs);
27
+ self.0.borrow_mut().format(
28
+ &mut *transaction.0.borrow_mut(),
29
+ index,
30
+ length,
31
+ a.0
32
+ );
33
+
34
+ Ok(())
35
+ }
36
+ pub(crate) fn ytext_insert(
37
+ &self,
38
+ transaction: &YTransaction,
39
+ index: u32,
40
+ chunk: String
41
+ ) -> Result<(), Error> {
42
+ self.0.borrow_mut().insert(
43
+ &mut *transaction.0.borrow_mut(),
44
+ index,
45
+ &*chunk
46
+ );
47
+
48
+ Ok(())
49
+ }
50
+ pub(crate) fn ytext_insert_embed(
51
+ &self,
52
+ transaction: &YTransaction,
53
+ index: u32,
54
+ content: Value
55
+ ) -> Result<(), Error> {
56
+ let yvalue = YValue::from(content);
57
+ let avalue = Any::from(yvalue);
58
+
59
+ self.0.borrow_mut().insert_embed(
60
+ &mut *transaction.0.borrow_mut(),
61
+ index,
62
+ avalue
63
+ );
64
+
65
+ Ok(())
66
+ }
67
+ pub(crate) fn ytext_insert_embed_with_attributes(
68
+ &self,
69
+ transaction: &YTransaction,
70
+ index: u32,
71
+ embed: Value,
72
+ attrs: RHash
73
+ ) -> Result<(), Error> {
74
+ let yvalue = YValue::from(embed);
75
+ let avalue = Any::from(yvalue);
76
+
77
+ let a = YAttrs::from(attrs);
78
+
79
+ self.0.borrow_mut().insert_embed_with_attributes(
80
+ &mut *transaction.0.borrow_mut(),
81
+ index,
82
+ avalue,
83
+ a.0
84
+ );
85
+
86
+ Ok(())
87
+ }
88
+ pub(crate) fn ytext_insert_with_attributes(
89
+ &self,
90
+ transaction: &YTransaction,
91
+ index: u32,
92
+ chunk: String,
93
+ attrs: RHash
94
+ ) -> Result<(), Error> {
95
+ let a = YAttrs::from(attrs);
96
+
97
+ self.0.borrow_mut().insert_with_attributes(
98
+ &mut *transaction.0.borrow_mut(),
99
+ index,
100
+ &*chunk,
101
+ a.0
102
+ );
103
+
104
+ Ok(())
105
+ }
106
+ pub(crate) fn ytext_length(&self) -> u32 {
107
+ self.0.borrow().len()
108
+ }
109
+ pub(crate) fn ytext_observe(&self, block: Proc) -> Result<u32, Error> {
110
+ let delta_insert = Symbol::new("insert").to_static();
111
+ let delta_retain = Symbol::new("retain").to_static();
112
+ let delta_delete = Symbol::new("delete").to_static();
113
+ let attributes = Symbol::new("attributes").to_static();
114
+
115
+ // let mut error: Option<Error> = None;
116
+
117
+ let subscription_id = self
118
+ .0
119
+ .borrow_mut()
120
+ .observe(move |transaction, text_event| {
121
+ let delta = text_event.delta(transaction);
122
+ let (_, errors): (Vec<_>, Vec<_>) = delta
123
+ .iter()
124
+ .map(|change| match change {
125
+ Delta::Inserted(value, attrs) => {
126
+ let yvalue = YValue::from(value.clone());
127
+ let payload = RHash::new();
128
+ payload
129
+ .aset(delta_insert, yvalue.0.into_inner())
130
+ .map(|()| match attrs {
131
+ Some(a) => a
132
+ .clone()
133
+ .into_iter()
134
+ .map(|(key, val)| {
135
+ let yvalue = YValue::from(val);
136
+ (
137
+ key.to_string(),
138
+ yvalue.0.into_inner()
139
+ )
140
+ })
141
+ .collect::<RHash>()
142
+ .into(),
143
+ None => None
144
+ })
145
+ .map(|attrs_hash| {
146
+ attrs_hash
147
+ .map(|v| payload.aset(attributes, v))
148
+ })
149
+ .map(|_| {
150
+ block.call::<(RHash,), Qnil>((payload,))
151
+ })
152
+ }
153
+ Delta::Retain(index, attrs) => {
154
+ let payload = RHash::new();
155
+
156
+ let yvalue = YValue::from(index.clone());
157
+
158
+ payload
159
+ .aset(delta_retain, yvalue.0.into_inner())
160
+ .map(|()| match attrs {
161
+ Some(a) => a
162
+ .clone()
163
+ .into_iter()
164
+ .map(|(key, val)| {
165
+ let yvalue = YValue::from(val);
166
+ (
167
+ key.to_string(),
168
+ yvalue.0.into_inner()
169
+ )
170
+ })
171
+ .collect::<RHash>()
172
+ .into(),
173
+ None => None
174
+ })
175
+ .map(|attrs_hash| {
176
+ attrs_hash
177
+ .map(|v| payload.aset(attributes, v))
178
+ })
179
+ .map(|_| {
180
+ block.call::<(RHash,), Qnil>((payload,))
181
+ })
182
+ }
183
+ Delta::Deleted(index) => {
184
+ let payload = RHash::new();
185
+
186
+ let yvalue = YValue::from(index.clone());
187
+
188
+ payload
189
+ .aset(delta_delete, yvalue.0.into_inner())
190
+ .map(|()| {
191
+ block.call::<(RHash,), Qnil>((payload,))
192
+ })
193
+ }
194
+ })
195
+ .partition(Result::is_ok);
196
+
197
+ if errors.len() > 0 {
198
+ // todo: make sure we respect errors and let the method fail by
199
+ // by returning a Result containing an Error
200
+ }
201
+ })
202
+ .into();
203
+
204
+ Ok(subscription_id)
205
+ }
206
+ pub(crate) fn ytext_push(&self, transaction: &YTransaction, chunk: String) {
207
+ self.0
208
+ .borrow_mut()
209
+ .push(&mut *transaction.0.borrow_mut(), &*chunk);
210
+ }
211
+ pub(crate) fn ytext_remove_range(
212
+ &self,
213
+ transaction: &YTransaction,
214
+ start: u32,
215
+ length: u32
216
+ ) -> Result<(), Error> {
217
+ self.0.borrow_mut().remove_range(
218
+ &mut *transaction.0.borrow_mut(),
219
+ start,
220
+ length
221
+ );
222
+
223
+ Ok(())
224
+ }
225
+ pub(crate) fn ytext_to_s(&self) -> String {
226
+ return self.0.borrow().to_string();
227
+ }
228
+ pub(crate) fn ytext_unobserve(&self, subscription_id: u32) {
229
+ return self.0.borrow_mut().unobserve(subscription_id);
230
+ }
231
+ }