y-rb 0.3.2-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
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(&self, transaction: &YTransaction, index: u32, value: Value) {
30
+ let yvalue = YValue::from(value);
31
+ let avalue = Any::from(yvalue);
32
+ self.0
33
+ .borrow_mut()
34
+ .insert(&mut *transaction.0.borrow_mut(), index, avalue);
35
+ }
36
+ pub(crate) fn yarray_insert_range(
37
+ &self,
38
+ transaction: &YTransaction,
39
+ index: u32,
40
+ values: RArray,
41
+ ) {
42
+ let arr: Vec<Any> = values
43
+ .each()
44
+ .into_iter()
45
+ .map(|value| YValue::from(value.unwrap()).into())
46
+ .collect();
47
+
48
+ self.0
49
+ .borrow_mut()
50
+ .insert_range(&mut *transaction.0.borrow_mut(), index, arr);
51
+ }
52
+ pub(crate) fn yarray_length(&self) -> u32 {
53
+ return self.0.borrow().len();
54
+ }
55
+ pub(crate) fn yarray_observe(&self, block: Proc) -> Result<u32, Error> {
56
+ let change_added = Symbol::new("added").to_static();
57
+ let change_retain = Symbol::new("retain").to_static();
58
+ let change_removed = Symbol::new("removed").to_static();
59
+
60
+ // let mut error: Option<Error> = None;
61
+
62
+ let subscription_id = self
63
+ .0
64
+ .borrow_mut()
65
+ .observe(move |transaction, array_event| {
66
+ let delta = array_event.delta(transaction);
67
+ // let mut changes = RArray::with_capacity(delta.len());
68
+ let (changes, errors): (Vec<_>, Vec<_>) = delta
69
+ .iter()
70
+ .map(|change| {
71
+ let payload = RHash::new();
72
+ let result = match change {
73
+ Change::Added(v) => {
74
+ let values = v
75
+ .iter()
76
+ .map(|v| <YValue as Into<Value>>::into(YValue::from(v.clone())))
77
+ .collect::<RArray>();
78
+ payload.aset(change_added, values)
79
+ }
80
+ Change::Retain(position) => {
81
+ payload.aset(change_retain, Value::from(*position))
82
+ }
83
+ Change::Removed(position) => {
84
+ payload.aset(change_removed, Value::from(*position))
85
+ }
86
+ };
87
+
88
+ match result {
89
+ Ok(()) => Ok(payload),
90
+ Err(e) => Err(e),
91
+ }
92
+ })
93
+ .partition(Result::is_ok);
94
+
95
+ if errors.is_empty() {
96
+ let args = (RArray::from_vec(
97
+ changes.into_iter().map(Result::unwrap).collect(),
98
+ ),);
99
+ let _ = block.call::<(RArray,), Qnil>(args);
100
+ // todo: make sure we respect the result and bubble up the
101
+ // error so that we can return as part of the Result
102
+ }
103
+
104
+ // todo: make sure we respect errors and let the method fail by
105
+ // by returning a Result containing an Error
106
+ })
107
+ .into();
108
+
109
+ Ok(subscription_id)
110
+ }
111
+ pub(crate) fn yarray_push_back(&self, transaction: &YTransaction, value: Value) {
112
+ let yvalue = YValue::from(value);
113
+ let avalue = Any::from(yvalue);
114
+ self.0
115
+ .borrow_mut()
116
+ .push_back(&mut *transaction.0.borrow_mut(), avalue)
117
+ }
118
+ pub(crate) fn yarray_push_front(&self, transaction: &YTransaction, value: Value) {
119
+ let yvalue = YValue::from(value);
120
+ let avalue = Any::from(yvalue);
121
+ self.0
122
+ .borrow_mut()
123
+ .push_front(&mut *transaction.0.borrow_mut(), avalue)
124
+ }
125
+ pub(crate) fn yarray_remove(&self, transaction: &YTransaction, index: u32) {
126
+ self.0
127
+ .borrow_mut()
128
+ .remove(&mut transaction.0.borrow_mut(), index)
129
+ }
130
+ pub(crate) fn yarray_remove_range(&self, transaction: &YTransaction, index: u32, len: u32) {
131
+ self.0
132
+ .borrow_mut()
133
+ .remove_range(&mut transaction.0.borrow_mut(), index, len)
134
+ }
135
+ pub(crate) fn yarray_to_a(&self) -> RArray {
136
+ let arr = self
137
+ .0
138
+ .borrow_mut()
139
+ .iter()
140
+ .map(|v| YValue::from(v).into())
141
+ .collect::<Vec<Value>>();
142
+
143
+ RArray::from_vec(arr)
144
+ }
145
+ pub(crate) fn yarray_unobserve(&self, subscription_id: u32) {
146
+ self.0.borrow_mut().unobserve(subscription_id);
147
+ }
148
+ }
@@ -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(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(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,131 @@
1
+ use crate::awareness::{Awareness, AwarenessUpdate, Event};
2
+ use magnus::block::Proc;
3
+ use magnus::{Error, Value};
4
+ use std::borrow::Borrow;
5
+ use std::cell::RefCell;
6
+ use std::collections::HashMap;
7
+ use yrs::block::ClientID;
8
+ use yrs::updates::decoder::Decode;
9
+ use yrs::updates::encoder::Encode;
10
+ use yrs::Doc;
11
+
12
+ #[magnus::wrap(class = "Y::Awareness")]
13
+ pub(crate) struct YAwareness(pub(crate) RefCell<Awareness>);
14
+
15
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
16
+ unsafe impl Send for YAwareness {}
17
+
18
+ impl YAwareness {
19
+ pub(crate) fn yawareness_new() -> Self {
20
+ let doc = Doc::new();
21
+ let awareness = Awareness::new(doc);
22
+
23
+ Self(RefCell::new(awareness))
24
+ }
25
+
26
+ pub(crate) fn yawareness_apply_update(&self, update: Vec<u8>) -> Result<(), Error> {
27
+ AwarenessUpdate::decode_v1(update.as_slice())
28
+ .map_err(|_error| Error::runtime_error("cannot decode update"))
29
+ .and_then(|value| {
30
+ self.0
31
+ .borrow_mut()
32
+ .apply_update(value)
33
+ .map_err(|_error| Error::runtime_error("cannot apply awareness update"))
34
+ })
35
+ }
36
+
37
+ pub(crate) fn yawareness_clean_local_state(&self) {
38
+ self.0.borrow_mut().clean_local_state();
39
+ }
40
+
41
+ pub(crate) fn yawareness_client_id(&self) -> ClientID {
42
+ self.0.borrow().client_id()
43
+ }
44
+
45
+ pub(crate) fn yawareness_clients(&self) -> HashMap<ClientID, String> {
46
+ self.0.borrow().clients().to_owned()
47
+ }
48
+
49
+ pub(crate) fn yawareness_local_state(&self) -> Option<String> {
50
+ self.0.borrow().local_state().map(|value| value.to_string())
51
+ }
52
+
53
+ pub(crate) fn yawareness_on_update(&self, block: Proc) -> Result<u32, Error> {
54
+ let subscription_id = self
55
+ .0
56
+ .borrow_mut()
57
+ .on_update(move |_awareness, event| {
58
+ let awareness_event = YAwarenessEvent::from(event);
59
+ let args = (awareness_event,);
60
+ block
61
+ .call::<(YAwarenessEvent,), Value>(args)
62
+ .expect("cannot call block: on_update");
63
+ })
64
+ .into();
65
+
66
+ Ok(subscription_id)
67
+ }
68
+
69
+ pub(crate) fn yawareness_remove_on_update(&self, subscription_id: u32) {
70
+ self.0.borrow_mut().remove_on_update(subscription_id)
71
+ }
72
+
73
+ pub(crate) fn yawareness_remove_state(&self, client_id: ClientID) {
74
+ self.0.borrow_mut().remove_state(client_id)
75
+ }
76
+
77
+ pub(crate) fn yawareness_set_local_state(&self, json: String) {
78
+ self.0.borrow_mut().set_local_state(json)
79
+ }
80
+
81
+ pub(crate) fn yawareness_update(&self) -> Result<Vec<u8>, Error> {
82
+ self.0
83
+ .borrow_mut()
84
+ .update()
85
+ .map(|update| update.encode_v1())
86
+ .map_err(|_error| Error::runtime_error("cannot create update for current state"))
87
+ }
88
+
89
+ pub(crate) fn yawareness_update_with_clients(
90
+ &self,
91
+ clients: Vec<ClientID>,
92
+ ) -> Result<Vec<u8>, Error> {
93
+ self.0
94
+ .borrow_mut()
95
+ .update_with_clients(clients)
96
+ .map(|update| update.encode_v1())
97
+ .map_err(|_error| {
98
+ Error::runtime_error("cannot create update for current state and given clients")
99
+ })
100
+ }
101
+ }
102
+
103
+ impl From<Awareness> for YAwareness {
104
+ fn from(value: Awareness) -> Self {
105
+ Self(RefCell::from(value))
106
+ }
107
+ }
108
+
109
+ #[magnus::wrap(class = "Y::AwarenessEvent")]
110
+ pub(crate) struct YAwarenessEvent(Event);
111
+
112
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
113
+ unsafe impl Send for YAwarenessEvent {}
114
+
115
+ impl YAwarenessEvent {
116
+ pub(crate) fn added(&self) -> Vec<ClientID> {
117
+ self.0.borrow().added().to_vec()
118
+ }
119
+ pub(crate) fn updated(&self) -> Vec<ClientID> {
120
+ self.0.borrow().updated().to_vec()
121
+ }
122
+ pub(crate) fn removed(&self) -> Vec<ClientID> {
123
+ self.0.borrow().removed().to_vec()
124
+ }
125
+ }
126
+
127
+ impl From<&Event> for YAwarenessEvent {
128
+ fn from(value: &Event) -> Self {
129
+ Self(value.clone())
130
+ }
131
+ }
@@ -0,0 +1,35 @@
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 = Integer::from_value(*value).unwrap().to_u64().unwrap();
17
+ }
18
+
19
+ options.offset_kind = OffsetKind::Utf32;
20
+
21
+ let doc = Doc::with_options(options);
22
+ Self(RefCell::new(doc))
23
+ }
24
+
25
+ pub(crate) fn ydoc_transact(&self) -> YTransaction {
26
+ let transaction = self.0.borrow().transact();
27
+
28
+ YTransaction(RefCell::new(transaction))
29
+ }
30
+ pub(crate) fn ydoc_encode_diff_v1(&self, state_vector: Vec<u8>) -> Result<Vec<u8>, Error> {
31
+ StateVector::decode_v1(&*state_vector)
32
+ .map(|sv| self.0.borrow().encode_state_as_update_v1(&sv))
33
+ .map_err(|_e| Error::runtime_error("cannot encode diff"))
34
+ }
35
+ }
@@ -0,0 +1,151 @@
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
54
+ .borrow_mut()
55
+ .insert(&mut *transaction.0.borrow_mut(), k, v);
56
+
57
+ Ok(())
58
+ }
59
+ }
60
+ }
61
+ pub(crate) fn ymap_observe(&self, block: Proc) -> u32 {
62
+ let change_inserted = Symbol::new("inserted").as_static();
63
+ let change_updated = Symbol::new("updated").as_static();
64
+ let change_removed = Symbol::new("removed").as_static();
65
+
66
+ self.0
67
+ .borrow_mut()
68
+ .observe(move |transaction, map_event| {
69
+ let delta = map_event.keys(transaction);
70
+ let changes = RArray::with_capacity(delta.len());
71
+
72
+ for (key, change) in delta {
73
+ match change {
74
+ EntryChange::Inserted(v) => {
75
+ let h = RHash::new();
76
+ h.aset(Symbol::new(key), *YValue::from(v.clone()).0.borrow())
77
+ .expect("cannot add change::inserted");
78
+
79
+ let payload = RHash::new();
80
+ payload
81
+ .aset(change_inserted, h)
82
+ .expect("cannot add change::inserted");
83
+
84
+ changes.push(payload).expect("cannot push changes::payload");
85
+ }
86
+ EntryChange::Updated(old, new) => {
87
+ let values = RArray::with_capacity(2);
88
+ values
89
+ .push(*YValue::from(old.clone()).0.borrow())
90
+ .expect("cannot push change::updated");
91
+ values
92
+ .push(*YValue::from(new.clone()).0.borrow())
93
+ .expect("cannot push change::updated");
94
+
95
+ let h = RHash::new();
96
+ h.aset(Symbol::new(key), values)
97
+ .expect("cannot push change::updated");
98
+
99
+ let payload = RHash::new();
100
+ payload
101
+ .aset(change_updated, h)
102
+ .expect("cannot push change::updated");
103
+
104
+ changes.push(payload).expect("cannot push changes::payload");
105
+ }
106
+ EntryChange::Removed(v) => {
107
+ let h = RHash::new();
108
+ h.aset(Symbol::new(key), *YValue::from(v.clone()).0.borrow())
109
+ .expect("cannot push change::removed");
110
+
111
+ let payload = RHash::new();
112
+ payload
113
+ .aset(change_removed, h)
114
+ .expect("cannot push change::removed");
115
+
116
+ changes.push(payload).expect("cannot push changes::payload");
117
+ }
118
+ }
119
+ }
120
+
121
+ block
122
+ .call::<(RArray,), Value>((changes,))
123
+ .expect("cannot call block");
124
+ })
125
+ .into()
126
+ }
127
+ pub(crate) fn ymap_remove(&self, transaction: &YTransaction, key: Value) -> Option<Value> {
128
+ indifferent_hash_key(key)
129
+ .map(|k| {
130
+ self.0
131
+ .borrow()
132
+ .remove(&mut *transaction.0.borrow_mut(), &*k)
133
+ })
134
+ .map(|v| v.unwrap_or(YrsValue::Any(Any::Undefined)))
135
+ .map(|v| *YValue::from(v).0.borrow())
136
+ }
137
+ pub(crate) fn ymap_size(&self) -> u32 {
138
+ self.0.borrow().len()
139
+ }
140
+ pub(crate) fn ymap_to_h(&self) -> RHash {
141
+ RHash::from_iter(
142
+ self.0
143
+ .borrow()
144
+ .iter()
145
+ .map(move |(k, v)| (k.to_string(), *YValue::from(v).0.borrow())),
146
+ )
147
+ }
148
+ pub(crate) fn ymap_unobserve(&self, subscription_id: u32) {
149
+ self.0.borrow_mut().unobserve(subscription_id);
150
+ }
151
+ }