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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }