proto_turf 0.0.1 → 0.0.2
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 +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +0 -4
- data/lib/proto_turf/version.rb +1 -1
- data/lib/proto_turf.rb +49 -8
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a059f77cfc5a504cf09140a84a578a3609ef40c83074897f8dda0eb42bcc011e
|
4
|
+
data.tar.gz: 1f0156bec33ddd18a48d90a3500b20066bf3a99a57627ef5a811e4efe439a60f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d7d01d659d17256f3cb3bcba5abb9a1b5634c0e423cb7a0b603855ddbd3c26abb882ca8ae23e651fa5b1e7d39286ff024933fb31c058b57a6077d5b6a4f37ae
|
7
|
+
data.tar.gz: eab1c0e1e9b220a1eb1a9adf2b969adde64298d248816faffa9ed96f15d0ca565997d9d7e201f8d4fef5fe7cf3d128d971720b3393532fb083704bf1ca640774
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## UNRELEASED
|
9
|
+
|
10
|
+
# 0.0.2 - 2025-8-14
|
11
|
+
|
12
|
+
* Initial release.
|
data/README.md
CHANGED
@@ -40,9 +40,5 @@ If you're using [buf](https://buf.build/) to manage your Protobuf definitions, y
|
|
40
40
|
|
41
41
|
## Notes about usage
|
42
42
|
|
43
|
-
* For now, this library only supports a single message per `.proto` file that is registered with the Schema Registry. You can reference as many other files and messages as you like from that message, but keeping it to one message per file simplifies the workflow significantly.
|
44
43
|
* When decoding, this library does *not* attempt to fully parse the Proto definition stored on the schema registry and generate dynamic classes. Instead, it simply parses out the package and message and assumes that the reader has the message available in the descriptor pool. Any compatibility issues should be detected through normal means, i.e. just by instantiating the message and seeing if any errors are raised.
|
45
44
|
|
46
|
-
## TODO
|
47
|
-
|
48
|
-
* Support multi-message proto files
|
data/lib/proto_turf/version.rb
CHANGED
data/lib/proto_turf.rb
CHANGED
@@ -90,7 +90,8 @@ class ProtoTurf
|
|
90
90
|
def encode(message, subject: nil)
|
91
91
|
load_schemas! if @all_schemas.empty?
|
92
92
|
|
93
|
-
|
93
|
+
file_descriptor = message.class.descriptor.file_descriptor
|
94
|
+
id = register_schema(file_descriptor, subject: subject)
|
94
95
|
|
95
96
|
stream = StringIO.new
|
96
97
|
# Always start with the magic byte.
|
@@ -99,9 +100,15 @@ class ProtoTurf
|
|
99
100
|
# The schema id is encoded as a 4-byte big-endian integer.
|
100
101
|
stream.write([id].pack("N"))
|
101
102
|
|
102
|
-
|
103
|
-
|
104
|
-
|
103
|
+
_, indexes = find_index(message.class.descriptor.to_proto,
|
104
|
+
file_descriptor.to_proto.message_type)
|
105
|
+
|
106
|
+
if indexes == [0]
|
107
|
+
write_int(stream, 0)
|
108
|
+
else
|
109
|
+
write_int(stream, indexes.length)
|
110
|
+
indexes.each { |i| write_int(stream, i) }
|
111
|
+
end
|
105
112
|
|
106
113
|
# Now we write the actual message.
|
107
114
|
stream.write(message.to_proto)
|
@@ -135,17 +142,49 @@ class ProtoTurf
|
|
135
142
|
|
136
143
|
# For now, we're only going to support a single message per schema. See
|
137
144
|
# https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#wire-format
|
138
|
-
read_int(stream)
|
145
|
+
index_length = read_int(stream)
|
146
|
+
indexes = []
|
147
|
+
if index_length.zero?
|
148
|
+
indexes.push(0)
|
149
|
+
else
|
150
|
+
index_length.times do
|
151
|
+
indexes.push(read_int(stream))
|
152
|
+
end
|
153
|
+
end
|
139
154
|
|
140
155
|
schema = @registry.fetch(schema_id)
|
141
156
|
encoded = stream.read
|
142
|
-
decode_protobuf(schema, encoded)
|
157
|
+
decode_protobuf(schema, encoded, indexes)
|
143
158
|
rescue Excon::Error::NotFound
|
144
159
|
raise SchemaNotFoundError.new("Schema with id: #{schema_id} is not found on registry")
|
145
160
|
end
|
146
161
|
|
147
162
|
private
|
148
163
|
|
164
|
+
def find_index(descriptor, messages, indexes=[])
|
165
|
+
messages.each_with_index do |sub_descriptor, i|
|
166
|
+
if sub_descriptor == descriptor
|
167
|
+
indexes.push(i)
|
168
|
+
return [true, indexes]
|
169
|
+
else
|
170
|
+
found, found_indexes = find_index(descriptor, sub_descriptor.nested_type, indexes + [i])
|
171
|
+
return [true, found_indexes] if found
|
172
|
+
end
|
173
|
+
end
|
174
|
+
[]
|
175
|
+
end
|
176
|
+
|
177
|
+
def find_descriptor(indexes, messages)
|
178
|
+
first_index = indexes.shift
|
179
|
+
message = messages[first_index]
|
180
|
+
path = [message.name]
|
181
|
+
while indexes.length.positive?
|
182
|
+
message = message.nested_type[indexes.shift]
|
183
|
+
path.push(message.name)
|
184
|
+
end
|
185
|
+
path
|
186
|
+
end
|
187
|
+
|
149
188
|
# Write an int with zig-zag encoding. Copied from Avro.
|
150
189
|
def write_int(stream, n)
|
151
190
|
n = (n << 1) ^ (n >> 63)
|
@@ -169,7 +208,7 @@ class ProtoTurf
|
|
169
208
|
(n >> 1) ^ -(n & 1)
|
170
209
|
end
|
171
210
|
|
172
|
-
def decode_protobuf(schema, encoded)
|
211
|
+
def decode_protobuf(schema, encoded, indexes)
|
173
212
|
# get the package
|
174
213
|
package = schema.match(/package (\S+);/)[1]
|
175
214
|
# get the first message in the protobuf text
|
@@ -181,7 +220,9 @@ class ProtoTurf
|
|
181
220
|
unless descriptor
|
182
221
|
raise "Could not find schema for #{full_name}. Make sure the corresponding .proto file has been compiled and loaded."
|
183
222
|
end
|
184
|
-
descriptor.
|
223
|
+
path = find_descriptor(indexes, descriptor.file_descriptor.to_proto.message_type)
|
224
|
+
correct_message = Google::Protobuf::DescriptorPool.generated_pool.lookup("#{package}.#{path.join('.')}")
|
225
|
+
correct_message.msgclass.decode(encoded)
|
185
226
|
end
|
186
227
|
|
187
228
|
def register_schema(file_descriptor, subject: nil)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proto_turf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Orner
|
@@ -73,6 +73,7 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
+
- CHANGELOG.md
|
76
77
|
- LICENSE
|
77
78
|
- README.md
|
78
79
|
- lib/proto_turf.rb
|