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.
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
@@ -0,0 +1,4 @@
1
+ module Unibuf
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
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: []