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

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,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
+ }