unibuf 0.1.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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/.rubocop_todo.yml +498 -0
- data/README.adoc +490 -0
- data/Rakefile +12 -0
- data/exe/unibuf +7 -0
- data/lib/unibuf/cli.rb +128 -0
- data/lib/unibuf/commands/convert.rb +121 -0
- data/lib/unibuf/commands/parse.rb +85 -0
- data/lib/unibuf/commands/schema.rb +114 -0
- data/lib/unibuf/commands/validate.rb +76 -0
- data/lib/unibuf/errors.rb +36 -0
- data/lib/unibuf/models/enum_definition.rb +78 -0
- data/lib/unibuf/models/field.rb +159 -0
- data/lib/unibuf/models/field_definition.rb +119 -0
- data/lib/unibuf/models/message.rb +203 -0
- data/lib/unibuf/models/message_definition.rb +102 -0
- data/lib/unibuf/models/schema.rb +67 -0
- data/lib/unibuf/models/values/base_value.rb +78 -0
- data/lib/unibuf/models/values/list_value.rb +114 -0
- data/lib/unibuf/models/values/map_value.rb +103 -0
- data/lib/unibuf/models/values/message_value.rb +70 -0
- data/lib/unibuf/models/values/scalar_value.rb +113 -0
- data/lib/unibuf/parsers/binary/wire_format_parser.rb +43 -0
- data/lib/unibuf/parsers/proto3/grammar.rb +149 -0
- data/lib/unibuf/parsers/proto3/processor.rb +188 -0
- data/lib/unibuf/parsers/textproto/grammar.rb +141 -0
- data/lib/unibuf/parsers/textproto/parser.rb +92 -0
- data/lib/unibuf/parsers/textproto/processor.rb +136 -0
- data/lib/unibuf/validators/schema_validator.rb +110 -0
- data/lib/unibuf/validators/type_validator.rb +122 -0
- data/lib/unibuf/version.rb +5 -0
- data/lib/unibuf.rb +207 -0
- data/sig/unibuf.rbs +4 -0
- metadata +139 -0
data/lib/unibuf.rb
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "unibuf/version"
|
|
4
|
+
require_relative "unibuf/errors"
|
|
5
|
+
|
|
6
|
+
module Unibuf
|
|
7
|
+
# Module for all parsers
|
|
8
|
+
module Parsers
|
|
9
|
+
# Text format parser
|
|
10
|
+
module Textproto
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Proto3 schema parser
|
|
14
|
+
module Proto3
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Binary Protocol Buffer parser
|
|
18
|
+
module Binary
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# FlatBuffers schema parser
|
|
22
|
+
module Flatbuffers
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Module for all models
|
|
27
|
+
module Models
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Module for validators
|
|
31
|
+
module Validators
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
# ===== TEXT FORMAT PARSING (no schema required) =====
|
|
36
|
+
|
|
37
|
+
# Parse Protocol Buffer text format from string
|
|
38
|
+
# @param content [String] Text format content
|
|
39
|
+
# @return [Models::Message] Parsed message
|
|
40
|
+
def parse_textproto(content)
|
|
41
|
+
require_relative "unibuf/parsers/textproto/parser"
|
|
42
|
+
Parsers::Textproto::Parser.new.parse(content)
|
|
43
|
+
end
|
|
44
|
+
alias parse_text parse_textproto
|
|
45
|
+
alias parse_txtpb parse_textproto
|
|
46
|
+
|
|
47
|
+
# Parse Protocol Buffer text format from file
|
|
48
|
+
# @param path [String] Path to text format file
|
|
49
|
+
# @return [Models::Message] Parsed message
|
|
50
|
+
def parse_textproto_file(path)
|
|
51
|
+
require_relative "unibuf/parsers/textproto/parser"
|
|
52
|
+
Parsers::Textproto::Parser.new.parse_file(path)
|
|
53
|
+
end
|
|
54
|
+
alias parse_text_file parse_textproto_file
|
|
55
|
+
|
|
56
|
+
# ===== BINARY FORMAT PARSING (schema required) =====
|
|
57
|
+
|
|
58
|
+
# Parse binary Protocol Buffer data
|
|
59
|
+
# @param content [String] Binary data
|
|
60
|
+
# @param schema [Models::Schema] Proto3 schema (required)
|
|
61
|
+
# @return [Models::Message] Parsed message
|
|
62
|
+
def parse_binary(content, schema:)
|
|
63
|
+
raise ArgumentError, "Schema required for binary parsing" unless schema
|
|
64
|
+
|
|
65
|
+
require_relative "unibuf/parsers/binary/wire_format_parser"
|
|
66
|
+
Parsers::Binary::WireFormatParser.new(schema).parse(content)
|
|
67
|
+
end
|
|
68
|
+
alias parse_binpb parse_binary
|
|
69
|
+
|
|
70
|
+
# Parse binary Protocol Buffer file
|
|
71
|
+
# @param path [String] Path to binary file
|
|
72
|
+
# @param schema [Models::Schema] Proto3 schema (required)
|
|
73
|
+
# @return [Models::Message] Parsed message
|
|
74
|
+
def parse_binary_file(path, schema:)
|
|
75
|
+
parse_binary(File.binread(path), schema: schema)
|
|
76
|
+
end
|
|
77
|
+
alias parse_binpb_file parse_binary_file
|
|
78
|
+
|
|
79
|
+
# ===== SCHEMA PARSING =====
|
|
80
|
+
|
|
81
|
+
# Parse Proto3 schema file
|
|
82
|
+
# @param path [String] Path to .proto file
|
|
83
|
+
# @return [Models::Schema] Schema object
|
|
84
|
+
def parse_schema(path)
|
|
85
|
+
require_relative "unibuf/parsers/proto3/grammar"
|
|
86
|
+
require_relative "unibuf/parsers/proto3/processor"
|
|
87
|
+
|
|
88
|
+
grammar = Parsers::Proto3::Grammar.new
|
|
89
|
+
content = File.read(path)
|
|
90
|
+
ast = grammar.parse(content)
|
|
91
|
+
Parsers::Proto3::Processor.process(ast)
|
|
92
|
+
end
|
|
93
|
+
alias load_schema parse_schema
|
|
94
|
+
alias parse_proto3 parse_schema
|
|
95
|
+
|
|
96
|
+
# ===== FLATBUFFERS =====
|
|
97
|
+
|
|
98
|
+
# Parse FlatBuffers schema file
|
|
99
|
+
# @param path [String] Path to .fbs file
|
|
100
|
+
# @return [Models::Flatbuffers::Schema] FlatBuffers schema
|
|
101
|
+
def parse_flatbuffers_schema(path)
|
|
102
|
+
require_relative "unibuf/parsers/flatbuffers/grammar"
|
|
103
|
+
require_relative "unibuf/parsers/flatbuffers/processor"
|
|
104
|
+
|
|
105
|
+
grammar = Parsers::Flatbuffers::Grammar.new
|
|
106
|
+
content = File.read(path)
|
|
107
|
+
ast = grammar.parse(content)
|
|
108
|
+
Parsers::Flatbuffers::Processor.process(ast)
|
|
109
|
+
end
|
|
110
|
+
alias parse_fbs parse_flatbuffers_schema
|
|
111
|
+
|
|
112
|
+
# Parse FlatBuffers binary data
|
|
113
|
+
# @param content [String] Binary FlatBuffers data
|
|
114
|
+
# @param schema [Models::Flatbuffers::Schema] FlatBuffers schema (required)
|
|
115
|
+
# @return [Object] Parsed FlatBuffer object
|
|
116
|
+
def parse_flatbuffers_binary(content, schema:)
|
|
117
|
+
unless schema
|
|
118
|
+
raise ArgumentError,
|
|
119
|
+
"Schema required for FlatBuffers parsing"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
require_relative "unibuf/parsers/flatbuffers/binary_parser"
|
|
123
|
+
Parsers::Flatbuffers::BinaryParser.new(schema).parse(content)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# ===== AUTO-DETECTION (convenience methods) =====
|
|
127
|
+
|
|
128
|
+
# Auto-detect format and parse
|
|
129
|
+
# @param path_or_content [String] File path or content
|
|
130
|
+
# @param schema [Models::Schema, nil] Schema for binary formats (optional)
|
|
131
|
+
# @return [Models::Message] Parsed message
|
|
132
|
+
def parse(path_or_content, schema: nil)
|
|
133
|
+
if File.exist?(path_or_content)
|
|
134
|
+
parse_file(path_or_content, schema: schema)
|
|
135
|
+
else
|
|
136
|
+
# Assume text if no schema provided
|
|
137
|
+
parse_textproto(path_or_content)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Parse file with format auto-detection
|
|
142
|
+
# @param path [String] File path
|
|
143
|
+
# @param schema [Models::Schema, nil] Schema for binary formats
|
|
144
|
+
# @return [Models::Message] Parsed message
|
|
145
|
+
def parse_file(path, schema: nil)
|
|
146
|
+
case File.extname(path).downcase
|
|
147
|
+
when ".txtpb", ".textproto"
|
|
148
|
+
parse_textproto_file(path)
|
|
149
|
+
when ".binpb"
|
|
150
|
+
unless schema
|
|
151
|
+
raise ArgumentError,
|
|
152
|
+
"Binary format requires schema (use schema: parameter)"
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
parse_binary_file(path, schema: schema)
|
|
156
|
+
when ".proto"
|
|
157
|
+
raise ArgumentError, ".proto files are schemas, use parse_schema()"
|
|
158
|
+
when ".fbs"
|
|
159
|
+
raise ArgumentError,
|
|
160
|
+
".fbs files are schemas, use parse_flatbuffers_schema()"
|
|
161
|
+
when ".pb"
|
|
162
|
+
# Ambiguous extension - try to detect
|
|
163
|
+
detect_and_parse_pb(path, schema)
|
|
164
|
+
else
|
|
165
|
+
# Try text format
|
|
166
|
+
parse_textproto_file(path)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
private
|
|
171
|
+
|
|
172
|
+
def detect_and_parse_pb(path, schema)
|
|
173
|
+
content = File.binread(path)
|
|
174
|
+
|
|
175
|
+
if binary_format?(content)
|
|
176
|
+
unless schema
|
|
177
|
+
raise ArgumentError,
|
|
178
|
+
"Binary .pb requires schema parameter"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
parse_binary(content, schema: schema)
|
|
182
|
+
else
|
|
183
|
+
# Text format
|
|
184
|
+
parse_textproto(File.read(path))
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def binary_format?(content)
|
|
189
|
+
# Binary Protocol Buffers have field tags in first few bytes
|
|
190
|
+
# Text format starts with field names (letters)
|
|
191
|
+
return false if content.empty?
|
|
192
|
+
|
|
193
|
+
# Check first non-whitespace byte
|
|
194
|
+
first_byte = content.bytes.find { |b| b > 32 }
|
|
195
|
+
return false unless first_byte
|
|
196
|
+
|
|
197
|
+
# Text starts with letters (65-90, 97-122) or # (35) for comments
|
|
198
|
+
# Binary starts with field tags (usually 8-127 for small field numbers)
|
|
199
|
+
return false if first_byte == 35 # # comment
|
|
200
|
+
return false if first_byte.between?(65, 90) # A-Z
|
|
201
|
+
return false if first_byte.between?(97, 122) # a-z
|
|
202
|
+
|
|
203
|
+
# Likely binary
|
|
204
|
+
true
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
data/sig/unibuf.rbs
ADDED
metadata
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: unibuf
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ronald Tse
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-11-19 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bindata
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.5'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.5'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: lutaml-model
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.7'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.7'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: parslet
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '2.0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '2.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: thor
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.4'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '1.4'
|
|
69
|
+
description: A pure Ruby gem for parsing Protocol Buffers text format (textproto/txtpb)
|
|
70
|
+
and FlatBuffers schema definitions with rich domain models
|
|
71
|
+
email:
|
|
72
|
+
- ronald.tse@ribose.com
|
|
73
|
+
executables:
|
|
74
|
+
- unibuf
|
|
75
|
+
extensions: []
|
|
76
|
+
extra_rdoc_files: []
|
|
77
|
+
files:
|
|
78
|
+
- ".rspec"
|
|
79
|
+
- ".rubocop.yml"
|
|
80
|
+
- ".rubocop_todo.yml"
|
|
81
|
+
- README.adoc
|
|
82
|
+
- Rakefile
|
|
83
|
+
- exe/unibuf
|
|
84
|
+
- lib/unibuf.rb
|
|
85
|
+
- lib/unibuf/cli.rb
|
|
86
|
+
- lib/unibuf/commands/convert.rb
|
|
87
|
+
- lib/unibuf/commands/parse.rb
|
|
88
|
+
- lib/unibuf/commands/schema.rb
|
|
89
|
+
- lib/unibuf/commands/validate.rb
|
|
90
|
+
- lib/unibuf/errors.rb
|
|
91
|
+
- lib/unibuf/models/enum_definition.rb
|
|
92
|
+
- lib/unibuf/models/field.rb
|
|
93
|
+
- lib/unibuf/models/field_definition.rb
|
|
94
|
+
- lib/unibuf/models/message.rb
|
|
95
|
+
- lib/unibuf/models/message_definition.rb
|
|
96
|
+
- lib/unibuf/models/schema.rb
|
|
97
|
+
- lib/unibuf/models/values/base_value.rb
|
|
98
|
+
- lib/unibuf/models/values/list_value.rb
|
|
99
|
+
- lib/unibuf/models/values/map_value.rb
|
|
100
|
+
- lib/unibuf/models/values/message_value.rb
|
|
101
|
+
- lib/unibuf/models/values/scalar_value.rb
|
|
102
|
+
- lib/unibuf/parsers/binary/wire_format_parser.rb
|
|
103
|
+
- lib/unibuf/parsers/proto3/grammar.rb
|
|
104
|
+
- lib/unibuf/parsers/proto3/processor.rb
|
|
105
|
+
- lib/unibuf/parsers/textproto/grammar.rb
|
|
106
|
+
- lib/unibuf/parsers/textproto/parser.rb
|
|
107
|
+
- lib/unibuf/parsers/textproto/processor.rb
|
|
108
|
+
- lib/unibuf/validators/schema_validator.rb
|
|
109
|
+
- lib/unibuf/validators/type_validator.rb
|
|
110
|
+
- lib/unibuf/version.rb
|
|
111
|
+
- sig/unibuf.rbs
|
|
112
|
+
homepage: https://github.com/lutaml/unibuf
|
|
113
|
+
licenses:
|
|
114
|
+
- MIT
|
|
115
|
+
metadata:
|
|
116
|
+
homepage_uri: https://github.com/lutaml/unibuf
|
|
117
|
+
source_code_uri: https://github.com/lutaml/unibuf
|
|
118
|
+
changelog_uri: https://github.com/lutaml/unibuf/blob/main/CHANGELOG.md
|
|
119
|
+
rubygems_mfa_required: 'true'
|
|
120
|
+
post_install_message:
|
|
121
|
+
rdoc_options: []
|
|
122
|
+
require_paths:
|
|
123
|
+
- lib
|
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
|
+
requirements:
|
|
126
|
+
- - ">="
|
|
127
|
+
- !ruby/object:Gem::Version
|
|
128
|
+
version: 3.1.0
|
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
|
+
requirements:
|
|
131
|
+
- - ">="
|
|
132
|
+
- !ruby/object:Gem::Version
|
|
133
|
+
version: '0'
|
|
134
|
+
requirements: []
|
|
135
|
+
rubygems_version: 3.5.22
|
|
136
|
+
signing_key:
|
|
137
|
+
specification_version: 4
|
|
138
|
+
summary: Universal Protocol Buffer & FlatBuffer Parser
|
|
139
|
+
test_files: []
|