ruby-fst 0.2.0-x64-mingw-ucrt

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9b31a9e023439fc14954b754fa2436e85ffa31c1b17a38c59c67cf790b35fad6
4
+ data.tar.gz: 66ca8d5e9c2dcd370ce14ccfb48712fff21fc087bf25c8a32cc1993f19fa7025
5
+ SHA512:
6
+ metadata.gz: 031f8bf7bfde299f4e3133d423d43403880d6aedbe1201d39fd9a082ccaebdef9cb1fcd0401237f795f3c2068d53f1a6302119688f6f71f8f2be2b31895baf39
7
+ data.tar.gz: 183ca46a0001a7ed95b51de6db5c0d57f1d6b2a58bd2e3b40f5dcdeea5ac20aa51ce09027df96c3a1b1fe8a8db4f3dc446258b0f9f6c72026d2324b763f2bc50
data/.rubocop.yml ADDED
@@ -0,0 +1,82 @@
1
+ plugins:
2
+ - rubocop-minitest
3
+ - rubocop-rake
4
+
5
+ AllCops:
6
+ NewCops: enable
7
+ TargetRubyVersion: 3.2
8
+ SuggestExtensions: false
9
+ Exclude:
10
+ - 'target/**/*'
11
+ - 'tmp/**/*'
12
+ - 'pkg/**/*'
13
+ - 'vendor/**/*'
14
+
15
+ Style/StringLiterals:
16
+ EnforcedStyle: single_quotes
17
+
18
+ Style/StringLiteralsInInterpolation:
19
+ EnforcedStyle: single_quotes
20
+
21
+ Style/SymbolArray:
22
+ EnforcedStyle: percent
23
+ MinSize: 3
24
+
25
+ Style/WordArray:
26
+ EnforcedStyle: percent
27
+ MinSize: 3
28
+
29
+ Style/PercentLiteralDelimiters:
30
+ PreferredDelimiters:
31
+ default: '()'
32
+ '%i': '()'
33
+ '%w': '()'
34
+
35
+ Style/Documentation:
36
+ Enabled: false
37
+
38
+ Style/HashEachMethods:
39
+ Exclude:
40
+ - 'test/**/*'
41
+
42
+ Style/MapIntoArray:
43
+ Exclude:
44
+ - 'test/**/*'
45
+
46
+ Naming/MethodParameterName:
47
+ AllowedNames:
48
+ - ge
49
+ - le
50
+ - id
51
+ - to
52
+ - by
53
+ - on
54
+ - in
55
+ - at
56
+ - of
57
+ - or
58
+ - if
59
+ - is
60
+ - as
61
+ - it
62
+
63
+ Naming/VariableNumber:
64
+ CheckMethodNames: false
65
+
66
+ Layout/LineLength:
67
+ Max: 120
68
+
69
+ Metrics/BlockLength:
70
+ Exclude:
71
+ - 'test/**/*'
72
+ - '*.gemspec'
73
+ - 'Rakefile'
74
+
75
+ Metrics/MethodLength:
76
+ Max: 25
77
+
78
+ Metrics/AbcSize:
79
+ Max: 25
80
+
81
+ Minitest/MultipleAssertions:
82
+ Max: 8
data/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.2.0] — 2026-05-13
10
+
11
+ ### Added
12
+ - `Map.from_path_mmap` and `Set.from_path_mmap` for memory-mapped loading of large FSTs.
13
+ - `Map#range(ge:, le:)` and `Set#range(ge:, le:)` streaming range iteration.
14
+ - `Map#starts_with(prefix)` and `Set#starts_with(prefix)` prefix scans.
15
+ - `Map#get_le_value` and `Map#get_ge_value` — return only the value (no key allocation) for floor/ceiling lookups.
16
+ - Precompiled native gems for Linux (x86_64, aarch64), macOS (x86_64, arm64), and Windows (x64) — installs without a Rust toolchain on those platforms.
17
+ - Tests covering binary string encoding, key lifetime after stream drop, builder GC, and 0xFF prefix-scan edge case.
18
+ - RuboCop lint configuration with rubocop-minitest and rubocop-rake plugins; runs as part of `rake` and as a CI gate.
19
+
20
+ ### Changed
21
+ - Minimum Ruby version raised to 3.2.
22
+ - `MapBuilder` and `SetBuilder` now operate on a generic `Storage` backing (heap or mmap) for both `Map` and `Set`.
23
+ - Upgraded to magnus 0.8 (drops support for Ruby 2.7 and 3.0 in the underlying bindings; we already require 3.2+).
24
+
25
+ ### Documentation
26
+ - README clarifies key encoding, insertion order, mmap vs in-memory loading, and Levenshtein UTF-8 requirement.
27
+
28
+ ## [0.1.0] — 2026-05-13
29
+
30
+ ### Added
31
+ - Initial release: `RubyFst::Map`, `RubyFst::Set`, `MapBuilder`, `SetBuilder`.
32
+ - Floor/ceiling lookups (`get_le`, `get_ge`).
33
+ - Levenshtein automaton search.
34
+ - Bytes/file serialization via `to_bytes` / `save` / `from_path`.
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ gem 'minitest', '~> 5.0'
8
+ gem 'rake', '~> 13.0'
9
+ gem 'rake-compiler', '~> 1.2'
10
+ gem 'rubocop', '~> 1.60', require: false
11
+ gem 'rubocop-minitest', '~> 0.34', require: false
12
+ gem 'rubocop-rake', '~> 0.6', require: false
data/LICENSE.txt ADDED
@@ -0,0 +1,46 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Denis Sablic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+
23
+ ---
24
+
25
+ This gem wraps the fst crate (https://github.com/BurntSushi/fst) by
26
+ Andrew Gallant, which is licensed under the MIT License:
27
+
28
+ Copyright (c) 2015 Andrew Gallant
29
+
30
+ Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ of this software and associated documentation files (the "Software"), to deal
32
+ in the Software without restriction, including without limitation the rights
33
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ copies of the Software, and to permit persons to whom the Software is
35
+ furnished to do so, subject to the following conditions:
36
+
37
+ The above copyright notice and this permission notice shall be included in
38
+ all copies or substantial portions of the Software.
39
+
40
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # ruby-fst
2
+
3
+ [![CI](https://github.com/dsablic/ruby-fst/actions/workflows/ci.yml/badge.svg)](https://github.com/dsablic/ruby-fst/actions/workflows/ci.yml) [![Gem Version](https://badge.fury.io/rb/ruby-fst.svg)](https://badge.fury.io/rb/ruby-fst) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE.txt) [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.2-red.svg)](https://www.ruby-lang.org/)
4
+
5
+ Ruby bindings for the [fst](https://github.com/BurntSushi/fst) crate by Andrew Gallant. Provides finite state transducer backed ordered maps and sets with fast lookup, prefix and range scans, floor/ceiling lookups, and Levenshtein fuzzy search.
6
+
7
+ ## Requirements
8
+
9
+ - Ruby >= 3.2
10
+ - For source installs: a Rust toolchain. Precompiled gems are published for Linux (x86_64, aarch64, glibc and musl), macOS (x86_64, arm64), and Windows (x64) — these install with no Rust toolchain required.
11
+
12
+ ## Installation
13
+
14
+ ```
15
+ gem install ruby-fst
16
+ ```
17
+
18
+ Or add to your Gemfile:
19
+
20
+ ```ruby
21
+ gem 'ruby-fst'
22
+ ```
23
+
24
+ ## Keys are byte strings
25
+
26
+ All FST keys are arbitrary byte strings (`Encoding::BINARY`). When a key is returned from the gem (e.g. via `each`, `get_le`, `range`) it always carries the `Encoding::BINARY` encoding — be careful when interpolating into UTF-8 strings or `puts`-ing keys that contain non-ASCII bytes.
27
+
28
+ Keys must be inserted into a builder in **strictly ascending lexicographic byte order**, with no duplicates. Out-of-order or duplicate inserts raise.
29
+
30
+ ## Map
31
+
32
+ Ordered map from byte string keys to unsigned 64-bit integer values.
33
+
34
+ ```ruby
35
+ require 'ruby_fst'
36
+
37
+ builder = RubyFst::MapBuilder.new
38
+ builder.insert('bar', 2)
39
+ builder.insert('baz', 3)
40
+ builder.insert('foo', 1)
41
+ map = RubyFst::Map.new(builder.finish)
42
+
43
+ map['foo'] # => 1
44
+ map.get('missing') # => nil
45
+ map.contains?('bar') # => true
46
+ map.length # => 3
47
+
48
+ map.each { |key, value| puts("#{key}: #{value}") }
49
+ ```
50
+
51
+ ## Set
52
+
53
+ Ordered set of byte string keys.
54
+
55
+ ```ruby
56
+ builder = RubyFst::SetBuilder.new
57
+ builder.insert('bar')
58
+ builder.insert('baz')
59
+ builder.insert('foo')
60
+ set = RubyFst::Set.new(builder.finish)
61
+
62
+ set.contains?('foo') # => true
63
+ set.length # => 3
64
+
65
+ set.each { |key| puts(key) }
66
+ ```
67
+
68
+ ## Range queries
69
+
70
+ `Map#range` and `Set#range` stream every entry whose key falls in `[ge, le]`. Either bound may be omitted.
71
+
72
+ ```ruby
73
+ map.range(ge: 'b', le: 'f') { |key, value| puts("#{key} -> #{value}") }
74
+ map.range(ge: 'b').to_a # Enumerator without a block
75
+ set.range(le: 'baz') { |key| puts(key) }
76
+ ```
77
+
78
+ `Map#starts_with` and `Set#starts_with` stream every entry whose key begins with the given prefix.
79
+
80
+ ```ruby
81
+ map.starts_with('foo') { |key, value| puts("#{key} -> #{value}") }
82
+ set.starts_with('app').to_a
83
+ ```
84
+
85
+ ## Floor and ceiling lookups
86
+
87
+ `get_le` returns the greatest key less than or equal to the query. `get_ge` returns the smallest key greater than or equal to the query. Both return `[key, value]` or `nil`.
88
+
89
+ ```ruby
90
+ builder = RubyFst::MapBuilder.new
91
+ builder.insert('bar', 1)
92
+ builder.insert('foo', 2)
93
+ builder.insert('qux', 3)
94
+ map = RubyFst::Map.new(builder.finish)
95
+
96
+ map.get_le('dog') # => ["bar", 1]
97
+ map.get_ge('dog') # => ["foo", 2]
98
+ map.get_le('aaa') # => nil
99
+ ```
100
+
101
+ For range lookups where you only need the value, `get_le_value` and `get_ge_value` skip key reconstruction and return only the `Integer` (or `nil`):
102
+
103
+ ```ruby
104
+ map.get_le_value('dog') # => 1
105
+ map.get_ge_value('dog') # => 2
106
+ map.get_le_value('aaa') # => nil
107
+ ```
108
+
109
+ This is useful for IP range lookups. Encode range starts as 4-byte big-endian keys and use `get_le_value` to find which range an IP falls into:
110
+
111
+ ```ruby
112
+ require 'ipaddr'
113
+
114
+ builder = RubyFst::MapBuilder.new
115
+ builder.insert([167_772_160].pack('N'), 1) # 10.0.0.0
116
+ builder.insert([3_232_235_520].pack('N'), 2) # 192.168.0.0
117
+ map = RubyFst::Map.new(builder.finish)
118
+
119
+ ip = IPAddr.new('10.0.0.100').to_i
120
+ label_id = map.get_le_value([ip].pack('N'))
121
+ ```
122
+
123
+ ## Levenshtein search
124
+
125
+ Find all keys within a given edit distance. The search runs as an automaton intersection with the FST, visiting only reachable states.
126
+
127
+ The query must be valid UTF-8 (the Levenshtein automaton is defined over Unicode codepoints), but the keys themselves can be any bytes — the automaton matches against the UTF-8 interpretation of the keys.
128
+
129
+ ```ruby
130
+ builder = RubyFst::MapBuilder.new
131
+ %w(bar baz cat foo fun).each_with_index { |w, i| builder.insert(w, i) }
132
+ map = RubyFst::Map.new(builder.finish)
133
+
134
+ map.search_levenshtein('far', 1) { |key, value| puts(key) }
135
+ # => bar
136
+ ```
137
+
138
+ Works on sets too:
139
+
140
+ ```ruby
141
+ set.search_levenshtein('university', 2) { |key| puts(key) }
142
+ ```
143
+
144
+ ## Serialization
145
+
146
+ ```ruby
147
+ # Bytes
148
+ bytes = map.to_bytes # binary string
149
+ map = RubyFst::Map.new(bytes)
150
+
151
+ # File: read entire file into memory (good for small/medium FSTs)
152
+ map.save('/path/to/file.fst')
153
+ map = RubyFst::Map.from_path('/path/to/file.fst')
154
+
155
+ # File: memory-map the file (good for large FSTs; lookups page in only what they touch)
156
+ map = RubyFst::Map.from_path_mmap('/path/to/file.fst')
157
+ ```
158
+
159
+ When using `from_path_mmap`, the file must remain unchanged on disk for the lifetime of the resulting `Map` or `Set` — modifying or truncating it causes undefined behavior.
160
+
161
+ ## Development
162
+
163
+ ```
164
+ bundle install
165
+ bundle exec rake # compile + test + rubocop
166
+ ```
167
+
168
+ Individual tasks: `rake compile`, `rake test`, `rake rubocop`. Bump the version (and CHANGELOG) with `rake bump[patch]` / `rake bump[minor]` / `rake bump[major]`. Tagging `vX.Y.Z` on GitHub triggers cross-compile and publish to RubyGems.
169
+
170
+ ## License
171
+
172
+ MIT. See [LICENSE.txt](LICENSE.txt) for details.
173
+
174
+ This gem wraps the [fst](https://github.com/BurntSushi/fst) crate by Andrew Gallant, also MIT licensed.
data/Rakefile ADDED
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake/testtask'
4
+ require 'rb_sys/extensiontask'
5
+ require 'rubocop/rake_task'
6
+
7
+ GEMSPEC = Gem::Specification.load('ruby_fst.gemspec')
8
+
9
+ RbSys::ExtensionTask.new('ruby_fst', GEMSPEC) do |ext|
10
+ ext.lib_dir = 'lib/ruby_fst'
11
+ ext.cross_compile = true
12
+ ext.cross_platform = %w(
13
+ aarch64-linux
14
+ aarch64-linux-musl
15
+ arm64-darwin
16
+ x64-mingw-ucrt
17
+ x86_64-darwin
18
+ x86_64-linux
19
+ x86_64-linux-musl
20
+ )
21
+ end
22
+
23
+ Rake::TestTask.new do |t|
24
+ t.libs << 'test'
25
+ t.test_files = FileList['test/**/*_test.rb']
26
+ end
27
+
28
+ RuboCop::RakeTask.new
29
+
30
+ task default: %i(compile test rubocop)
31
+
32
+ desc 'Bump version (rake bump[patch], rake bump[minor], rake bump[major])'
33
+ task :bump, [:level] do |_, args|
34
+ level = args[:level] || 'patch'
35
+ version_file = File.join(__dir__, 'lib', 'ruby_fst', 'version.rb')
36
+ cargo_file = File.join(__dir__, 'ext', 'ruby_fst', 'Cargo.toml')
37
+ lock_file = File.join(__dir__, 'Cargo.lock')
38
+
39
+ content = File.read(version_file)
40
+ current = content[/VERSION = '(.+)'/, 1]
41
+ major, minor, patch = current.split('.').map(&:to_i)
42
+
43
+ new_version =
44
+ case level
45
+ when 'major' then "#{major + 1}.0.0"
46
+ when 'minor' then "#{major}.#{minor + 1}.0"
47
+ when 'patch' then "#{major}.#{minor}.#{patch + 1}"
48
+ else abort("Unknown level: #{level}. Use major, minor, or patch.")
49
+ end
50
+
51
+ File.write(version_file, content.sub(/VERSION = '.+'/, "VERSION = '#{new_version}'"))
52
+
53
+ cargo = File.read(cargo_file)
54
+ File.write(cargo_file, cargo.sub(/^version = ".+"/, "version = \"#{new_version}\""))
55
+
56
+ if File.exist?(lock_file)
57
+ lock = File.read(lock_file)
58
+ File.write(
59
+ lock_file,
60
+ lock.sub(
61
+ /(\[\[package\]\]\nname = "ruby_fst"\nversion = ").+(")/,
62
+ "\\1#{new_version}\\2"
63
+ )
64
+ )
65
+ end
66
+
67
+ changelog_file = File.join(__dir__, 'CHANGELOG.md')
68
+ if File.exist?(changelog_file)
69
+ changelog = File.read(changelog_file)
70
+ today = Time.now.utc.strftime('%Y-%m-%d')
71
+ promoted = changelog.sub(
72
+ '## [Unreleased]',
73
+ "## [Unreleased]\n\n## [#{new_version}] — #{today}"
74
+ )
75
+ File.write(changelog_file, promoted) if promoted != changelog
76
+ end
77
+
78
+ puts("#{current} -> #{new_version}")
79
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyFst
4
+ VERSION = '0.2.0'
5
+ end
data/lib/ruby_fst.rb ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ruby_fst/version'
4
+ require_relative 'ruby_fst/ruby_fst'
5
+
6
+ module RubyFst
7
+ module RangeQuery
8
+ def range(ge: nil, le: nil, &block)
9
+ return enum_for(:range, ge:, le:) unless block
10
+
11
+ _range(ge, le, &block)
12
+ end
13
+
14
+ def starts_with(prefix, &block)
15
+ return enum_for(:starts_with, prefix) unless block
16
+
17
+ _starts_with(prefix, &block)
18
+ end
19
+ end
20
+
21
+ class Map
22
+ include Enumerable
23
+
24
+ alias _range range
25
+ alias _starts_with starts_with
26
+ private :_range, :_starts_with
27
+
28
+ prepend RangeQuery
29
+ end
30
+
31
+ class Set
32
+ include Enumerable
33
+
34
+ alias _range range
35
+ alias _starts_with starts_with
36
+ private :_range, :_starts_with
37
+
38
+ prepend RangeQuery
39
+ end
40
+ end
data/ruby_fst.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/ruby_fst/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'ruby-fst'
7
+ spec.version = RubyFst::VERSION
8
+ spec.authors = ['Denis Sablic']
9
+ spec.email = ['denis.sablic@gmail.com']
10
+ spec.summary = 'Ruby bindings for the Rust fst crate'
11
+ spec.description = 'Finite state transducer backed ordered sets and maps via the Rust fst crate by BurntSushi'
12
+ spec.homepage = 'https://github.com/dsablic/ruby-fst'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = '>= 3.2'
15
+
16
+ spec.metadata['rubygems_mfa_required'] = 'true'
17
+ spec.metadata['source_code_uri'] = 'https://github.com/dsablic/ruby-fst'
18
+ spec.metadata['changelog_uri'] = 'https://github.com/dsablic/ruby-fst/blob/main/CHANGELOG.md'
19
+
20
+ spec.files = Dir.chdir(__dir__) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.start_with?('test/', '.git') }
22
+ end
23
+ spec.extensions = ['ext/ruby_fst/extconf.rb']
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_dependency('rb_sys', '~> 0.9')
27
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-fst
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: x64-mingw-ucrt
6
+ authors:
7
+ - Denis Sablic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-05-13 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Finite state transducer backed ordered sets and maps via the Rust fst
14
+ crate by BurntSushi
15
+ email:
16
+ - denis.sablic@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".rubocop.yml"
22
+ - CHANGELOG.md
23
+ - Gemfile
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - lib/ruby_fst.rb
28
+ - lib/ruby_fst/3.2/ruby_fst.so
29
+ - lib/ruby_fst/3.3/ruby_fst.so
30
+ - lib/ruby_fst/3.4/ruby_fst.so
31
+ - lib/ruby_fst/version.rb
32
+ - ruby_fst.gemspec
33
+ homepage: https://github.com/dsablic/ruby-fst
34
+ licenses:
35
+ - MIT
36
+ metadata:
37
+ rubygems_mfa_required: 'true'
38
+ source_code_uri: https://github.com/dsablic/ruby-fst
39
+ changelog_uri: https://github.com/dsablic/ruby-fst/blob/main/CHANGELOG.md
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '3.2'
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: 3.5.dev
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubygems_version: 3.5.23
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: Ruby bindings for the Rust fst crate
62
+ test_files: []