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.
- checksums.yaml +7 -0
- data/ext/yrb/Cargo.toml +19 -0
- data/ext/yrb/extconf.rb +10 -0
- data/ext/yrb/src/lib.rs +476 -0
- data/ext/yrb/src/utils.rs +36 -0
- data/ext/yrb/src/yany.rs +44 -0
- data/ext/yrb/src/yarray.rs +178 -0
- data/ext/yrb/src/yattrs.rs +48 -0
- data/ext/yrb/src/ydoc.rs +39 -0
- data/ext/yrb/src/ymap.rs +168 -0
- data/ext/yrb/src/ytext.rs +231 -0
- data/ext/yrb/src/ytransaction.rs +61 -0
- data/ext/yrb/src/yvalue.rs +237 -0
- data/ext/yrb/src/yxml_element.rs +228 -0
- data/ext/yrb/src/yxml_text.rs +157 -0
- data/lib/2.7/yrb.so +0 -0
- data/lib/3.0/yrb.so +0 -0
- data/lib/3.1/yrb.so +0 -0
- data/lib/y/array.rb +352 -0
- data/lib/y/doc.rb +220 -0
- data/lib/y/map.rb +200 -0
- data/lib/y/text.rb +372 -0
- data/lib/y/transaction.rb +143 -0
- data/lib/y/version.rb +5 -0
- data/lib/y/xml.rb +846 -0
- data/lib/y.rb +20 -0
- metadata +133 -0
@@ -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
|
+
}
|
data/ext/yrb/src/ydoc.rs
ADDED
@@ -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
|
+
}
|
data/ext/yrb/src/ymap.rs
ADDED
@@ -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
|
+
}
|