y-rb 0.1.4.alpha.1-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,175 @@
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
+ impl YArray {
15
+ pub(crate) fn yarray_each(&self, block: Proc) -> () {
16
+ self.0.borrow_mut().iter().for_each(|val| {
17
+ let yvalue = YValue::from(val);
18
+ let args = (yvalue.into(),);
19
+ let _ = block.call::<(Value,), Qnil>(args);
20
+ });
21
+ }
22
+ pub(crate) fn yarray_get(&self, index: u32) -> Value {
23
+ let v = self.0.borrow().get(index).unwrap();
24
+ YValue::from(v).into()
25
+ }
26
+ pub(crate) fn yarray_insert(
27
+ &self,
28
+ transaction: &YTransaction,
29
+ index: u32,
30
+ value: Value
31
+ ) -> () {
32
+ let yvalue = YValue::from(value);
33
+ let avalue = Any::from(yvalue);
34
+ self.0.borrow_mut().insert(
35
+ &mut *transaction.0.borrow_mut(),
36
+ index,
37
+ avalue
38
+ );
39
+ }
40
+ pub(crate) fn yarray_insert_range(
41
+ &self,
42
+ transaction: &YTransaction,
43
+ index: u32,
44
+ values: RArray
45
+ ) -> () {
46
+ let arr: Vec<Any> = values
47
+ .each()
48
+ .into_iter()
49
+ .map(|value| YValue::from(value.unwrap()).into())
50
+ .collect();
51
+
52
+ self.0.borrow_mut().insert_range(
53
+ &mut *transaction.0.borrow_mut(),
54
+ index,
55
+ arr
56
+ );
57
+ }
58
+ pub(crate) fn yarray_length(&self) -> u32 {
59
+ return self.0.borrow().len();
60
+ }
61
+ pub(crate) fn yarray_observe(&self, block: Proc) -> Result<u32, Error> {
62
+ let change_added = Symbol::new("added").to_static();
63
+ let change_retain = Symbol::new("retain").to_static();
64
+ let change_removed = Symbol::new("removed").to_static();
65
+
66
+ // let mut error: Option<Error> = None;
67
+
68
+ let subscription_id = self
69
+ .0
70
+ .borrow_mut()
71
+ .observe(move |transaction, array_event| {
72
+ let delta = array_event.delta(transaction);
73
+ // let mut changes = RArray::with_capacity(delta.len());
74
+ let (changes, errors): (Vec<_>, Vec<_>) = delta
75
+ .iter()
76
+ .map(|change| {
77
+ let payload = RHash::new();
78
+ let result = match change {
79
+ Change::Added(v) => {
80
+ let values = v
81
+ .iter()
82
+ .map(|v| {
83
+ <YValue as Into<Value>>::into(
84
+ YValue::from(v.clone())
85
+ )
86
+ })
87
+ .collect::<RArray>();
88
+ payload.aset(change_added, values)
89
+ }
90
+ Change::Retain(position) => payload
91
+ .aset(change_retain, Value::from(*position)),
92
+ Change::Removed(position) => payload
93
+ .aset(change_removed, Value::from(*position))
94
+ };
95
+
96
+ match result {
97
+ Ok(()) => Ok(payload),
98
+ Err(e) => Err(e)
99
+ }
100
+ })
101
+ .partition(Result::is_ok);
102
+
103
+ if errors.len() == 0 {
104
+ let args = (RArray::from_vec(
105
+ changes.into_iter().map(Result::unwrap).collect()
106
+ ),);
107
+ let _ = block.call::<(RArray,), Qnil>(args);
108
+ // todo: make sure we respect the result and bubble up the
109
+ // error so that we can return as part of the Result
110
+ }
111
+
112
+ // todo: make sure we respect errors and let the method fail by
113
+ // by returning a Result containing an Error
114
+ })
115
+ .into();
116
+
117
+ Ok(subscription_id)
118
+ }
119
+ pub(crate) fn yarray_push_back(
120
+ &self,
121
+ transaction: &YTransaction,
122
+ value: Value
123
+ ) -> () {
124
+ let yvalue = YValue::from(value);
125
+ let avalue = Any::from(yvalue);
126
+ self.0
127
+ .borrow_mut()
128
+ .push_back(&mut *transaction.0.borrow_mut(), avalue)
129
+ }
130
+ pub(crate) fn yarray_push_front(
131
+ &self,
132
+ transaction: &YTransaction,
133
+ value: Value
134
+ ) -> () {
135
+ let yvalue = YValue::from(value);
136
+ let avalue = Any::from(yvalue);
137
+ self.0
138
+ .borrow_mut()
139
+ .push_front(&mut *transaction.0.borrow_mut(), avalue)
140
+ }
141
+ pub(crate) fn yarray_remove(
142
+ &self,
143
+ transaction: &YTransaction,
144
+ index: u32
145
+ ) -> () {
146
+ self.0
147
+ .borrow_mut()
148
+ .remove(&mut transaction.0.borrow_mut(), index)
149
+ }
150
+ pub(crate) fn yarray_remove_range(
151
+ &self,
152
+ transaction: &YTransaction,
153
+ index: u32,
154
+ len: u32
155
+ ) -> () {
156
+ self.0.borrow_mut().remove_range(
157
+ &mut transaction.0.borrow_mut(),
158
+ index,
159
+ len
160
+ )
161
+ }
162
+ pub(crate) fn yarray_to_a(&self) -> RArray {
163
+ let arr = self
164
+ .0
165
+ .borrow_mut()
166
+ .iter()
167
+ .map(|v| YValue::from(v).into())
168
+ .collect::<Vec<Value>>();
169
+
170
+ return RArray::from_vec(arr);
171
+ }
172
+ pub(crate) fn yarray_unobserve(&self, subscription_id: u32) -> () {
173
+ self.0.borrow_mut().unobserve(subscription_id);
174
+ }
175
+ }
@@ -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,165 @@
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
+ impl YMap {
15
+ pub(crate) fn ymap_clear(&self, transaction: &YTransaction) {
16
+ self.0.borrow_mut().clear(&mut *transaction.0.borrow_mut());
17
+ }
18
+ pub(crate) fn ymap_contains(&self, key: Value) -> bool {
19
+ match indifferent_hash_key(key) {
20
+ None => false,
21
+ Some(k) => self.0.borrow().contains(&*k)
22
+ }
23
+ }
24
+ pub(crate) fn ymap_each(&self, proc: Proc) {
25
+ self.0.borrow().iter().for_each(|(key, val)| {
26
+ let k = key.to_string();
27
+ let v = *YValue::from(val).0.borrow();
28
+ proc.call::<(String, Value), Value>((k, v))
29
+ .expect("cannot iterate map");
30
+ });
31
+ }
32
+ pub(crate) fn ymap_get(&self, key: Value) -> Option<Value> {
33
+ indifferent_hash_key(key)
34
+ .map(|k| self.0.borrow().get(&*k))
35
+ .map(|v| v.unwrap_or(YrsValue::Any(Any::Undefined)))
36
+ .map(|v| *YValue::from(v).0.borrow())
37
+ }
38
+ pub(crate) fn ymap_insert(
39
+ &self,
40
+ transaction: &YTransaction,
41
+ key: Value,
42
+ value: Value
43
+ ) -> Result<(), Error> {
44
+ match indifferent_hash_key(key) {
45
+ None => Err(Error::runtime_error(
46
+ "invalid key type, make sure it is either a Symbol or a String"
47
+ )),
48
+ Some(k) => {
49
+ let v = Any::from(YValue::from(value));
50
+ self.0.borrow_mut().insert(
51
+ &mut *transaction.0.borrow_mut(),
52
+ k,
53
+ v
54
+ );
55
+
56
+ Ok(())
57
+ }
58
+ }
59
+ }
60
+ pub(crate) fn ymap_observe(&self, block: Proc) -> u32 {
61
+ let change_inserted = Symbol::new("inserted").as_static();
62
+ let change_updated = Symbol::new("updated").as_static();
63
+ let change_removed = Symbol::new("removed").as_static();
64
+
65
+ self.0
66
+ .borrow_mut()
67
+ .observe(move |transaction, map_event| {
68
+ let delta = map_event.keys(transaction);
69
+ let changes = RArray::with_capacity(delta.len());
70
+
71
+ for (key, change) in delta {
72
+ match change {
73
+ EntryChange::Inserted(v) => {
74
+ let h = RHash::new();
75
+ h.aset(
76
+ Symbol::new(&key.to_string()),
77
+ *YValue::from(v.clone()).0.borrow()
78
+ )
79
+ .expect("cannot add change::inserted");
80
+
81
+ let payload = RHash::new();
82
+ payload
83
+ .aset(change_inserted, h)
84
+ .expect("cannot add change::inserted");
85
+
86
+ changes
87
+ .push(payload)
88
+ .expect("cannot push changes::payload");
89
+ }
90
+ EntryChange::Updated(old, new) => {
91
+ let values = RArray::with_capacity(2);
92
+ values
93
+ .push(*YValue::from(old.clone()).0.borrow())
94
+ .expect("cannot push change::updated");
95
+ values
96
+ .push(*YValue::from(new.clone()).0.borrow())
97
+ .expect("cannot push change::updated");
98
+
99
+ let h = RHash::new();
100
+ h.aset(Symbol::new(&key.to_string()), values)
101
+ .expect("cannot push change::updated");
102
+
103
+ let payload = RHash::new();
104
+ payload
105
+ .aset(change_updated, h)
106
+ .expect("cannot push change::updated");
107
+
108
+ changes
109
+ .push(payload)
110
+ .expect("cannot push changes::payload");
111
+ }
112
+ EntryChange::Removed(v) => {
113
+ let h = RHash::new();
114
+ h.aset(
115
+ Symbol::new(&key.to_string()),
116
+ *YValue::from(v.clone()).0.borrow()
117
+ )
118
+ .expect("cannot push change::removed");
119
+
120
+ let payload = RHash::new();
121
+ payload
122
+ .aset(change_removed, h)
123
+ .expect("cannot push change::removed");
124
+
125
+ changes
126
+ .push(payload)
127
+ .expect("cannot push changes::payload");
128
+ }
129
+ }
130
+ }
131
+
132
+ block
133
+ .call::<(RArray,), Value>((changes,))
134
+ .expect("cannot call block");
135
+ })
136
+ .into()
137
+ }
138
+ pub(crate) fn ymap_remove(
139
+ &self,
140
+ transaction: &YTransaction,
141
+ key: Value
142
+ ) -> Option<Value> {
143
+ indifferent_hash_key(key)
144
+ .map(|k| {
145
+ self.0
146
+ .borrow()
147
+ .remove(&mut *transaction.0.borrow_mut(), &*k)
148
+ })
149
+ .map(|v| v.unwrap_or(YrsValue::Any(Any::Undefined)))
150
+ .map(|v| *YValue::from(v).0.borrow())
151
+ }
152
+ pub(crate) fn ymap_size(&self) -> u32 {
153
+ self.0.borrow().len()
154
+ }
155
+ pub(crate) fn ymap_to_h(&self) -> RHash {
156
+ RHash::from_iter(
157
+ self.0.borrow().iter().map(move |(k, v)| {
158
+ (k.to_string(), *YValue::from(v).0.borrow())
159
+ })
160
+ )
161
+ }
162
+ pub(crate) fn ymap_unobserve(&self, subscription_id: u32) {
163
+ self.0.borrow_mut().unobserve(subscription_id);
164
+ }
165
+ }
@@ -0,0 +1,228 @@
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
+ impl YText {
16
+ pub(crate) fn ytext_format(
17
+ &self,
18
+ transaction: &YTransaction,
19
+ index: u32,
20
+ length: u32,
21
+ attrs: RHash
22
+ ) -> Result<(), Error> {
23
+ let a = YAttrs::from(attrs);
24
+ self.0.borrow_mut().format(
25
+ &mut *transaction.0.borrow_mut(),
26
+ index,
27
+ length,
28
+ a.0
29
+ );
30
+
31
+ Ok(())
32
+ }
33
+ pub(crate) fn ytext_insert(
34
+ &self,
35
+ transaction: &YTransaction,
36
+ index: u32,
37
+ chunk: String
38
+ ) -> Result<(), Error> {
39
+ self.0.borrow_mut().insert(
40
+ &mut *transaction.0.borrow_mut(),
41
+ index,
42
+ &*chunk
43
+ );
44
+
45
+ Ok(())
46
+ }
47
+ pub(crate) fn ytext_insert_embed(
48
+ &self,
49
+ transaction: &YTransaction,
50
+ index: u32,
51
+ content: Value
52
+ ) -> Result<(), Error> {
53
+ let yvalue = YValue::from(content);
54
+ let avalue = Any::from(yvalue);
55
+
56
+ self.0.borrow_mut().insert_embed(
57
+ &mut *transaction.0.borrow_mut(),
58
+ index,
59
+ avalue
60
+ );
61
+
62
+ Ok(())
63
+ }
64
+ pub(crate) fn ytext_insert_embed_with_attributes(
65
+ &self,
66
+ transaction: &YTransaction,
67
+ index: u32,
68
+ embed: Value,
69
+ attrs: RHash
70
+ ) -> Result<(), Error> {
71
+ let yvalue = YValue::from(embed);
72
+ let avalue = Any::from(yvalue);
73
+
74
+ let a = YAttrs::from(attrs);
75
+
76
+ self.0.borrow_mut().insert_embed_with_attributes(
77
+ &mut *transaction.0.borrow_mut(),
78
+ index,
79
+ avalue,
80
+ a.0
81
+ );
82
+
83
+ Ok(())
84
+ }
85
+ pub(crate) fn ytext_insert_with_attributes(
86
+ &self,
87
+ transaction: &YTransaction,
88
+ index: u32,
89
+ chunk: String,
90
+ attrs: RHash
91
+ ) -> Result<(), Error> {
92
+ let a = YAttrs::from(attrs);
93
+
94
+ self.0.borrow_mut().insert_with_attributes(
95
+ &mut *transaction.0.borrow_mut(),
96
+ index,
97
+ &*chunk,
98
+ a.0
99
+ );
100
+
101
+ Ok(())
102
+ }
103
+ pub(crate) fn ytext_length(&self) -> u32 {
104
+ self.0.borrow().len()
105
+ }
106
+ pub(crate) fn ytext_observe(&self, block: Proc) -> Result<u32, Error> {
107
+ let delta_insert = Symbol::new("insert").to_static();
108
+ let delta_retain = Symbol::new("retain").to_static();
109
+ let delta_delete = Symbol::new("delete").to_static();
110
+ let attributes = Symbol::new("attributes").to_static();
111
+
112
+ // let mut error: Option<Error> = None;
113
+
114
+ let subscription_id = self
115
+ .0
116
+ .borrow_mut()
117
+ .observe(move |transaction, text_event| {
118
+ let delta = text_event.delta(transaction);
119
+ let (_, errors): (Vec<_>, Vec<_>) = delta
120
+ .iter()
121
+ .map(|change| match change {
122
+ Delta::Inserted(value, attrs) => {
123
+ let yvalue = YValue::from(value.clone());
124
+ let payload = RHash::new();
125
+ payload
126
+ .aset(delta_insert, yvalue.0.into_inner())
127
+ .map(|()| match attrs {
128
+ Some(a) => a
129
+ .clone()
130
+ .into_iter()
131
+ .map(|(key, val)| {
132
+ let yvalue = YValue::from(val);
133
+ (
134
+ key.to_string(),
135
+ yvalue.0.into_inner()
136
+ )
137
+ })
138
+ .collect::<RHash>()
139
+ .into(),
140
+ None => None
141
+ })
142
+ .map(|attrs_hash| {
143
+ attrs_hash
144
+ .map(|v| payload.aset(attributes, v))
145
+ })
146
+ .map(|_| {
147
+ block.call::<(RHash,), Qnil>((payload,))
148
+ })
149
+ }
150
+ Delta::Retain(index, attrs) => {
151
+ let payload = RHash::new();
152
+
153
+ let yvalue = YValue::from(index.clone());
154
+
155
+ payload
156
+ .aset(delta_retain, yvalue.0.into_inner())
157
+ .map(|()| match attrs {
158
+ Some(a) => a
159
+ .clone()
160
+ .into_iter()
161
+ .map(|(key, val)| {
162
+ let yvalue = YValue::from(val);
163
+ (
164
+ key.to_string(),
165
+ yvalue.0.into_inner()
166
+ )
167
+ })
168
+ .collect::<RHash>()
169
+ .into(),
170
+ None => None
171
+ })
172
+ .map(|attrs_hash| {
173
+ attrs_hash
174
+ .map(|v| payload.aset(attributes, v))
175
+ })
176
+ .map(|_| {
177
+ block.call::<(RHash,), Qnil>((payload,))
178
+ })
179
+ }
180
+ Delta::Deleted(index) => {
181
+ let payload = RHash::new();
182
+
183
+ let yvalue = YValue::from(index.clone());
184
+
185
+ payload
186
+ .aset(delta_delete, yvalue.0.into_inner())
187
+ .map(|()| {
188
+ block.call::<(RHash,), Qnil>((payload,))
189
+ })
190
+ }
191
+ })
192
+ .partition(Result::is_ok);
193
+
194
+ if errors.len() > 0 {
195
+ // todo: make sure we respect errors and let the method fail by
196
+ // by returning a Result containing an Error
197
+ }
198
+ })
199
+ .into();
200
+
201
+ Ok(subscription_id)
202
+ }
203
+ pub(crate) fn ytext_push(&self, transaction: &YTransaction, chunk: String) {
204
+ self.0
205
+ .borrow_mut()
206
+ .push(&mut *transaction.0.borrow_mut(), &*chunk);
207
+ }
208
+ pub(crate) fn ytext_remove_range(
209
+ &self,
210
+ transaction: &YTransaction,
211
+ start: u32,
212
+ length: u32
213
+ ) -> Result<(), Error> {
214
+ self.0.borrow_mut().remove_range(
215
+ &mut *transaction.0.borrow_mut(),
216
+ start,
217
+ length
218
+ );
219
+
220
+ Ok(())
221
+ }
222
+ pub(crate) fn ytext_to_s(&self) -> String {
223
+ return self.0.borrow().to_string();
224
+ }
225
+ pub(crate) fn ytext_unobserve(&self, subscription_id: u32) {
226
+ return self.0.borrow_mut().unobserve(subscription_id);
227
+ }
228
+ }