avrocadabra 0.0.1

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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +6 -0
  3. data/Cargo.lock +923 -0
  4. data/Cargo.toml +8 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +131 -0
  7. data/docs/avro_turf.md +61 -0
  8. data/docs/licenses/crates/quad-rand-0.2.3/DECLARED-LICENSE.txt +32 -0
  9. data/docs/licenses/gcc-16.2.0/COPYING +340 -0
  10. data/docs/licenses/gcc-16.2.0/COPYING.RUNTIME +73 -0
  11. data/docs/licenses/mingw-w64-14.0.0/AUTHORS +73 -0
  12. data/docs/licenses/mingw-w64-14.0.0/COPYING +43 -0
  13. data/docs/licenses/rust-1.99.0/COMPILER-BUILTINS.txt +275 -0
  14. data/docs/licenses/rust-1.99.0/COPYRIGHT-library.html +29357 -0
  15. data/docs/licenses/rust-1.99.0/LIBM.txt +258 -0
  16. data/docs/licenses/rust-1.99.0/LLVM-LIBUNWIND.txt +311 -0
  17. data/docs/licenses/rust-1.99.0/RUST-LICENSE-APACHE.txt +176 -0
  18. data/docs/licenses/rust-1.99.0/RUST-LICENSE-MIT.txt +25 -0
  19. data/docs/licenses/rust-1.99.0/STDLIB-BACKTRACE-MIT.txt +25 -0
  20. data/docs/licenses/rust-1.99.0/STDLIB-PORTABLE-SIMD-MIT.txt +19 -0
  21. data/docs/licenses/rust-1.99.0/STDLIB-STDARCH-MIT.txt +25 -0
  22. data/docs/licenses/rust-1.99.0/licenses/Apache-2.0.txt +73 -0
  23. data/docs/licenses/rust-1.99.0/licenses/BSD-2-Clause.txt +9 -0
  24. data/docs/licenses/rust-1.99.0/licenses/CC-BY-SA-4.0.txt +427 -0
  25. data/docs/licenses/rust-1.99.0/licenses/GCC-exception-3.1.txt +30 -0
  26. data/docs/licenses/rust-1.99.0/licenses/GPL-2.0-only.txt +133 -0
  27. data/docs/licenses/rust-1.99.0/licenses/GPL-3.0-or-later.txt +202 -0
  28. data/docs/licenses/rust-1.99.0/licenses/ISC.txt +7 -0
  29. data/docs/licenses/rust-1.99.0/licenses/LLVM-exception.txt +15 -0
  30. data/docs/licenses/rust-1.99.0/licenses/MIT.txt +9 -0
  31. data/docs/licenses/rust-1.99.0/licenses/NCSA.txt +28 -0
  32. data/docs/licenses/rust-1.99.0/licenses/OFL-1.1.txt +43 -0
  33. data/docs/licenses/rust-1.99.0/licenses/Unicode-3.0.txt +39 -0
  34. data/docs/releasing.md +71 -0
  35. data/docs/third_party.md +5922 -0
  36. data/ext/avrocadabra/Cargo.toml +29 -0
  37. data/ext/avrocadabra/build.rs +4 -0
  38. data/ext/avrocadabra/extconf.rb +9 -0
  39. data/ext/avrocadabra/src/big_decimal.rs +107 -0
  40. data/ext/avrocadabra/src/callback.rs +106 -0
  41. data/ext/avrocadabra/src/convert.rs +617 -0
  42. data/ext/avrocadabra/src/decode_value.rs +473 -0
  43. data/ext/avrocadabra/src/guard.rs +680 -0
  44. data/ext/avrocadabra/src/lib.rs +670 -0
  45. data/ext/avrocadabra/src/mapping.rs +63 -0
  46. data/ext/avrocadabra/src/memory.rs +194 -0
  47. data/ext/avrocadabra/src/prepare.rs +819 -0
  48. data/ext/avrocadabra/src/resolution.rs +1932 -0
  49. data/ext/avrocadabra/src/schema_state.rs +60 -0
  50. data/ext/avrocadabra/src/validation.rs +174 -0
  51. data/ext/avrocadabra/src/wire.rs +269 -0
  52. data/lib/avrocadabra/avro_turf/cache.rb +28 -0
  53. data/lib/avrocadabra/avro_turf/codec.rb +69 -0
  54. data/lib/avrocadabra/avro_turf/datum_reader.rb +17 -0
  55. data/lib/avrocadabra/avro_turf/datum_writer.rb +14 -0
  56. data/lib/avrocadabra/avro_turf/mapping.rb +48 -0
  57. data/lib/avrocadabra/avro_turf/messaging.rb +12 -0
  58. data/lib/avrocadabra/avro_turf/ractor_support.rb +154 -0
  59. data/lib/avrocadabra/avro_turf/routing.rb +15 -0
  60. data/lib/avrocadabra/avro_turf/schema_state.rb +70 -0
  61. data/lib/avrocadabra/avro_turf/validation.rb +33 -0
  62. data/lib/avrocadabra/avro_turf.rb +25 -0
  63. data/lib/avrocadabra/logical.rb +71 -0
  64. data/lib/avrocadabra/schema.rb +48 -0
  65. data/lib/avrocadabra/version.rb +5 -0
  66. data/lib/avrocadabra.rb +34 -0
  67. metadata +183 -0
@@ -0,0 +1,63 @@
1
+ use magnus::{Error, Exception, RArray, RString, Value, prelude::*};
2
+
3
+ #[derive(Clone, Copy)]
4
+ pub struct Mapping {
5
+ context: Value,
6
+ node: RArray,
7
+ }
8
+
9
+ impl Mapping {
10
+ pub fn new(graph: RArray) -> Result<Self, Error> {
11
+ Ok(Self {
12
+ context: graph.entry(0)?,
13
+ node: graph.entry(1)?,
14
+ })
15
+ }
16
+
17
+ pub fn child(self, index: usize) -> Result<Self, Error> {
18
+ let children: RArray = self.node.entry(2)?;
19
+ Ok(Self {
20
+ context: self.context,
21
+ node: children.entry(index as isize)?,
22
+ })
23
+ }
24
+
25
+ pub fn convert(self, method: &str, value: Value) -> Result<Value, Error> {
26
+ let adapter: Value = self.node.entry(1)?;
27
+ if adapter.is_nil() {
28
+ Ok(value)
29
+ } else {
30
+ adapter.funcall(method, (value,))
31
+ }
32
+ }
33
+
34
+ pub fn identity(self) -> Result<bool, Error> {
35
+ Ok(self.node.entry::<Value>(1)?.is_nil())
36
+ }
37
+
38
+ pub fn union_index(self, value: Value, budget: RArray) -> Result<usize, Error> {
39
+ let schema: Value = self.node.entry(0)?;
40
+ self.context.funcall("union_index", (schema, value, budget))
41
+ }
42
+
43
+ pub fn enum_index(self, value: Value) -> Result<Option<usize>, Error> {
44
+ let schema: Value = self.node.entry(0)?;
45
+ let symbols: RArray = schema.funcall_public("symbols", ())?;
46
+ symbols.funcall_public("index", (value,))
47
+ }
48
+
49
+ pub fn default_value(self, name: RString) -> Result<Value, Error> {
50
+ let schema: Value = self.node.entry(0)?;
51
+ self.context.funcall("default_value", (schema, name))
52
+ }
53
+
54
+ pub fn encoding_error(self, value: Value) -> Result<Error, Error> {
55
+ let schema: Value = self.node.entry(0)?;
56
+ let exception: Exception = self.context.funcall("encoding_error", (schema, value))?;
57
+ Ok(exception.into())
58
+ }
59
+ }
60
+
61
+ pub fn child(mapping: Option<Mapping>, index: usize) -> Result<Option<Mapping>, Error> {
62
+ mapping.map(|mapping| mapping.child(index)).transpose()
63
+ }
@@ -0,0 +1,194 @@
1
+ use apache_avro::{
2
+ Schema,
3
+ schema::{Alias, FixedSchema, InnerDecimalSchema, Name, RecordField, UuidSchema},
4
+ types::Value,
5
+ };
6
+ use serde_json::Value as Json;
7
+ use std::collections::{BTreeMap, HashMap};
8
+
9
+ pub trait HeapSize {
10
+ fn heap_size(&self) -> usize;
11
+ }
12
+
13
+ impl HeapSize for String {
14
+ fn heap_size(&self) -> usize {
15
+ self.capacity()
16
+ }
17
+ }
18
+
19
+ impl<T: HeapSize> HeapSize for Vec<T> {
20
+ fn heap_size(&self) -> usize {
21
+ self.capacity() * size_of::<T>() + self.iter().map(HeapSize::heap_size).sum::<usize>()
22
+ }
23
+ }
24
+
25
+ impl<T: HeapSize> HeapSize for Option<T> {
26
+ fn heap_size(&self) -> usize {
27
+ self.as_ref().map_or(0, HeapSize::heap_size)
28
+ }
29
+ }
30
+
31
+ impl<T: HeapSize> HeapSize for Box<T> {
32
+ fn heap_size(&self) -> usize {
33
+ size_of::<T>() + (**self).heap_size()
34
+ }
35
+ }
36
+
37
+ impl<T> HeapSize for &T {
38
+ fn heap_size(&self) -> usize {
39
+ 0
40
+ }
41
+ }
42
+
43
+ impl HeapSize for usize {
44
+ fn heap_size(&self) -> usize {
45
+ 0
46
+ }
47
+ }
48
+
49
+ impl<K: HeapSize, V: HeapSize> HeapSize for HashMap<K, V> {
50
+ fn heap_size(&self) -> usize {
51
+ // Account for spare hash buckets and control bytes as well as entries.
52
+ let buckets = if self.capacity() == 0 {
53
+ 0
54
+ } else {
55
+ (self.capacity() + 1).next_power_of_two()
56
+ };
57
+ buckets * (size_of::<(K, V)>() + 1)
58
+ + self
59
+ .iter()
60
+ .map(|(key, value)| key.heap_size() + value.heap_size())
61
+ .sum::<usize>()
62
+ }
63
+ }
64
+
65
+ impl<K: HeapSize, V: HeapSize> HeapSize for BTreeMap<K, V> {
66
+ fn heap_size(&self) -> usize {
67
+ tree_storage::<K, V>(self.len())
68
+ + self
69
+ .iter()
70
+ .map(|(key, value)| key.heap_size() + value.heap_size())
71
+ .sum::<usize>()
72
+ }
73
+ }
74
+
75
+ pub fn tree_storage<K, V>(length: usize) -> usize {
76
+ // Rust does not expose B-tree node capacities; include spare entries and links.
77
+ length.div_ceil(6) * (11 * size_of::<(K, V)>() + 15 * size_of::<usize>())
78
+ }
79
+
80
+ impl HeapSize for Json {
81
+ fn heap_size(&self) -> usize {
82
+ match self {
83
+ Self::String(value) => value.heap_size(),
84
+ Self::Array(values) => values.heap_size(),
85
+ Self::Object(values) => {
86
+ tree_storage::<String, Json>(values.len())
87
+ + values
88
+ .iter()
89
+ .map(|(key, value)| key.heap_size() + value.heap_size())
90
+ .sum::<usize>()
91
+ }
92
+ _ => 0,
93
+ }
94
+ }
95
+ }
96
+
97
+ impl HeapSize for Name {
98
+ fn heap_size(&self) -> usize {
99
+ self.name().len() + self.namespace().map_or(0, |namespace| namespace.len() + 1)
100
+ }
101
+ }
102
+
103
+ impl HeapSize for Alias {
104
+ fn heap_size(&self) -> usize {
105
+ self.name().len() + self.namespace().map_or(0, |namespace| namespace.len() + 1)
106
+ }
107
+ }
108
+
109
+ impl HeapSize for FixedSchema {
110
+ fn heap_size(&self) -> usize {
111
+ self.name.heap_size()
112
+ + self.aliases.heap_size()
113
+ + self.doc.heap_size()
114
+ + self.attributes.heap_size()
115
+ }
116
+ }
117
+
118
+ impl HeapSize for RecordField {
119
+ fn heap_size(&self) -> usize {
120
+ self.name.heap_size()
121
+ + self.doc.heap_size()
122
+ + self.aliases.heap_size()
123
+ + self.default.heap_size()
124
+ + self.schema.heap_size()
125
+ + self.custom_attributes.heap_size()
126
+ }
127
+ }
128
+
129
+ impl HeapSize for Schema {
130
+ fn heap_size(&self) -> usize {
131
+ match self {
132
+ Self::Record(record) => {
133
+ record.name.heap_size()
134
+ + record.aliases.heap_size()
135
+ + record.doc.heap_size()
136
+ + record.fields.heap_size()
137
+ + record.lookup.heap_size()
138
+ + record.attributes.heap_size()
139
+ }
140
+ Self::Enum(value) => {
141
+ value.name.heap_size()
142
+ + value.aliases.heap_size()
143
+ + value.doc.heap_size()
144
+ + value.symbols.heap_size()
145
+ + value.default.heap_size()
146
+ + value.attributes.heap_size()
147
+ }
148
+ Self::Fixed(value) | Self::Duration(value) | Self::Uuid(UuidSchema::Fixed(value)) => {
149
+ value.heap_size()
150
+ }
151
+ Self::Decimal(value) => match &value.inner {
152
+ InnerDecimalSchema::Fixed(fixed) => fixed.heap_size(),
153
+ InnerDecimalSchema::Bytes => 0,
154
+ },
155
+ Self::Array(value) => value.items.heap_size() + value.attributes.heap_size(),
156
+ Self::Map(value) => value.types.heap_size() + value.attributes.heap_size(),
157
+ Self::Union(value) => {
158
+ let variants = value.variants();
159
+ variants.len() * (size_of::<Schema>() + size_of::<usize>())
160
+ + tree_storage::<apache_avro::schema::SchemaKind, usize>(variants.len())
161
+ + variants.iter().map(HeapSize::heap_size).sum::<usize>()
162
+ }
163
+ Self::Ref { name } => name.heap_size(),
164
+ _ => 0,
165
+ }
166
+ }
167
+ }
168
+
169
+ impl HeapSize for Value {
170
+ fn heap_size(&self) -> usize {
171
+ match self {
172
+ Self::String(value) | Self::Enum(_, value) => value.heap_size(),
173
+ Self::Bytes(value) | Self::Fixed(_, value) => value.capacity(),
174
+ Self::Array(values) => values.heap_size(),
175
+ Self::Map(values) => values.heap_size(),
176
+ Self::Record(values) => {
177
+ values.capacity() * size_of::<(String, Value)>()
178
+ + values
179
+ .iter()
180
+ .map(|(name, value)| name.heap_size() + value.heap_size())
181
+ .sum::<usize>()
182
+ }
183
+ Self::Union(_, value) => value.heap_size(),
184
+ Self::Decimal(value) => {
185
+ let value = apache_avro::BigDecimal::new(value.clone().into(), 0);
186
+ (value.as_bigint_and_scale().0.bits().div_ceil(64) * 8) as usize
187
+ }
188
+ Self::BigDecimal(value) => {
189
+ (value.as_bigint_and_scale().0.bits().div_ceil(64) * 8) as usize
190
+ }
191
+ _ => 0,
192
+ }
193
+ }
194
+ }