twilic 3.0.0

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,506 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Twilic
4
+ module Core
5
+ module Model
6
+ class MessageKind
7
+ Entry = Data.define(:value)
8
+ SCALAR = Entry.new(0x00)
9
+ ARRAY = Entry.new(0x01)
10
+ MAP = Entry.new(0x02)
11
+ SHAPED_OBJECT = Entry.new(0x03)
12
+ SCHEMA_OBJECT = Entry.new(0x04)
13
+ TYPED_VECTOR = Entry.new(0x05)
14
+ ROW_BATCH = Entry.new(0x06)
15
+ COLUMN_BATCH = Entry.new(0x07)
16
+ CONTROL = Entry.new(0x08)
17
+ EXT = Entry.new(0x09)
18
+ STATE_PATCH = Entry.new(0x0A)
19
+ TEMPLATE_BATCH = Entry.new(0x0B)
20
+ CONTROL_STREAM = Entry.new(0x0C)
21
+ BASE_SNAPSHOT = Entry.new(0x0D)
22
+
23
+ def self.from_byte(b)
24
+ case b
25
+ when 0x00 then SCALAR
26
+ when 0x01 then ARRAY
27
+ when 0x02 then MAP
28
+ when 0x03 then SHAPED_OBJECT
29
+ when 0x04 then SCHEMA_OBJECT
30
+ when 0x05 then TYPED_VECTOR
31
+ when 0x06 then ROW_BATCH
32
+ when 0x07 then COLUMN_BATCH
33
+ when 0x08 then CONTROL
34
+ when 0x09 then EXT
35
+ when 0x0A then STATE_PATCH
36
+ when 0x0B then TEMPLATE_BATCH
37
+ when 0x0C then CONTROL_STREAM
38
+ when 0x0D then BASE_SNAPSHOT
39
+ end
40
+ end
41
+ end
42
+
43
+ class ValueKind
44
+ Entry = Data.define(:name)
45
+ NULL = Entry.new(:null)
46
+ BOOL = Entry.new(:bool)
47
+ I64 = Entry.new(:i64)
48
+ U64 = Entry.new(:u64)
49
+ F64 = Entry.new(:f64)
50
+ STRING = Entry.new(:string)
51
+ BINARY = Entry.new(:binary)
52
+ ARRAY = Entry.new(:array)
53
+ MAP = Entry.new(:map)
54
+ end
55
+
56
+ Value = Data.define(:kind, :bool, :i64, :u64, :f64, :str, :bin, :arr, :map) do
57
+ def scalar?
58
+ kind != ValueKind::ARRAY && kind != ValueKind::MAP
59
+ end
60
+
61
+ def clone_value
62
+ case kind
63
+ when ValueKind::NULL, ValueKind::BOOL, ValueKind::I64, ValueKind::U64, ValueKind::F64, ValueKind::STRING
64
+ self
65
+ when ValueKind::BINARY
66
+ with(bin: bin.b.dup)
67
+ when ValueKind::ARRAY
68
+ with(arr: arr.map(&:clone_value))
69
+ when ValueKind::MAP
70
+ with(map: map.map { |e| MapEntry.new(e.key, e.value.clone_value) })
71
+ else
72
+ new(kind: ValueKind::NULL)
73
+ end
74
+ end
75
+ end
76
+
77
+ MapEntry = Data.define(:key, :value)
78
+ MessageMapEntry = Data.define(:key, :value)
79
+
80
+ KeyRef = Data.define(:literal, :id, :is_id) do
81
+ def self.literal(s)
82
+ new(literal: s, id: 0, is_id: false)
83
+ end
84
+
85
+ def self.id_ref(id)
86
+ new(literal: "", id: id, is_id: true)
87
+ end
88
+ end
89
+
90
+ class StringMode
91
+ Entry = Data.define(:value)
92
+ EMPTY = Entry.new(0)
93
+ LITERAL = Entry.new(1)
94
+ REF = Entry.new(2)
95
+ PREFIX_DELTA = Entry.new(3)
96
+ INLINE_ENUM = Entry.new(4)
97
+
98
+ def self.from_byte(b)
99
+ return Entry.new(b) if (0..4).cover?(b)
100
+
101
+ nil
102
+ end
103
+ end
104
+
105
+ StringValue = Data.define(:mode, :value, :ref_id, :prefix_len)
106
+
107
+ class ElementType
108
+ Entry = Data.define(:value)
109
+ BOOL = Entry.new(0)
110
+ I64 = Entry.new(1)
111
+ U64 = Entry.new(2)
112
+ F64 = Entry.new(3)
113
+ STRING = Entry.new(4)
114
+ BINARY = Entry.new(5)
115
+ VALUE = Entry.new(6)
116
+
117
+ def self.from_byte(b)
118
+ return Entry.new(b) if (0..6).cover?(b)
119
+
120
+ nil
121
+ end
122
+ end
123
+
124
+ class VectorCodec
125
+ Entry = Data.define(:value)
126
+ PLAIN = Entry.new(0)
127
+ DIRECT_BITPACK = Entry.new(1)
128
+ DELTA_BITPACK = Entry.new(2)
129
+ FOR_BITPACK = Entry.new(3)
130
+ DELTA_FOR_BITPACK = Entry.new(4)
131
+ DELTA_DELTA_BITPACK = Entry.new(5)
132
+ RLE = Entry.new(6)
133
+ PATCHED_FOR = Entry.new(7)
134
+ SIMPLE8B = Entry.new(8)
135
+ XOR_FLOAT = Entry.new(9)
136
+ DICTIONARY = Entry.new(10)
137
+ STRING_REF = Entry.new(11)
138
+ PREFIX_DELTA = Entry.new(12)
139
+
140
+ def self.from_byte(b)
141
+ return Entry.new(b) if b <= 12
142
+
143
+ nil
144
+ end
145
+ end
146
+
147
+ TypedVectorData = Data.define(:bools, :i64s, :u64s, :f64s, :strings, :binary, :values, :kind)
148
+ TypedVector = Data.define(:element_type, :codec, :data)
149
+
150
+ SchemaField = Data.define(
151
+ :number, :name, :logical_type, :required, :default_value, :min, :max, :enum_values
152
+ )
153
+
154
+ Schema = Data.define(:schema_id, :name, :fields)
155
+
156
+ class NullStrategy
157
+ Entry = Data.define(:value)
158
+ NONE = Entry.new(0)
159
+ PRESENCE_BITMAP = Entry.new(1)
160
+ INVERTED_PRESENCE_BITMAP = Entry.new(2)
161
+ ALL_PRESENT_ELIDED = Entry.new(3)
162
+
163
+ def self.from_byte(b)
164
+ return Entry.new(b) if (0..3).cover?(b)
165
+
166
+ nil
167
+ end
168
+ end
169
+
170
+ Column = Data.define(
171
+ :field_id, :null_strategy, :presence, :has_presence, :codec, :dictionary_id, :values
172
+ )
173
+
174
+ class ControlOpcode
175
+ Entry = Data.define(:value)
176
+ REGISTER_KEYS = Entry.new(0)
177
+ REGISTER_SHAPE = Entry.new(1)
178
+ REGISTER_STRINGS = Entry.new(2)
179
+ PROMOTE_STRING_FIELD_TO_ENUM = Entry.new(3)
180
+ RESET_TABLES = Entry.new(4)
181
+ RESET_STATE = Entry.new(5)
182
+
183
+ def self.from_byte(b)
184
+ return Entry.new(b) if (0..5).cover?(b)
185
+
186
+ nil
187
+ end
188
+ end
189
+
190
+ ControlMessage = Data.define(
191
+ :register_keys, :register_shape, :register_strings, :promote_string_field_to_enum,
192
+ :reset_tables, :reset_state, :opcode
193
+ )
194
+
195
+ RegisterShapeControl = Data.define(:shape_id, :keys)
196
+ PromoteEnumControl = Data.define(:field_identity, :values)
197
+
198
+ class PatchOpcode
199
+ Entry = Data.define(:value)
200
+ KEEP = Entry.new(0)
201
+ REPLACE_SCALAR = Entry.new(1)
202
+ REPLACE_VECTOR = Entry.new(2)
203
+ APPEND_VECTOR = Entry.new(3)
204
+ TRUNCATE_VECTOR = Entry.new(4)
205
+ DELETE_FIELD = Entry.new(5)
206
+ INSERT_FIELD = Entry.new(6)
207
+ STRING_REF = Entry.new(7)
208
+ PREFIX_DELTA = Entry.new(8)
209
+
210
+ def self.from_byte(b)
211
+ return Entry.new(b) if b <= 8
212
+
213
+ nil
214
+ end
215
+ end
216
+
217
+ BaseRef = Data.define(:previous, :base_id) do
218
+ def self.previous
219
+ new(previous: true, base_id: 0)
220
+ end
221
+
222
+ def self.id_ref(id)
223
+ new(previous: false, base_id: id)
224
+ end
225
+ end
226
+
227
+ PatchOperation = Data.define(:field_id, :opcode, :value)
228
+
229
+ class ControlStreamCodec
230
+ Entry = Data.define(:value)
231
+ PLAIN = Entry.new(0)
232
+ RLE = Entry.new(1)
233
+ BITPACK = Entry.new(2)
234
+ HUFFMAN = Entry.new(3)
235
+ FSE = Entry.new(4)
236
+
237
+ def self.from_byte(b)
238
+ return Entry.new(b) if b <= 4
239
+
240
+ nil
241
+ end
242
+ end
243
+
244
+ Message = Data.define(
245
+ :scalar, :array, :map, :shaped_object, :schema_object, :typed_vector, :row_batch,
246
+ :column_batch, :control, :ext, :state_patch, :template_batch, :control_stream,
247
+ :base_snapshot, :kind
248
+ ) do
249
+ def clone_message
250
+ case kind
251
+ when MessageKind::SCALAR
252
+ v = scalar.clone_value
253
+ Model.message(kind: kind, scalar: v)
254
+ when MessageKind::ARRAY
255
+ Model.message(kind: kind, array: array.map(&:clone_value))
256
+ when MessageKind::MAP
257
+ Model.message(kind: kind, map: map.map { |e| MessageMapEntry.new(e.key, e.value.clone_value) })
258
+ when MessageKind::SHAPED_OBJECT
259
+ s = shaped_object
260
+ vals = s.values.map(&:clone_value)
261
+ pres = s.has_presence ? s.presence.dup : nil
262
+ Model.message(kind: kind, shaped_object: ShapedObjectMessage.new(
263
+ shape_id: s.shape_id, presence: pres, has_presence: s.has_presence, values: vals
264
+ ))
265
+ when MessageKind::SCHEMA_OBJECT
266
+ s = schema_object
267
+ fields = s.fields.map(&:clone_value)
268
+ pres = s.has_presence ? s.presence.dup : nil
269
+ sid = s.schema_id
270
+ Model.message(kind: kind, schema_object: SchemaObjectMessage.new(
271
+ schema_id: sid, presence: pres, has_presence: s.has_presence, fields: fields
272
+ ))
273
+ when MessageKind::TYPED_VECTOR
274
+ Model.message(kind: kind, typed_vector: Model.clone_typed_vector(typed_vector))
275
+ when MessageKind::ROW_BATCH
276
+ rows = row_batch.rows.map { |r| r.map(&:clone_value) }
277
+ Model.message(kind: kind, row_batch: RowBatchMessage.new(rows: rows))
278
+ when MessageKind::COLUMN_BATCH
279
+ cols = column_batch.columns.map { |c| Model.clone_column(c) }
280
+ Model.message(kind: kind, column_batch: ColumnBatchMessage.new(
281
+ count: column_batch.count, columns: cols
282
+ ))
283
+ when MessageKind::CONTROL
284
+ Model.message(kind: kind, control: Model.clone_control(control))
285
+ when MessageKind::EXT
286
+ Model.message(kind: kind, ext: ExtMessage.new(
287
+ ext_type: ext.ext_type, payload: ext.payload.b.dup
288
+ ))
289
+ when MessageKind::STATE_PATCH
290
+ sp = state_patch
291
+ ops = sp.operations.map do |op|
292
+ val = op.value ? op.value.clone_value : nil
293
+ PatchOperation.new(field_id: op.field_id, opcode: op.opcode, value: val)
294
+ end
295
+ lits = sp.literals.map(&:clone_value)
296
+ Model.message(kind: kind, state_patch: StatePatchMessage.new(
297
+ base_ref: sp.base_ref, operations: ops, literals: lits
298
+ ))
299
+ when MessageKind::TEMPLATE_BATCH
300
+ tb = template_batch
301
+ cols = tb.columns.map { |c| Model.clone_column(c) }
302
+ Model.message(kind: kind, template_batch: TemplateBatchMessage.new(
303
+ template_id: tb.template_id, count: tb.count,
304
+ changed_column_mask: tb.changed_column_mask.dup, columns: cols
305
+ ))
306
+ when MessageKind::CONTROL_STREAM
307
+ cs = control_stream
308
+ Model.message(kind: kind, control_stream: ControlStreamMessage.new(
309
+ codec: cs.codec, payload: cs.payload.b.dup
310
+ ))
311
+ when MessageKind::BASE_SNAPSHOT
312
+ bs = base_snapshot
313
+ Model.message(kind: kind, base_snapshot: BaseSnapshotMessage.new(
314
+ base_id: bs.base_id, schema_or_shape_ref: bs.schema_or_shape_ref,
315
+ payload: bs.payload.clone_message
316
+ ))
317
+ else
318
+ Model.message(kind: MessageKind::SCALAR)
319
+ end
320
+ end
321
+ end
322
+
323
+ ShapedObjectMessage = Data.define(:shape_id, :presence, :has_presence, :values)
324
+ SchemaObjectMessage = Data.define(:schema_id, :presence, :has_presence, :fields)
325
+ RowBatchMessage = Data.define(:rows)
326
+ ColumnBatchMessage = Data.define(:count, :columns)
327
+ ExtMessage = Data.define(:ext_type, :payload)
328
+ StatePatchMessage = Data.define(:base_ref, :operations, :literals)
329
+ TemplateBatchMessage = Data.define(:template_id, :count, :changed_column_mask, :columns)
330
+ ControlStreamMessage = Data.define(:codec, :payload)
331
+ BaseSnapshotMessage = Data.define(:base_id, :schema_or_shape_ref, :payload)
332
+ TemplateDescriptor = Data.define(:template_id, :field_ids, :null_strategies, :codecs)
333
+
334
+ EMPTY_MESSAGE_FIELDS = {
335
+ scalar: nil, array: nil, map: nil, shaped_object: nil, schema_object: nil,
336
+ typed_vector: nil, row_batch: nil, column_batch: nil, control: nil, ext: nil,
337
+ state_patch: nil, template_batch: nil, control_stream: nil, base_snapshot: nil
338
+ }.freeze
339
+
340
+ def self.message(kind:, **kwargs)
341
+ Message.new(**EMPTY_MESSAGE_FIELDS, kind: kind, **kwargs)
342
+ end
343
+
344
+ module_function
345
+
346
+ def null_value
347
+ Value.new(kind: ValueKind::NULL, bool: false, i64: 0, u64: 0, f64: 0.0,
348
+ str: "", bin: +"", arr: [], map: [])
349
+ end
350
+
351
+ def bool_value(b)
352
+ Value.new(kind: ValueKind::BOOL, bool: b, i64: 0, u64: 0, f64: 0.0,
353
+ str: "", bin: +"", arr: [], map: [])
354
+ end
355
+
356
+ def i64_value(n)
357
+ Value.new(kind: ValueKind::I64, bool: false, i64: n, u64: 0, f64: 0.0,
358
+ str: "", bin: +"", arr: [], map: [])
359
+ end
360
+
361
+ def u64_value(n)
362
+ Value.new(kind: ValueKind::U64, bool: false, i64: 0, u64: n, f64: 0.0,
363
+ str: "", bin: +"", arr: [], map: [])
364
+ end
365
+
366
+ def f64_value(n)
367
+ Value.new(kind: ValueKind::F64, bool: false, i64: 0, u64: 0, f64: n,
368
+ str: "", bin: +"", arr: [], map: [])
369
+ end
370
+
371
+ def string_value(s)
372
+ Value.new(kind: ValueKind::STRING, bool: false, i64: 0, u64: 0, f64: 0.0,
373
+ str: s, bin: +"", arr: [], map: [])
374
+ end
375
+
376
+ def binary_value(b)
377
+ Value.new(kind: ValueKind::BINARY, bool: false, i64: 0, u64: 0, f64: 0.0,
378
+ str: "", bin: b.b.dup, arr: [], map: [])
379
+ end
380
+
381
+ def array_value(items)
382
+ Value.new(kind: ValueKind::ARRAY, bool: false, i64: 0, u64: 0, f64: 0.0,
383
+ str: "", bin: +"", arr: items.map(&:clone_value), map: [])
384
+ end
385
+
386
+ def entry(key, value)
387
+ MapEntry.new(key, value)
388
+ end
389
+
390
+ def map_value(entries = nil, **kwargs)
391
+ if kwargs.any?
392
+ entries = kwargs.map { |k, v| MapEntry.new(k.to_s, v) }
393
+ elsif entries.is_a?(Hash)
394
+ entries = entries.map { |k, v| MapEntry.new(k.to_s, v) }
395
+ end
396
+ entries ||= []
397
+ Value.new(kind: ValueKind::MAP, bool: false, i64: 0, u64: 0, f64: 0.0,
398
+ str: "", bin: +"", arr: [],
399
+ map: entries.map { |e| MapEntry.new(e.key, e.value.clone_value) })
400
+ end
401
+
402
+ def equal(a, b)
403
+ return false unless a.kind == b.kind
404
+
405
+ case a.kind
406
+ when ValueKind::NULL then true
407
+ when ValueKind::BOOL then a.bool == b.bool
408
+ when ValueKind::I64 then a.i64 == b.i64
409
+ when ValueKind::U64 then a.u64 == b.u64
410
+ when ValueKind::F64 then a.f64 == b.f64
411
+ when ValueKind::STRING then a.str == b.str
412
+ when ValueKind::BINARY then a.bin == b.bin
413
+ when ValueKind::ARRAY
414
+ return false unless a.arr.length == b.arr.length
415
+
416
+ a.arr.each_with_index.all? { |v, i| equal(v, b.arr[i]) }
417
+ when ValueKind::MAP
418
+ return false unless a.map.length == b.map.length
419
+
420
+ a.map.each_with_index.all? do |e, i|
421
+ e.key == b.map[i].key && equal(e.value, b.map[i].value)
422
+ end
423
+ else
424
+ false
425
+ end
426
+ end
427
+
428
+ def clone_typed_vector(tv)
429
+ return nil unless tv
430
+
431
+ data = tv.data
432
+ out_data = case tv.element_type
433
+ when ElementType::BOOL
434
+ TypedVectorData.new(bools: data.bools.dup, i64s: [], u64s: [], f64s: [],
435
+ strings: [], binary: [], values: [], kind: tv.element_type)
436
+ when ElementType::I64
437
+ TypedVectorData.new(bools: [], i64s: data.i64s.dup, u64s: [], f64s: [],
438
+ strings: [], binary: [], values: [], kind: tv.element_type)
439
+ when ElementType::U64
440
+ TypedVectorData.new(bools: [], i64s: [], u64s: data.u64s.dup, f64s: [],
441
+ strings: [], binary: [], values: [], kind: tv.element_type)
442
+ when ElementType::F64
443
+ TypedVectorData.new(bools: [], i64s: [], u64s: [], f64s: data.f64s.dup,
444
+ strings: [], binary: [], values: [], kind: tv.element_type)
445
+ when ElementType::STRING
446
+ TypedVectorData.new(bools: [], i64s: [], u64s: [], f64s: [],
447
+ strings: data.strings.dup, binary: [], values: [],
448
+ kind: tv.element_type)
449
+ when ElementType::BINARY
450
+ TypedVectorData.new(bools: [], i64s: [], u64s: [], f64s: [],
451
+ strings: [], binary: data.binary.map(&:b), values: [],
452
+ kind: tv.element_type)
453
+ when ElementType::VALUE
454
+ TypedVectorData.new(bools: [], i64s: [], u64s: [], f64s: [],
455
+ strings: [], binary: [],
456
+ values: data.values.map(&:clone_value), kind: tv.element_type)
457
+ else
458
+ TypedVectorData.new(bools: [], i64s: [], u64s: [], f64s: [],
459
+ strings: [], binary: [], values: [], kind: tv.element_type)
460
+ end
461
+ TypedVector.new(element_type: tv.element_type, codec: tv.codec, data: out_data)
462
+ end
463
+
464
+ def clone_column(c)
465
+ pres = c.has_presence ? c.presence.dup : nil
466
+ dict_id = c.dictionary_id
467
+ Column.new(
468
+ field_id: c.field_id, null_strategy: c.null_strategy, presence: pres,
469
+ has_presence: c.has_presence, codec: c.codec, dictionary_id: dict_id,
470
+ values: clone_typed_vector_data(c.values)
471
+ )
472
+ end
473
+
474
+ def clone_typed_vector_data(d)
475
+ TypedVectorData.new(
476
+ bools: d.bools.dup, i64s: d.i64s.dup, u64s: d.u64s.dup, f64s: d.f64s.dup,
477
+ strings: d.strings.dup, binary: d.binary.map(&:b), values: d.values.map(&:clone_value),
478
+ kind: d.kind
479
+ )
480
+ end
481
+
482
+ def clone_control(c)
483
+ return nil unless c
484
+
485
+ rs = if c.register_shape
486
+ RegisterShapeControl.new(
487
+ shape_id: c.register_shape.shape_id,
488
+ keys: c.register_shape.keys.dup
489
+ )
490
+ end
491
+ pe = if c.promote_string_field_to_enum
492
+ PromoteEnumControl.new(
493
+ field_identity: c.promote_string_field_to_enum.field_identity,
494
+ values: c.promote_string_field_to_enum.values.dup
495
+ )
496
+ end
497
+ ControlMessage.new(
498
+ register_keys: c.register_keys.dup, register_shape: rs,
499
+ register_strings: c.register_strings.dup,
500
+ promote_string_field_to_enum: pe, reset_tables: c.reset_tables,
501
+ reset_state: c.reset_state, opcode: c.opcode
502
+ )
503
+ end
504
+ end
505
+ end
506
+ end