y-rb 0.6.0-x86_64-linux-gnu

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,177 @@
1
+ use crate::utils::map_rhash_to_attrs;
2
+ use crate::yvalue::YValue;
3
+ use crate::yxml_fragment::YXmlFragment;
4
+ use crate::{YTransaction, YXmlElement};
5
+ use magnus::{Error, IntoValue, RHash, Value};
6
+ use std::cell::RefCell;
7
+ use yrs::{Any, GetString, Text, Xml, XmlNode, XmlTextRef};
8
+
9
+ #[magnus::wrap(class = "Y::XMLText")]
10
+ pub(crate) struct YXmlText(pub(crate) RefCell<XmlTextRef>);
11
+
12
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
13
+ unsafe impl Send for YXmlText {}
14
+
15
+ impl YXmlText {
16
+ pub(crate) fn yxml_text_attributes(&self, transaction: &YTransaction) -> RHash {
17
+ let tx = transaction.transaction();
18
+ let tx = tx.as_ref().unwrap();
19
+
20
+ RHash::from_iter(self.0.borrow().attributes(tx))
21
+ }
22
+ pub(crate) fn yxml_text_format(
23
+ &self,
24
+ transaction: &YTransaction,
25
+ index: u32,
26
+ length: u32,
27
+ attrs: RHash,
28
+ ) -> Result<(), Error> {
29
+ let mut tx = transaction.transaction();
30
+ let tx = tx.as_mut().unwrap();
31
+
32
+ map_rhash_to_attrs(attrs).map(|a| self.0.borrow_mut().format(tx, index, length, a))
33
+ }
34
+ pub(crate) fn yxml_text_get_attribute(
35
+ &self,
36
+ transaction: &YTransaction,
37
+ name: String,
38
+ ) -> Option<String> {
39
+ let tx = transaction.transaction();
40
+ let tx = tx.as_ref().unwrap();
41
+
42
+ self.0.borrow().get_attribute(tx, name.as_str())
43
+ }
44
+ pub(crate) fn yxml_text_insert(&self, transaction: &YTransaction, index: u32, content: String) {
45
+ let mut tx = transaction.transaction();
46
+ let tx = tx.as_mut().unwrap();
47
+
48
+ self.0.borrow_mut().insert(tx, index, content.as_str())
49
+ }
50
+ pub(crate) fn yxml_text_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_text_insert_embed_with_attributes(
62
+ &self,
63
+ transaction: &YTransaction,
64
+ index: u32,
65
+ content: Value,
66
+ attrs: RHash,
67
+ ) -> Result<(), Error> {
68
+ let mut tx = transaction.transaction();
69
+ let tx = tx.as_mut().unwrap();
70
+
71
+ let yvalue = YValue::from(content);
72
+ let avalue = Any::from(yvalue);
73
+
74
+ map_rhash_to_attrs(attrs)
75
+ .map(|a| {
76
+ self.0
77
+ .borrow_mut()
78
+ .insert_embed_with_attributes(tx, index, avalue, a)
79
+ })
80
+ .map(|_| ())
81
+ }
82
+ pub(crate) fn yxml_text_insert_embed(
83
+ &self,
84
+ transaction: &YTransaction,
85
+ index: u32,
86
+ embed: Value,
87
+ ) {
88
+ let mut tx = transaction.transaction();
89
+ let tx = tx.as_mut().unwrap();
90
+
91
+ self.0
92
+ .borrow_mut()
93
+ .insert_embed(tx, index, Any::from(YValue::from(embed)));
94
+ }
95
+ pub(crate) fn yxml_text_insert_with_attributes(
96
+ &self,
97
+ transaction: &YTransaction,
98
+ index: u32,
99
+ content: String,
100
+ attrs: RHash,
101
+ ) -> Result<(), Error> {
102
+ let mut tx = transaction.transaction();
103
+ let tx = tx.as_mut().unwrap();
104
+
105
+ map_rhash_to_attrs(attrs).map(|a| {
106
+ self.0
107
+ .borrow_mut()
108
+ .insert_with_attributes(tx, index, content.as_str(), a);
109
+ })
110
+ }
111
+ pub(crate) fn yxml_text_length(&self, transaction: &YTransaction) -> u32 {
112
+ let tx = transaction.transaction();
113
+ let tx = tx.as_ref().unwrap();
114
+
115
+ self.0.borrow().len(tx)
116
+ }
117
+ pub(crate) fn yxml_text_next_sibling(&self, transaction: &YTransaction) -> Option<Value> {
118
+ let tx = transaction.transaction();
119
+ let tx = tx.as_ref().unwrap();
120
+
121
+ self.0.borrow().siblings(tx).next().map(|item| match item {
122
+ XmlNode::Element(el) => YXmlElement(RefCell::from(el)).into_value(),
123
+ XmlNode::Fragment(fragment) => YXmlFragment(RefCell::from(fragment)).into_value(),
124
+ XmlNode::Text(text) => YXmlText(RefCell::from(text)).into_value(),
125
+ })
126
+ }
127
+ pub(crate) fn yxml_text_parent(&self) -> Option<Value> {
128
+ self.0.borrow().parent().map(|item| match item {
129
+ XmlNode::Element(el) => YXmlElement(RefCell::from(el)).into_value(),
130
+ XmlNode::Fragment(fragment) => YXmlFragment(RefCell::from(fragment)).into_value(),
131
+ XmlNode::Text(text) => YXmlText(RefCell::from(text)).into_value(),
132
+ })
133
+ }
134
+ pub(crate) fn yxml_text_prev_sibling(&self, transaction: &YTransaction) -> Option<Value> {
135
+ let tx = transaction.transaction();
136
+ let tx = tx.as_ref().unwrap();
137
+
138
+ self.0
139
+ .borrow()
140
+ .siblings(tx)
141
+ .next_back()
142
+ .map(|item| match item {
143
+ XmlNode::Element(el) => YXmlElement(RefCell::from(el)).into_value(),
144
+ XmlNode::Fragment(fragment) => YXmlFragment(RefCell::from(fragment)).into_value(),
145
+ XmlNode::Text(text) => YXmlText(RefCell::from(text)).into_value(),
146
+ })
147
+ }
148
+ pub(crate) fn yxml_text_push(&self, transaction: &YTransaction, content: String) {
149
+ let mut tx = transaction.transaction();
150
+ let tx = tx.as_mut().unwrap();
151
+
152
+ self.0.borrow_mut().push(tx, content.as_str())
153
+ }
154
+ pub(crate) fn yxml_text_remove_range(
155
+ &self,
156
+ transaction: &YTransaction,
157
+ index: u32,
158
+ length: u32,
159
+ ) {
160
+ let mut tx = transaction.transaction();
161
+ let tx = tx.as_mut().unwrap();
162
+
163
+ self.0.borrow_mut().remove_range(tx, index, length)
164
+ }
165
+ pub(crate) fn yxml_text_to_s(&self, transaction: &YTransaction) -> String {
166
+ let tx = transaction.transaction();
167
+ let tx = tx.as_ref().unwrap();
168
+
169
+ self.0.borrow().get_string(tx)
170
+ }
171
+ }
172
+
173
+ impl From<XmlTextRef> for YXmlText {
174
+ fn from(v: XmlTextRef) -> Self {
175
+ YXmlText(RefCell::from(v))
176
+ }
177
+ }
data/lib/3.1/yrb.so ADDED
Binary file
data/lib/3.2/yrb.so ADDED
Binary file
data/lib/3.3/yrb.so ADDED
Binary file
data/lib/3.4/yrb.so ADDED
Binary file
data/lib/y/array.rb ADDED
@@ -0,0 +1,371 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Y
4
+ # An array can be used to store and retrieve elements.
5
+ #
6
+ # The array is the replicated counterpart to a Ruby Array. It supports a
7
+ # subset of the Ruby Array operations, like adding, getting and deleting
8
+ # values by position or ranges.
9
+ #
10
+ # Someone should not instantiate an array directly, but use {Y::Doc#get_array}
11
+ # instead.
12
+ #
13
+ # @example
14
+ # doc = Y::Doc.new
15
+ # array = doc.get_array("my array")
16
+ #
17
+ # array << 1
18
+ # array.push(2)
19
+ # array.concat([3, 4, 5])
20
+ #
21
+ # array.to_a == [1, 2, 3, 4, 5] # true
22
+ class Array # rubocop:disable Metrics/ClassLength
23
+ include Enumerable
24
+
25
+ # @!attribute [r] document
26
+ #
27
+ # @return [Y::Doc] The document this array belongs to
28
+ attr_accessor :document
29
+
30
+ # Create a new array instance
31
+ #
32
+ # @param doc [Y::Doc]
33
+ def initialize(doc = nil)
34
+ @document = doc || Y::Doc.new
35
+
36
+ super()
37
+ end
38
+
39
+ # Retrieves element at position
40
+ #
41
+ # @return [true, false, Float, Integer, String, Array, Hash]
42
+ def [](index)
43
+ document.current_transaction { |tx| yarray_get(tx, index) }
44
+ end
45
+
46
+ # Inserts value at position
47
+ #
48
+ # @param index [Integer]
49
+ # @param value [true, false, Float, Integer, String, Array, Hash]
50
+ # @return [void]
51
+ def []=(index, value)
52
+ document.current_transaction { |tx| yarray_insert(tx, index, value) }
53
+ end
54
+
55
+ # Adds an element to the end of the array
56
+ #
57
+ # @param value [true, false, Float, Integer, String, ::Array, Hash]
58
+ # @return [void]
59
+ def <<(value, *values)
60
+ document.current_transaction do |tx|
61
+ yarray_push_back(tx, value)
62
+ values.each { |v| yarray_push_back(tx, v) }
63
+ end
64
+ end
65
+
66
+ # Attach listener to array changes
67
+ #
68
+ # @example Listen to changes in array type
69
+ # local = Y::Doc.new
70
+ #
71
+ # arr = local.get_array("my array")
72
+ # arr.attach { |delta| pp delta }
73
+ #
74
+ # local.transact do
75
+ # arr << 1
76
+ # end
77
+ #
78
+ # @param block [Block]
79
+ # @return [Integer]
80
+ def attach(&block)
81
+ raise "provide block" unless block
82
+
83
+ yarray_observe(block.to_proc)
84
+ end
85
+
86
+ # Adds to array all elements from each Array in `other_arrays`.
87
+ #
88
+ # If one of the arguments isn't an Array, it is silently ignored.
89
+ #
90
+ # @example Add multiple values to array
91
+ # doc = Y::Doc.new
92
+ # arr = doc.get_array("my array")
93
+ # arr.concat([1, 2, 3])
94
+ #
95
+ # arr.to_a == [1, 2, 3] # true
96
+ #
97
+ # @param other_arrays [Array<Array<Object>>]
98
+ # @return [void]
99
+ def concat(*other_arrays)
100
+ document.current_transaction do |tx|
101
+ combined = other_arrays.reduce([]) do |values, arr|
102
+ values.concat(arr) if arr.is_a?(::Array)
103
+ end
104
+
105
+ yarray_insert_range(tx, yarray_length(tx), combined)
106
+ end
107
+ end
108
+
109
+ # Detach listener
110
+ #
111
+ # @param subscription_id [Integer]
112
+ # @return [void]
113
+ def detach(subscription_id)
114
+ yarray_unobserve(subscription_id)
115
+ end
116
+
117
+ # @return [void]
118
+ def each(...)
119
+ document.current_transaction { |tx| yarray_each(tx, ...) }
120
+ end
121
+
122
+ # Check if the array is empty
123
+ #
124
+ # @return [true, false]
125
+ def empty?
126
+ size.zero?
127
+ end
128
+
129
+ # Returns first element in array if there is at least one
130
+ #
131
+ # @return [true, false, Float, Integer, String, ::Array, Hash, nil]
132
+ def first
133
+ document.current_transaction { |tx| yarray_get(tx, 0) }
134
+ end
135
+
136
+ # Returns last element in array if there is at least one element
137
+ #
138
+ # @return [true, false, Float, Integer, String, ::Array, Hash, nil]
139
+ def last
140
+ document.current_transaction do |tx|
141
+ len = yarray_length(tx)
142
+ return yarray_get(tx, len - 1) if len.positive?
143
+
144
+ nil
145
+ end
146
+ end
147
+
148
+ # rubocop:disable Naming/MethodParameterName
149
+
150
+ # Removes last (n) element(s) from array
151
+ #
152
+ # @param n [Integer, nil] Number of elements to remove
153
+ # @return [void]
154
+ def pop(n = nil)
155
+ document.current_transaction do |tx|
156
+ len = yarray_length(tx)
157
+ yarray_remove(tx, len - 1) if n.nil?
158
+ yarray_remove_range(tx, len - n, n) unless n.nil?
159
+ end
160
+ end
161
+
162
+ # rubocop:enable Naming/MethodParameterName
163
+
164
+ alias push <<
165
+
166
+ # rubocop:disable Naming/MethodParameterName
167
+
168
+ # Removes first (n) element(s) from array
169
+ #
170
+ # @param n [Integer, nil] Number of elements to remove
171
+ # @return [void]
172
+ def shift(n = nil)
173
+ document.current_transaction do |tx|
174
+ yarray_remove(tx, 0) if n.nil?
175
+
176
+ yarray_remove_range(tx, 0, n) unless nil?
177
+ end
178
+ end
179
+
180
+ # rubocop:enable Naming/MethodParameterName
181
+
182
+ # Size of array
183
+ #
184
+ # @return [Integer]
185
+ def size
186
+ document.current_transaction { |tx| yarray_length(tx) }
187
+ end
188
+
189
+ alias length size
190
+
191
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
192
+
193
+ # Removes one or more elements from array
194
+ #
195
+ # **Attention:** In comparison to Array#slice, {Array#slice!} will not
196
+ # return the values that got removed. Even this being technically
197
+ # possible, it requires us to read the elements before removing them, which
198
+ # is not desirable in most situations.
199
+ #
200
+ # @example Removes a single element
201
+ # doc = Y::Doc.new
202
+ #
203
+ # arr = doc.get_text("my array")
204
+ # arr << 1
205
+ # arr << 2
206
+ # arr << 3
207
+ #
208
+ # arr.slice!(1)
209
+ #
210
+ # arr.to_a == [1, 3] # true
211
+ #
212
+ # @overload slice!(n)
213
+ # Removes nth element from array
214
+ #
215
+ # @overload slice!(start, length)
216
+ # Removes a range of elements
217
+ #
218
+ # @overload slice!(range)
219
+ # Removes a range of elements
220
+ #
221
+ # @return [void]
222
+ def slice!(*args)
223
+ document.current_transaction do |tx| # rubocop:disable Metrics/BlockLength
224
+ if args.empty?
225
+ raise ArgumentError,
226
+ "Provide one of `index`, `range`, `start, length` as arguments"
227
+ end
228
+
229
+ if args.size == 1
230
+ arg = args.first
231
+
232
+ if arg.is_a?(Range)
233
+ if arg.exclude_end?
234
+ yarray_remove_range(tx, arg.first,
235
+ arg.last - arg.first)
236
+ end
237
+ unless arg.exclude_end?
238
+ yarray_remove_range(tx, arg.first,
239
+ arg.last + 1 - arg.first)
240
+ end
241
+ return nil
242
+ end
243
+
244
+ if arg.is_a?(Numeric)
245
+ yarray_remove(tx, arg.to_int)
246
+ return nil
247
+ end
248
+ end
249
+
250
+ if args.size == 2
251
+ first, second = args
252
+
253
+ if first.is_a?(Numeric) && second.is_a?(Numeric)
254
+ yarray_remove_range(tx, first, second)
255
+ return nil
256
+ end
257
+ end
258
+
259
+ raise ArgumentError, "Please check your arguments, can't slice."
260
+ end
261
+ end
262
+
263
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
264
+
265
+ # Convert this array to a Ruby Array
266
+ #
267
+ # @return [Array<true, false, Float, Integer, String, ::Array, Hash>]
268
+ def to_a
269
+ document.current_transaction { |tx| yarray_to_a(tx) }
270
+ end
271
+
272
+ # Adds an element to the beginning of the array
273
+ #
274
+ # @return [void]
275
+ def unshift(value)
276
+ document.current_transaction { |tx| yarray_push_front(tx, value) }
277
+ end
278
+
279
+ alias prepend unshift
280
+
281
+ # @!method yarray_each(proc)
282
+ # Iterates over all elements in Array by calling the provided proc
283
+ # with the value as argument.
284
+ #
285
+ # @param proc [Proc<Object>] A proc that is called for every element
286
+ # @!visibility private
287
+
288
+ # @!method yarray_get(transaction, index)
289
+ # Retrieves content as specified index
290
+ #
291
+ # @param index [Integer]
292
+ # @return [Object]
293
+ # @!visibility private
294
+
295
+ # @!method yarray_insert(transaction, index, content)
296
+ # Inserts content at specified index
297
+ #
298
+ # @param transaction [Y::Transaction]
299
+ # @param index [Integer]
300
+ # @param content [Boolean, Float, Integer, Array, Hash, Text]
301
+ # @return [void]
302
+ # @!visibility private
303
+
304
+ # @!method yarray_insert_range(transaction, index, arr)
305
+ # Inserts all elements of a given array at specified index
306
+ #
307
+ # @param transaction [Y::Transaction]
308
+ # @param index [Integer]
309
+ # @param arr [Array<Boolean, Float, Integer, Array, Hash, Text>]
310
+ # @return [void]
311
+ # @!visibility private
312
+
313
+ # @!method yarray_length(transaction)
314
+ # Returns length of array
315
+ #
316
+ # @param transaction [Y::Transaction]
317
+ # @return [Integer] Length of array
318
+ # @!visibility private
319
+
320
+ # @!method yarray_push_back(transaction, value)
321
+ # Adds an element to the end of the array
322
+ #
323
+ # @param transaction [Y::Transaction]
324
+ # @param value [Object]
325
+ # @return [void]
326
+ # @!visibility private
327
+
328
+ # @!method yarray_push_front(transaction, value)
329
+ # Adds an element to the front of the array
330
+ #
331
+ # @param transaction [Y::Transaction]
332
+ # @param value [Object]
333
+ # @return [void]
334
+ # @!visibility private
335
+
336
+ # @!method yarray_observe(proc)
337
+ #
338
+ # @param proc [Proc]
339
+ # @return [Integer]
340
+ # @!visibility private
341
+
342
+ # @!method yarray_remove(transaction, index)
343
+ # Removes a single element from array at index
344
+ #
345
+ # @param transaction [Y::Transaction]
346
+ # @param index [Integer]
347
+ # @return [void]
348
+ # @!visibility private
349
+
350
+ # @!method yarray_remove_range(transaction, index, length)
351
+ # Removes a range of elements from array
352
+ #
353
+ # @param transaction [Y::Transaction]
354
+ # @param index [Integer]
355
+ # @param length [Integer]
356
+ # @return [void]
357
+ # @!visibility private
358
+
359
+ # @!method yarray_to_a(transaction)
360
+ # Transforms the array into a Ruby array
361
+ # @param transaction [Y::Transaction]
362
+ # @return [Array]
363
+ # @!visibility private
364
+
365
+ # @!method yarray_unobserve(subscription_id)
366
+ #
367
+ # @param subscription_id [Integer]
368
+ # @return [void]
369
+ # @!visibility private
370
+ end
371
+ end