y-rb 0.6.0-x86_64-linux-gnu

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,256 @@
1
+ use crate::{YText, YXmlElement, YXmlText};
2
+ use magnus::r_hash::ForEach::Continue;
3
+ use magnus::value::{Qnil, ReprValue};
4
+ use magnus::{class, value, Float, Integer, IntoValue, RArray, RHash, RString, Symbol, Value};
5
+ use std::cell::RefCell;
6
+ use std::collections::HashMap;
7
+ use std::sync::Arc;
8
+ use yrs::types::Value as YrsValue;
9
+ use yrs::{
10
+ Any, Array, Map, TextRef as YrsText, Transact, XmlElementRef as YrsXmlElement,
11
+ XmlTextRef as YrsXmlText,
12
+ };
13
+
14
+ pub(crate) struct YValue(pub(crate) RefCell<Value>);
15
+
16
+ impl From<Value> for YValue {
17
+ fn from(value: Value) -> Self {
18
+ YValue(RefCell::from(value))
19
+ }
20
+ }
21
+
22
+ impl From<Qnil> for YValue {
23
+ fn from(value: Qnil) -> Self {
24
+ YValue(RefCell::from(value.into_value()))
25
+ }
26
+ }
27
+
28
+ impl From<bool> for YValue {
29
+ fn from(value: bool) -> Self {
30
+ YValue(RefCell::from(value.into_value()))
31
+ }
32
+ }
33
+
34
+ impl From<f64> for YValue {
35
+ fn from(value: f64) -> Self {
36
+ YValue(RefCell::from(value.into_value()))
37
+ }
38
+ }
39
+
40
+ impl From<i64> for YValue {
41
+ fn from(value: i64) -> Self {
42
+ YValue(RefCell::from(value.into_value()))
43
+ }
44
+ }
45
+
46
+ impl From<u32> for YValue {
47
+ fn from(value: u32) -> Self {
48
+ YValue(RefCell::from(value.into_value()))
49
+ }
50
+ }
51
+
52
+ impl From<String> for YValue {
53
+ fn from(value: String) -> Self {
54
+ YValue(RefCell::from(value.into_value()))
55
+ }
56
+ }
57
+
58
+ impl From<RArray> for YValue {
59
+ fn from(value: RArray) -> Self {
60
+ YValue(RefCell::from(value.into_value()))
61
+ }
62
+ }
63
+
64
+ impl From<RHash> for YValue {
65
+ fn from(value: RHash) -> Self {
66
+ YValue(RefCell::from(value.into_value()))
67
+ }
68
+ }
69
+
70
+ impl From<Vec<u8>> for YValue {
71
+ fn from(value: Vec<u8>) -> Self {
72
+ YValue(RefCell::from(value.into_value()))
73
+ }
74
+ }
75
+
76
+ impl From<YrsText> for YValue {
77
+ fn from(value: YrsText) -> Self {
78
+ YValue(RefCell::from(YText(RefCell::from(value)).into_value()))
79
+ }
80
+ }
81
+
82
+ impl From<YrsXmlElement> for YValue {
83
+ fn from(value: YrsXmlElement) -> Self {
84
+ YValue(RefCell::from(
85
+ YXmlElement(RefCell::from(value)).into_value(),
86
+ ))
87
+ }
88
+ }
89
+
90
+ impl From<YrsXmlText> for YValue {
91
+ fn from(value: YrsXmlText) -> Self {
92
+ YValue(RefCell::from(YXmlText(RefCell::from(value)).into_value()))
93
+ }
94
+ }
95
+
96
+ impl From<YText> for YValue {
97
+ fn from(value: YText) -> Self {
98
+ YValue(RefCell::from(value.into_value()))
99
+ }
100
+ }
101
+
102
+ impl From<YXmlElement> for YValue {
103
+ fn from(value: YXmlElement) -> Self {
104
+ YValue(RefCell::from(value.into_value()))
105
+ }
106
+ }
107
+
108
+ impl From<YXmlText> for YValue {
109
+ fn from(value: YXmlText) -> Self {
110
+ YValue(RefCell::from(value.into_value()))
111
+ }
112
+ }
113
+
114
+ impl From<Any> for YValue {
115
+ fn from(value: Any) -> Self {
116
+ match value {
117
+ Any::Null => YValue::from(value::qnil()),
118
+ Any::Undefined => YValue::from(value::qnil()),
119
+ Any::Bool(v) => YValue::from(v),
120
+ Any::Number(v) => YValue::from(v),
121
+ Any::BigInt(v) => YValue::from(v),
122
+ Any::String(v) => YValue::from(v.to_string()),
123
+ Any::Buffer(v) => YValue::from(v.to_vec()),
124
+ Any::Array(v) => {
125
+ let arr = RArray::new();
126
+ for item in v.iter() {
127
+ let val = YValue::from(item.clone());
128
+ let val = *val.0.borrow();
129
+ arr.push(val).expect("cannot push item event to array");
130
+ }
131
+ YValue::from(arr)
132
+ }
133
+ Any::Map(v) => {
134
+ let map = v
135
+ .iter()
136
+ .map(|(key, val)| {
137
+ let v = val.clone();
138
+ (key.to_string(), YValue::from(v).into())
139
+ })
140
+ .collect::<HashMap<String, Value>>();
141
+ YValue::from(RHash::from_iter(map))
142
+ }
143
+ }
144
+ }
145
+ }
146
+
147
+ impl From<YrsValue> for YValue {
148
+ fn from(value: YrsValue) -> Self {
149
+ match value {
150
+ YrsValue::Any(val) => YValue::from(val),
151
+ YrsValue::YText(text) => YValue::from(text),
152
+ YrsValue::YXmlElement(el) => YValue::from(el),
153
+ YrsValue::YXmlText(text) => YValue::from(text),
154
+ YrsValue::YArray(val) => {
155
+ let tx = val.transact();
156
+ let arr = RArray::new();
157
+ for item in val.iter(&tx) {
158
+ let val = YValue::from(item.clone());
159
+ let val = *val.0.borrow();
160
+ arr.push(val).expect("cannot push item event to array");
161
+ }
162
+ YValue::from(arr)
163
+ }
164
+ YrsValue::YMap(val) => {
165
+ let tx = val.transact();
166
+ let iter = val.iter(&tx).map(|(key, val)| {
167
+ let val = YValue::from(val);
168
+ let val = val.0.into_inner();
169
+ (key, val)
170
+ });
171
+ YValue::from(RHash::from_iter(iter))
172
+ }
173
+ v => panic!("cannot map complex yrs values to yvalue: {:?}", v),
174
+ }
175
+ }
176
+ }
177
+
178
+ impl From<YValue> for Any {
179
+ fn from(val: YValue) -> Self {
180
+ let value = val.0.into_inner();
181
+ if value.is_nil() {
182
+ Any::Null
183
+ } else if value.is_kind_of(class::float()) {
184
+ let f = Float::from_value(value).unwrap();
185
+ Any::Number(f.to_f64())
186
+ } else if value.is_kind_of(class::integer()) {
187
+ let i = Integer::from_value(value).unwrap();
188
+ Any::BigInt(i.to_i64().unwrap())
189
+ } else if value.is_kind_of(class::symbol()) {
190
+ let s = Symbol::from_value(value).unwrap();
191
+ Any::String(Arc::from(s.name().unwrap()))
192
+ } else if value.is_kind_of(class::true_class()) {
193
+ Any::Bool(true)
194
+ } else if value.is_kind_of(class::false_class()) {
195
+ Any::Bool(false)
196
+ } else if value.is_kind_of(class::string()) {
197
+ let s = RString::from_value(value).unwrap();
198
+ unsafe { Any::String(Arc::from(s.as_str().unwrap().to_string())) }
199
+ } else if value.is_kind_of(class::array()) {
200
+ let arr = RArray::from_value(value).unwrap();
201
+ let items = arr
202
+ .each()
203
+ .map(|item| {
204
+ let yvalue = YValue::from(item.unwrap());
205
+ Any::from(yvalue)
206
+ })
207
+ .collect::<Vec<Any>>();
208
+ Any::Array(Arc::from(items))
209
+ } else if value.is_kind_of(class::hash()) {
210
+ let map = RHash::from_value(value).unwrap();
211
+ let mut m: HashMap<String, Any> = HashMap::new();
212
+
213
+ // we need to map symbol keys to strings, because we can't store
214
+ // symbols in any of the yrs data structures
215
+ map.foreach(|key: Value, val: Value| {
216
+ let k = if let Some(converted_key) = Symbol::from_value(key) {
217
+ converted_key.to_string()
218
+ } else {
219
+ let converted_key = RString::from_value(key).unwrap();
220
+ let result = converted_key.to_string();
221
+ result.unwrap()
222
+ };
223
+ m.insert(k, Any::from(YValue::from(val)));
224
+ Ok(Continue)
225
+ })
226
+ .expect("cannot map key/value pair");
227
+
228
+ Any::Map(Arc::from(m))
229
+ } else {
230
+ Any::Undefined
231
+ }
232
+ }
233
+ }
234
+
235
+ #[allow(clippy::from_over_into)]
236
+ impl Into<Value> for YValue {
237
+ fn into(self) -> Value {
238
+ self.0.into_inner()
239
+ }
240
+ }
241
+
242
+ #[cfg(test)]
243
+ mod tests {
244
+ use crate::yvalue::YValue;
245
+ use magnus::value::ReprValue;
246
+ use yrs::Any;
247
+
248
+ #[test]
249
+ fn convert_any_to_yvalue() {
250
+ let _cleanup = unsafe { magnus::embed::init() };
251
+ let value = Any::Null;
252
+ let yvalue: YValue = value.into();
253
+
254
+ assert!(yvalue.0.into_inner().is_nil());
255
+ }
256
+ }
@@ -0,0 +1,280 @@
1
+ use crate::yvalue::YValue;
2
+ use crate::yxml_fragment::YXmlFragment;
3
+ use crate::yxml_text::YXmlText;
4
+ use crate::YTransaction;
5
+ use magnus::block::Proc;
6
+ use magnus::{Error, IntoValue, RArray, RHash, Symbol, Value};
7
+ use std::cell::RefCell;
8
+ use yrs::types::Change;
9
+ use yrs::{
10
+ GetString, Observable, Xml, XmlElementPrelim, XmlElementRef, XmlFragment, XmlNode,
11
+ XmlTextPrelim,
12
+ };
13
+
14
+ #[magnus::wrap(class = "Y::XMLElement")]
15
+ pub(crate) struct YXmlElement(pub(crate) RefCell<XmlElementRef>);
16
+
17
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
18
+ unsafe impl Send for YXmlElement {}
19
+
20
+ impl YXmlElement {
21
+ pub(crate) fn yxml_element_attributes(&self, transaction: &YTransaction) -> RHash {
22
+ let tx = transaction.transaction();
23
+ let tx = tx.as_ref().unwrap();
24
+
25
+ RHash::from_iter(self.0.borrow().attributes(tx))
26
+ }
27
+ pub(crate) fn yxml_element_first_child(&self, transaction: &YTransaction) -> Option<Value> {
28
+ self.yxml_element_get(transaction, 0)
29
+ }
30
+ pub(crate) fn yxml_element_get(&self, transaction: &YTransaction, index: u32) -> Option<Value> {
31
+ let tx = transaction.transaction();
32
+ let tx = tx.as_ref().unwrap();
33
+
34
+ self.0.borrow().get(tx, index).map(|node| match node {
35
+ XmlNode::Element(element) => YXmlElement::from(element).into_value(),
36
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
37
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
38
+ })
39
+ }
40
+ pub(crate) fn yxml_element_get_attribute(
41
+ &self,
42
+ transaction: &YTransaction,
43
+ name: String,
44
+ ) -> Option<String> {
45
+ let tx = transaction.transaction();
46
+ let tx = tx.as_ref().unwrap();
47
+
48
+ self.0.borrow().get_attribute(tx, name.as_str())
49
+ }
50
+ pub(crate) fn yxml_element_insert_attribute(
51
+ &self,
52
+ transaction: &YTransaction,
53
+ name: String,
54
+ value: String,
55
+ ) {
56
+ let mut tx = transaction.transaction();
57
+ let tx = tx.as_mut().unwrap();
58
+
59
+ self.0.borrow_mut().insert_attribute(tx, name, value)
60
+ }
61
+ pub(crate) fn yxml_element_insert_element(
62
+ &self,
63
+ transaction: &YTransaction,
64
+ index: u32,
65
+ tag: String,
66
+ ) -> YXmlElement {
67
+ let mut tx = transaction.transaction();
68
+ let tx = tx.as_mut().unwrap();
69
+
70
+ let node = XmlElementPrelim::empty(tag);
71
+ YXmlElement::from(self.0.borrow_mut().insert(tx, index, node))
72
+ }
73
+ pub(crate) fn yxml_element_insert_text(
74
+ &self,
75
+ transaction: &YTransaction,
76
+ index: u32,
77
+ content: String,
78
+ ) -> YXmlText {
79
+ let text = XmlTextPrelim::new(content.as_str());
80
+ let mut tx = transaction.transaction();
81
+ let tx = tx.as_mut().unwrap();
82
+
83
+ YXmlText::from(self.0.borrow_mut().insert(tx, index, text))
84
+ }
85
+ pub(crate) fn yxml_element_len(&self, transaction: &YTransaction) -> u32 {
86
+ let mut tx = transaction.transaction();
87
+ let tx = tx.as_mut().unwrap();
88
+
89
+ self.0.borrow().len(tx)
90
+ }
91
+ pub(crate) fn yxml_element_next_sibling(&self, transaction: &YTransaction) -> Option<Value> {
92
+ let tx = transaction.transaction();
93
+ let tx = tx.as_ref().unwrap();
94
+
95
+ self.0.borrow().siblings(tx).next().map(|item| match item {
96
+ XmlNode::Element(el) => YXmlElement::from(el).into_value(),
97
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
98
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
99
+ })
100
+ }
101
+ pub(crate) fn yxml_element_observe(&self, block: Proc) -> Result<u32, Error> {
102
+ let change_added = Symbol::new("added").to_static();
103
+ let change_retain = Symbol::new("retain").to_static();
104
+ let change_removed = Symbol::new("removed").to_static();
105
+
106
+ let subscription_id = self
107
+ .0
108
+ .borrow_mut()
109
+ .observe(move |transaction, xml_element_event| {
110
+ let delta = xml_element_event.delta(transaction);
111
+ let changes = RArray::with_capacity(delta.len());
112
+
113
+ for change in delta {
114
+ match change {
115
+ Change::Added(v) => {
116
+ let values = RArray::new();
117
+ for value in v.iter() {
118
+ let value = YValue::from(value.clone());
119
+ let value = *value.0.borrow();
120
+ values.push(value).expect("cannot push value to array");
121
+ }
122
+
123
+ let payload = RHash::new();
124
+ payload
125
+ .aset(change_added, values)
126
+ .expect("cannot create change::added payload");
127
+
128
+ changes
129
+ .push(payload)
130
+ .expect("cannot push payload to list of changes");
131
+ }
132
+ Change::Retain(position) => {
133
+ let payload = RHash::new();
134
+ payload
135
+ .aset(change_retain, *position)
136
+ .expect("cannot create change::retain payload");
137
+
138
+ changes
139
+ .push(payload)
140
+ .expect("cannot push payload to list of changes");
141
+ }
142
+ Change::Removed(position) => {
143
+ let payload = RHash::new();
144
+ payload
145
+ .aset(change_removed, *position)
146
+ .expect("cannot create change::removed payload");
147
+
148
+ changes
149
+ .push(payload)
150
+ .expect("cannot push payload to list of changes");
151
+ }
152
+ }
153
+ }
154
+
155
+ block
156
+ .call::<(RArray,), Value>((changes,))
157
+ .expect("cannot call block");
158
+ });
159
+
160
+ Ok(subscription_id.into())
161
+ }
162
+ pub(crate) fn yxml_element_parent(&self) -> Option<Value> {
163
+ self.0.borrow().parent().map(|item| match item {
164
+ XmlNode::Element(el) => YXmlElement::from(el).into_value(),
165
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
166
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
167
+ })
168
+ }
169
+ pub(crate) fn yxml_element_prev_sibling(&self, transaction: &YTransaction) -> Option<Value> {
170
+ let tx = transaction.transaction();
171
+ let tx = tx.as_ref().unwrap();
172
+
173
+ self.0
174
+ .borrow()
175
+ .siblings(tx)
176
+ .next_back()
177
+ .map(|item| match item {
178
+ XmlNode::Element(el) => YXmlElement::from(el).into_value(),
179
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
180
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
181
+ })
182
+ }
183
+ pub(crate) fn yxml_element_push_element_back(
184
+ &self,
185
+ transaction: &YTransaction,
186
+ tag: String,
187
+ ) -> YXmlElement {
188
+ let mut tx = transaction.transaction();
189
+ let tx = tx.as_mut().unwrap();
190
+
191
+ let node = XmlElementPrelim::empty(tag);
192
+ YXmlElement::from(self.0.borrow_mut().push_back(tx, node))
193
+ }
194
+ pub(crate) fn yxml_element_push_element_front(
195
+ &self,
196
+ transaction: &YTransaction,
197
+ tag: String,
198
+ ) -> YXmlElement {
199
+ let mut tx = transaction.transaction();
200
+ let tx = tx.as_mut().unwrap();
201
+
202
+ let node = XmlElementPrelim::empty(tag);
203
+ YXmlElement::from(self.0.borrow_mut().push_front(tx, node))
204
+ }
205
+ pub(crate) fn yxml_element_push_text_back(
206
+ &self,
207
+ transaction: &YTransaction,
208
+ content: String,
209
+ ) -> YXmlText {
210
+ let mut tx = transaction.transaction();
211
+ let tx = tx.as_mut().unwrap();
212
+
213
+ let text = XmlTextPrelim::new(content.as_str());
214
+ YXmlText::from(self.0.borrow_mut().push_back(tx, text))
215
+ }
216
+ pub(crate) fn yxml_element_push_text_front(
217
+ &self,
218
+ transaction: &YTransaction,
219
+ content: String,
220
+ ) -> YXmlText {
221
+ let mut tx = transaction.transaction();
222
+ let tx = tx.as_mut().unwrap();
223
+
224
+ let text = XmlTextPrelim::new(content.as_str());
225
+ YXmlText::from(self.0.borrow_mut().push_front(tx, text))
226
+ }
227
+ pub(crate) fn yxml_element_remove_attribute(&self, transaction: &YTransaction, name: String) {
228
+ let mut tx = transaction.transaction();
229
+ let tx = tx.as_mut().unwrap();
230
+
231
+ self.0.borrow_mut().remove_attribute(tx, &name)
232
+ }
233
+ pub(crate) fn yxml_element_remove_range(
234
+ &self,
235
+ transaction: &YTransaction,
236
+ index: u32,
237
+ length: u32,
238
+ ) {
239
+ let mut tx = transaction.transaction();
240
+ let tx = tx.as_mut().unwrap();
241
+
242
+ self.0.borrow_mut().remove_range(tx, index, length)
243
+ }
244
+ pub(crate) fn yxml_element_siblings(&self, transaction: &YTransaction) -> RArray {
245
+ let tx = transaction.transaction();
246
+ let tx = tx.as_ref().unwrap();
247
+
248
+ let siblings = self.0.borrow().siblings(tx).map(|item| match item {
249
+ XmlNode::Element(el) => YXmlElement::from(el).into_value(),
250
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
251
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
252
+ });
253
+
254
+ RArray::from_iter(siblings)
255
+ }
256
+ pub(crate) fn yxml_element_size(&self, transaction: &YTransaction) -> u32 {
257
+ let tx = transaction.transaction();
258
+ let tx = tx.as_ref().unwrap();
259
+
260
+ self.0.borrow().len(tx)
261
+ }
262
+ pub(crate) fn yxml_element_tag(&self) -> String {
263
+ self.0.borrow().tag().to_string()
264
+ }
265
+ pub(crate) fn yxml_element_to_s(&self, transaction: &YTransaction) -> String {
266
+ let tx = transaction.transaction();
267
+ let tx = tx.as_ref().unwrap();
268
+
269
+ self.0.borrow().get_string(tx)
270
+ }
271
+ pub(crate) fn yxml_element_unobserve(&self, subscription_id: u32) {
272
+ self.0.borrow_mut().unobserve(subscription_id);
273
+ }
274
+ }
275
+
276
+ impl From<XmlElementRef> for YXmlElement {
277
+ fn from(v: XmlElementRef) -> Self {
278
+ YXmlElement(RefCell::from(v))
279
+ }
280
+ }
@@ -0,0 +1,129 @@
1
+ use crate::ytransaction::YTransaction;
2
+ use crate::yxml_element::YXmlElement;
3
+ use crate::yxml_text::YXmlText;
4
+ use magnus::{IntoValue, RArray, Value};
5
+ use std::cell::RefCell;
6
+ use yrs::{GetString, XmlElementPrelim, XmlFragment, XmlFragmentRef, XmlNode};
7
+
8
+ #[magnus::wrap(class = "Y::XMLFragment")]
9
+ pub(crate) struct YXmlFragment(pub(crate) RefCell<XmlFragmentRef>);
10
+
11
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
12
+ unsafe impl Send for YXmlFragment {}
13
+
14
+ impl YXmlFragment {
15
+ pub(crate) fn yxml_fragment_first_child(&self) -> Option<Value> {
16
+ self.0.borrow().first_child().map(|node| match node {
17
+ XmlNode::Element(element) => YXmlElement::from(element).into_value(),
18
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
19
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
20
+ })
21
+ }
22
+
23
+ pub(crate) fn yxml_fragment_get(
24
+ &self,
25
+ transaction: &YTransaction,
26
+ index: u32,
27
+ ) -> Option<Value> {
28
+ let tx = transaction.transaction();
29
+ let tx = tx.as_ref().unwrap();
30
+
31
+ self.0.borrow().get(tx, index).map(|node| match node {
32
+ XmlNode::Element(element) => YXmlElement::from(element).into_value(),
33
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
34
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
35
+ })
36
+ }
37
+
38
+ pub(crate) fn yxml_fragment_insert(
39
+ &self,
40
+ transaction: &YTransaction,
41
+ index: u32,
42
+ tag: String,
43
+ ) -> YXmlElement {
44
+ let mut tx = transaction.transaction();
45
+ let tx = tx.as_mut().unwrap();
46
+
47
+ let node = XmlElementPrelim::empty(tag);
48
+ YXmlElement::from(self.0.borrow_mut().insert(tx, index, node))
49
+ }
50
+
51
+ pub(crate) fn yxml_fragment_len(&self, transaction: &YTransaction) -> u32 {
52
+ let tx = transaction.transaction();
53
+ let tx = tx.as_ref().unwrap();
54
+
55
+ self.0.borrow().len(tx)
56
+ }
57
+
58
+ pub(crate) fn yxml_fragment_parent(&self) -> Option<Value> {
59
+ self.0.borrow().parent().map(|item| match item {
60
+ XmlNode::Element(el) => YXmlElement::from(el).into_value(),
61
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
62
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
63
+ })
64
+ }
65
+
66
+ pub(crate) fn yxml_fragment_push_back(
67
+ &self,
68
+ transaction: &YTransaction,
69
+ tag: String,
70
+ ) -> YXmlElement {
71
+ let mut tx = transaction.transaction();
72
+ let tx = tx.as_mut().unwrap();
73
+
74
+ let node = XmlElementPrelim::empty(tag);
75
+ YXmlElement::from(self.0.borrow_mut().push_back(tx, node))
76
+ }
77
+
78
+ pub(crate) fn yxml_fragment_push_front(
79
+ &self,
80
+ transaction: &YTransaction,
81
+ tag: String,
82
+ ) -> YXmlElement {
83
+ let mut tx = transaction.transaction();
84
+ let tx = tx.as_mut().unwrap();
85
+
86
+ let node = XmlElementPrelim::empty(tag);
87
+ YXmlElement::from(self.0.borrow_mut().push_front(tx, node))
88
+ }
89
+
90
+ pub(crate) fn yxml_fragment_remove_range(
91
+ &self,
92
+ transaction: &YTransaction,
93
+ index: u32,
94
+ length: u32,
95
+ ) {
96
+ let mut tx = transaction.transaction();
97
+ let tx = tx.as_mut().unwrap();
98
+
99
+ self.0.borrow_mut().remove_range(tx, index, length);
100
+ }
101
+
102
+ pub(crate) fn yxml_fragment_successors(&self, transaction: &YTransaction) -> RArray {
103
+ let tx = transaction.transaction();
104
+ let tx = tx.as_ref().unwrap();
105
+
106
+ let fragment = self.0.borrow();
107
+
108
+ let result = fragment.successors(tx).map(|item| match item {
109
+ XmlNode::Element(el) => YXmlElement::from(el).into_value(),
110
+ XmlNode::Fragment(fragment) => YXmlFragment::from(fragment).into_value(),
111
+ XmlNode::Text(text) => YXmlText::from(text).into_value(),
112
+ });
113
+
114
+ RArray::from_iter(result)
115
+ }
116
+
117
+ pub(crate) fn yxml_fragment_to_s(&self, transaction: &YTransaction) -> String {
118
+ let tx = transaction.transaction();
119
+ let tx = tx.as_ref().unwrap();
120
+
121
+ self.0.borrow().get_string(tx)
122
+ }
123
+ }
124
+
125
+ impl From<XmlFragmentRef> for YXmlFragment {
126
+ fn from(v: XmlFragmentRef) -> Self {
127
+ YXmlFragment(RefCell::from(v))
128
+ }
129
+ }