Skip to content

Commit 9984b13

Browse files
committed
[Ruby] Add initial Ruby implementation
This supports only reading FlatBuffers data. I confirmed that this implementation works for `reflection/reflection.bfbs` and `tests/monsterdata_test.mon`. This includes tests for them in `tests/ruby/`. `tests/RubyTest.rb` is a test runner. Other `.rb` files in `tests/` are auto generated files by `scripts/generate_code.py`. I followed the suggestion in the pull request template. I'll work on the following tasks after this is merged: * Add support for writing FlatBuffers data. * Prepare RubyGems package.
1 parent ac8b124 commit 9984b13

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+3487
-12
lines changed

.github/workflows/build.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,31 @@ jobs:
594594
working-directory: tests/nim
595595
run: python3 testnim.py
596596

597+
build-ruby:
598+
name: Build Ruby
599+
runs-on: ubuntu-24.04
600+
steps:
601+
- uses: actions/checkout@v5
602+
- uses: ruby/setup-ruby@v1
603+
with:
604+
ruby-version: ruby
605+
- name: flatc
606+
run: |
607+
cmake \
608+
-S . \
609+
-B build \
610+
-G Ninja \
611+
-DCMAKE_BUILD_TYPE=Release \
612+
-DFLATBUFFERS_BUILD_FLATHASH=OFF \
613+
-DFLATBUFFERS_BUILD_FLATLIB=OFF \
614+
-DFLATBUFFERS_BUILD_TESTS=OFF \
615+
-DFLATBUFFERS_INSTALL=OFF \
616+
-DFLATBUFFERS_STRICT_MODE=ON
617+
ninja -C build
618+
- name: test
619+
run: |
620+
BUILD_DIR=build tests/RubyTest.rb
621+
597622
bazel:
598623
name: Bazel
599624
runs-on: ubuntu-24.04

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ set(FlatBuffers_Compiler_SRCS
183183
src/bfbs_gen.h
184184
src/bfbs_gen_lua.h
185185
src/bfbs_gen_nim.h
186+
src/bfbs_gen_ruby.h
186187
src/bfbs_namer.h
187188
include/codegen/idl_namer.h
188189
include/codegen/namer.h
@@ -195,6 +196,7 @@ set(FlatBuffers_Compiler_SRCS
195196
src/annotated_binary_text_gen.cpp
196197
src/bfbs_gen_lua.cpp
197198
src/bfbs_gen_nim.cpp
199+
src/bfbs_gen_ruby.cpp
198200
src/code_generators.cpp
199201
grpc/src/compiler/schema_interface.h
200202
grpc/src/compiler/cpp_generator.h

include/flatbuffers/idl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,7 @@ struct IDLOptions {
753753
kNim = 1 << 17,
754754
kProto = 1 << 18,
755755
kKotlinKmp = 1 << 19,
756+
kRuby = 1 << 20,
756757
kMAX
757758
};
758759

ruby/flatbuffers.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Copyright 2025 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
require_relative "flatbuffers/enum"
16+
require_relative "flatbuffers/flags"
17+
require_relative "flatbuffers/struct"
18+
require_relative "flatbuffers/table"
19+
require_relative "flatbuffers/union"
20+
require_relative "flatbuffers/version"

ruby/flatbuffers/enum.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright 2025 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module FlatBuffers
16+
class Enum
17+
class << self
18+
def try_convert(value)
19+
case value
20+
when Symbol, String
21+
@name_to_enum[value.to_s]
22+
when Integer
23+
@value_to_enum[value]
24+
when self
25+
value
26+
else
27+
nil
28+
end
29+
end
30+
31+
def register(name, value)
32+
object = new(name, value)
33+
(@name_to_enum ||= {})[name] = object
34+
(@value_to_enum ||= {})[value] = object
35+
object
36+
end
37+
end
38+
39+
attr_reader :name
40+
attr_reader :value
41+
def initialize(name, value)
42+
@name = name
43+
@value = value
44+
end
45+
46+
alias_method :to_i, :value
47+
alias_method :to_int, :value
48+
end
49+
end

ruby/flatbuffers/flags.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright 2025 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module FlatBuffers
16+
class Flags
17+
class << self
18+
def try_convert(value)
19+
case value
20+
when Array
21+
value.inject(new) do |previous, v|
22+
flag = try_convert(v)
23+
return nil if flag.nil?
24+
previous | flag
25+
end
26+
when Symbol, String
27+
try_convert(@name_to_value[value.to_s])
28+
when Integer
29+
new(value)
30+
when self
31+
value
32+
else
33+
nil
34+
end
35+
end
36+
37+
def register(name, value)
38+
(@name_to_value ||= {})[name] = value
39+
new(value)
40+
end
41+
42+
def names
43+
@name_to_value.keys
44+
end
45+
46+
def resolve_names(value)
47+
@name_to_value.select do |name, v|
48+
not (value & v).zero?
49+
end
50+
end
51+
end
52+
53+
attr_reader :value
54+
def initialize(value=0)
55+
@value = value
56+
end
57+
58+
def names
59+
@names ||= self.class.resolve_names(@value)
60+
end
61+
62+
alias_method :to_i, :value
63+
alias_method :to_int, :value
64+
65+
def |(other)
66+
self.class.new(@value | Integer(other))
67+
end
68+
end
69+
end

ruby/flatbuffers/inspectable.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2025 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module FlatBuffers
16+
module Inspectable
17+
def inspect
18+
inspected = +"<#{self.class}:"
19+
public_methods(false).each do |name|
20+
next unless method(name).arity.zero?
21+
inspected << " #{name}=#{__send__(name).inspect}"
22+
end
23+
inspected << ">"
24+
inspected
25+
end
26+
27+
def pretty_print(q)
28+
q.object_group(self) do
29+
targets = public_methods(false).select do |name|
30+
method(name).arity.zero?
31+
end
32+
q.seplist(targets, lambda {q.text(",")}) do |name|
33+
q.breakable
34+
q.text(name.to_s)
35+
q.text("=")
36+
q.pp(__send__(name))
37+
end
38+
end
39+
end
40+
end
41+
end

ruby/flatbuffers/struct.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Copyright 2025 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
require_relative "inspectable"
16+
require_relative "view"
17+
18+
module FlatBuffers
19+
class Struct
20+
include Inspectable
21+
22+
def initialize(view)
23+
@view = view
24+
end
25+
end
26+
end

ruby/flatbuffers/table.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright 2025 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
require_relative "inspectable"
16+
require_relative "view"
17+
18+
module FlatBuffers
19+
class Table
20+
include Inspectable
21+
22+
def initialize(input)
23+
if input.is_a?(View)
24+
@view = input
25+
else
26+
if input.is_a?(String)
27+
input = IO::Buffer.for(input)
28+
end
29+
offset = input.get_value(:u32, 0)
30+
@view = View.new(input, offset, have_vtable: true)
31+
end
32+
end
33+
end
34+
end

ruby/flatbuffers/union.rb

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright 2025 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module FlatBuffers
16+
class Union
17+
class << self
18+
def try_convert(value)
19+
case value
20+
when Symbol, String
21+
@name_to_union[value.to_s]
22+
when Integer
23+
@value_to_union[value]
24+
when self
25+
value
26+
else
27+
nil
28+
end
29+
end
30+
31+
def register(name, value, table_class_name, require_path)
32+
object = new(name, value, table_class_name, require_path)
33+
(@name_to_union ||= {})[name] = object
34+
(@value_to_union ||= {})[value] = object
35+
object
36+
end
37+
end
38+
39+
attr_reader :name
40+
attr_reader :value
41+
def initialize(name, value, table_class_name, require_path)
42+
@name = name
43+
@value = value
44+
@table_class_name = table_class_name
45+
@require_path = require_path
46+
end
47+
48+
def table_class
49+
@table_class ||= resolve_table_class
50+
end
51+
52+
private def resolve_table_class
53+
return nil if @table_class_name.nil?
54+
55+
require_table_class
56+
Object.const_get(@table_class_name)
57+
end
58+
59+
alias_method :to_i, :value
60+
alias_method :to_int, :value
61+
end
62+
end

0 commit comments

Comments
 (0)