rambling-trie 2.5.0 → 2.6.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +28 -0
  3. data/Gemfile +20 -9
  4. data/Guardfile +16 -5
  5. data/README.md +50 -42
  6. data/Rakefile +6 -0
  7. data/Steepfile +35 -0
  8. data/lib/rambling/trie/comparable.rb +2 -2
  9. data/lib/rambling/trie/compressible.rb +1 -1
  10. data/lib/rambling/trie/compressor.rb +31 -18
  11. data/lib/rambling/trie/configuration/properties.rb +5 -4
  12. data/lib/rambling/trie/configuration/provider_collection.rb +12 -7
  13. data/lib/rambling/trie/configuration.rb +2 -3
  14. data/lib/rambling/trie/container.rb +27 -26
  15. data/lib/rambling/trie/enumerable.rb +5 -5
  16. data/lib/rambling/trie/inspectable.rb +6 -1
  17. data/lib/rambling/trie/nodes/compressed.rb +28 -18
  18. data/lib/rambling/trie/nodes/node.rb +35 -8
  19. data/lib/rambling/trie/nodes/raw.rb +22 -22
  20. data/lib/rambling/trie/nodes.rb +2 -3
  21. data/lib/rambling/trie/readers/plain_text.rb +2 -2
  22. data/lib/rambling/trie/readers.rb +2 -3
  23. data/lib/rambling/trie/serializers/marshal.rb +1 -1
  24. data/lib/rambling/trie/serializers/yaml.rb +1 -1
  25. data/lib/rambling/trie/serializers/zip.rb +14 -8
  26. data/lib/rambling/trie/serializers.rb +2 -3
  27. data/lib/rambling/trie/stringifyable.rb +1 -1
  28. data/lib/rambling/trie/version.rb +1 -1
  29. data/lib/rambling/trie.rb +14 -17
  30. data/rambling-trie.gemspec +2 -2
  31. data/sig/lib/nilable.rbs +3 -0
  32. data/sig/lib/rambling/trie/comparable.rbs +17 -0
  33. data/sig/lib/rambling/trie/compressible.rbs +17 -0
  34. data/sig/lib/rambling/trie/compressor.rbs +17 -0
  35. data/sig/lib/rambling/trie/configuration/properties.rbs +28 -0
  36. data/sig/lib/rambling/trie/configuration/provider_collection.rbs +43 -0
  37. data/sig/lib/rambling/trie/container.rbs +69 -0
  38. data/sig/lib/rambling/trie/enumerable.rbs +23 -0
  39. data/sig/lib/rambling/trie/inspectable.rbs +32 -0
  40. data/sig/lib/rambling/trie/invalid_operation.rbs +7 -0
  41. data/sig/lib/rambling/trie/nodes/compressed.rbs +25 -0
  42. data/sig/lib/rambling/trie/nodes/missing.rbs +9 -0
  43. data/sig/lib/rambling/trie/nodes/node.rbs +70 -0
  44. data/sig/lib/rambling/trie/nodes/raw.rbs +27 -0
  45. data/sig/lib/rambling/trie/readers/plain_text.rbs +9 -0
  46. data/sig/lib/rambling/trie/readers/reader.rbs +9 -0
  47. data/sig/lib/rambling/trie/serializers/file.rbs +8 -0
  48. data/sig/lib/rambling/trie/serializers/marshal.rbs +13 -0
  49. data/sig/lib/rambling/trie/serializers/serializer.rbs +10 -0
  50. data/sig/lib/rambling/trie/serializers/yaml.rbs +13 -0
  51. data/sig/lib/rambling/trie/serializers/zip.rbs +21 -0
  52. data/sig/lib/rambling/trie/stringifyable.rbs +21 -0
  53. data/sig/lib/rambling/trie.rbs +25 -0
  54. data/sig/lib/zip/entry.rbs +11 -0
  55. data/sig/lib/zip/file.rbs +9 -0
  56. metadata +32 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a489fbd736614f76449e3f4254d798e759e120985a1b141fbae17ec12330c2f
4
- data.tar.gz: e92201410e743a5660fcbbb9703f68ee4e41366b9c4ee987a65f8fd78ea46d0f
3
+ metadata.gz: 52fe8e610cf15d433a18cbb24cdd4b72c48a4ab50398868ab68cce58ea0a8de6
4
+ data.tar.gz: a106639989c7ad33230c252d470a9c7924fd65204ab633743bd813d4f69fa4d4
5
5
  SHA512:
6
- metadata.gz: a0c8f6af0ce43902f5292829e48dfa86e3ca1b623a0742ac129af57bc10209249879f5bdf7ecb4feb65f03da6986748e8cc77f1c458816b8e1aa96063372fc5b
7
- data.tar.gz: 1cc6eb48bf18cdace40358e3ed9371f012f164d5fb6f37e7ff99ce01a4ed0a71d18b21821c3cfef324ebf0ae59c18c2a4fe11e2c8a12044de649c75772221fcb
6
+ metadata.gz: 6d4659cf7e712e4fbed4e6054d6f27f7db0ecbf4dca13fcad6cab34c3050b78cb63cee7993ccda2146868b8d7203932bea08667bb510d0afdcada8cb403c3418
7
+ data.tar.gz: a36621b0ee84dbb8905ca8af25b8fc1b2b08a23ce171fb83c3ec632f39ffc1e7108828330eb93c4285948e5c32a1a6c6d116ad74d9da5a28aa9bd428110dafe5
data/Dockerfile ADDED
@@ -0,0 +1,28 @@
1
+ FROM ruby:3.3.6
2
+
3
+ RUN bundle config --global frozen 1
4
+
5
+ WORKDIR /usr/rambling-trie
6
+ RUN git init
7
+
8
+ # Copy strictly what is necessary to install dependencies
9
+ COPY Gemfile Gemfile.lock rambling-trie.gemspec ./
10
+ COPY lib ./lib
11
+
12
+ # Install dependencies
13
+ RUN bundle install
14
+
15
+ # Copy rest of Ruby and Markdown files
16
+ COPY Rakefile ./
17
+ COPY *.md ./
18
+ COPY assets ./assets
19
+ COPY sig ./sig
20
+ COPY spec ./spec
21
+ COPY tasks ./tasks
22
+ COPY scripts ./scripts
23
+
24
+ # Copy rest of configuration files
25
+ COPY *file ./
26
+ COPY *.yml ./
27
+ COPY .mdl* ./
28
+ COPY .yardopts ./
data/Gemfile CHANGED
@@ -7,29 +7,40 @@ gemspec
7
7
  gem 'rubyzip'
8
8
 
9
9
  group :development do
10
- gem 'benchmark-ips'
11
- gem 'flamegraph'
12
- gem 'memory_profiler'
13
- gem 'pry'
14
10
  gem 'rake'
15
11
  gem 'rspec'
16
- gem 'ruby-prof'
17
- gem 'stackprof'
18
- gem 'yard'
19
12
  end
20
13
 
21
14
  group :test do
22
- gem 'coveralls_reborn', '~> 0.27.0', require: false
15
+ gem 'coveralls_reborn', require: false
23
16
  gem 'rspec_junit_formatter'
24
17
  gem 'simplecov', require: false
25
18
  end
26
19
 
27
20
  group :local do
21
+ gem 'benchmark', require: false
22
+ gem 'benchmark-ips', require: false
23
+ gem 'flamegraph', require: false
28
24
  gem 'flog', require: false
29
- gem 'guard-rspec'
25
+ gem 'guard', require: false
26
+ gem 'guard-reek', require: false
27
+ gem 'guard-rspec', require: false
28
+ gem 'guard-rubocop', require: false
29
+ gem 'guard-yard', require: false
30
+ gem 'irb', require: false
30
31
  gem 'mdl', require: false
32
+ gem 'memory_profiler', require: false
33
+ gem 'pry', require: false
34
+ gem 'racc', require: false
35
+ gem 'rbs', require: false
36
+ gem 'redcarpet', require: false
37
+ gem 'reek', require: false
31
38
  gem 'rubocop', require: false
32
39
  gem 'rubocop-performance', require: false
33
40
  gem 'rubocop-rake', require: false
34
41
  gem 'rubocop-rspec', require: false
42
+ gem 'ruby-prof', require: false
43
+ gem 'stackprof', require: false
44
+ gem 'steep', require: false
45
+ gem 'yard', require: false
35
46
  end
data/Guardfile CHANGED
@@ -1,10 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # A sample Guardfile
4
- # More info at https://github.com/guard/guard#readme
3
+ LIB_REGEX = %r{^lib/(.+)\.rb$}
5
4
 
6
- guard 'rspec', cmd: 'rspec', all_on_start: true, all_after_pass: false do
5
+ guard :reek, all_on_start: true, run_all: true do
6
+ watch(LIB_REGEX)
7
+ end
8
+
9
+ guard :rspec, cmd: 'rspec', all_on_start: true, all_after_pass: false do
7
10
  watch(%r{^spec/.+_spec\.rb$})
8
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
9
- watch('spec/spec_helper.rb') { 'spec' }
11
+ watch(LIB_REGEX) { |m| "spec/lib/#{m[1]}_spec.rb" }
12
+ watch('spec/spec_helper.rb') { 'spec' }
13
+ end
14
+
15
+ guard :rubocop, all_on_start: true do
16
+ watch(LIB_REGEX)
17
+ end
18
+
19
+ guard :yard, server: false do
20
+ watch(LIB_REGEX)
10
21
  end
data/README.md CHANGED
@@ -9,9 +9,6 @@
9
9
  [![Documentation Status][inch_ci_badge]][rubydoc]
10
10
  [![CodeQL Status][github_action_codeql_badge]][github_action_codeql_link]
11
11
 
12
- [![Code Climate Grade][code_climate_grade_badge]][code_climate_link]
13
- [![Code Climate Issue Count][code_climate_issues_badge]][code_climate_link]
14
-
15
12
  The Rambling Trie is a Ruby implementation of the [trie data structure][trie_wiki], which includes compression abilities
16
13
  and is designed to be very fast to traverse.
17
14
 
@@ -21,22 +18,22 @@ and is designed to be very fast to traverse.
21
18
 
22
19
  You will need:
23
20
 
24
- * Ruby 3.1.0 or up
21
+ * Ruby 3.2.0 or up
25
22
  * RubyGems
26
23
 
27
- See [RVM][rvm], [rbenv][rbenv] or [chruby][chruby] for more information on how to manage Ruby versions.
24
+ See [asdf][asdf], [RVM][rvm], [rbenv][rbenv] or [chruby][chruby] for more information on how to manage Ruby versions.
28
25
 
29
26
  ### Installation
30
27
 
31
28
  You can either install it manually with:
32
29
 
33
- ``` bash
30
+ ```shell
34
31
  gem install rambling-trie
35
32
  ```
36
33
 
37
34
  Or, include it in your `Gemfile` and bundle it:
38
35
 
39
- ``` ruby
36
+ ```ruby
40
37
  gem 'rambling-trie'
41
38
  ```
42
39
 
@@ -46,13 +43,13 @@ gem 'rambling-trie'
46
43
 
47
44
  To create a new trie, initialize it like this:
48
45
 
49
- ``` ruby
46
+ ```ruby
50
47
  trie = Rambling::Trie.create
51
48
  ```
52
49
 
53
50
  You can also provide a block and the created trie instance will be yielded for you to perform any operation on it:
54
51
 
55
- ``` ruby
52
+ ```ruby
56
53
  Rambling::Trie.create do |trie|
57
54
  trie << 'word'
58
55
  end
@@ -61,13 +58,13 @@ end
61
58
  Additionally, you can provide the path to a file that contains all the words to be added to the trie, and it will read
62
59
  the file and create the complete structure for you, like this:
63
60
 
64
- ``` ruby
61
+ ```ruby
65
62
  trie = Rambling::Trie.create '/path/to/file'
66
63
  ```
67
64
 
68
65
  By default, a plain text file with the following format will be expected:
69
66
 
70
- ``` text
67
+ ```text
71
68
  some
72
69
  words
73
70
  to
@@ -77,22 +74,21 @@ trie
77
74
  ```
78
75
 
79
76
  If you want to use a custom file format, you will need to provide a custom `Reader` that defines an `#each_word` method
80
- that yields each word contained in the file. Look at the [`PlainText` reader][rambling_trie_plain_text_reader] class for
81
- an example, and at the [Configuration section][rambling_trie_configuration] to see how to add your own custom file
82
- readers.
77
+ that yields each word contained in the file. Look at the [`PlainText` reader](./lib/rambling/trie/readers/plain_text.rb)
78
+ class for an example, and at the [Configuration section](#configuration) to see how to add your own custom file readers.
83
79
 
84
80
  ### Operations
85
81
 
86
82
  To add new words to the trie, use `#add` or its alias `#<<`:
87
83
 
88
- ``` ruby
84
+ ```ruby
89
85
  trie.add 'word'
90
86
  trie << 'word'
91
87
  ```
92
88
 
93
89
  Or if you have multiple words to add, you can use `#concat` or `#push`:
94
90
 
95
- ``` ruby
91
+ ```ruby
96
92
  trie.concat %w(a collection of words)
97
93
  trie.push 'a', 'collection', 'of', 'words'
98
94
 
@@ -104,7 +100,7 @@ trie.push *words
104
100
 
105
101
  And to find out if a word already exists in the trie, use `#word?` or its alias `#include?`:
106
102
 
107
- ``` ruby
103
+ ```ruby
108
104
  trie.word? 'word'
109
105
  trie.include? 'word'
110
106
  ```
@@ -112,21 +108,21 @@ trie.include? 'word'
112
108
  If you wish to find if part of a word exists in the trie instance, you should call `#partial_word?` or its
113
109
  alias `#match?`:
114
110
 
115
- ``` ruby
111
+ ```ruby
116
112
  trie.partial_word? 'partial_word'
117
113
  trie.match? 'partial_word'
118
114
  ```
119
115
 
120
116
  To get all the words that start with a particular string, you can use `#scan` or its alias `#words`:
121
117
 
122
- ``` ruby
118
+ ```ruby
123
119
  trie.scan 'hi' # => ['hi', 'high', 'highlight', ...]
124
120
  trie.words 'hi' # => ['hi', 'high', 'highlight', ...]
125
121
  ```
126
122
 
127
123
  To get all the words within a given string, you can use `#words_within`:
128
124
 
129
- ``` ruby
125
+ ```ruby
130
126
  trie.words_within 'ifdxawesome45someword3' # => ['if', 'aw', 'awe', ...]
131
127
  trie.words_within 'tktktktk' # => []
132
128
  ```
@@ -134,7 +130,7 @@ trie.words_within 'tktktktk' # => []
134
130
  Or, if you're just interested in knowing whether a given string contains any valid words or not, you can
135
131
  use `#words_within?`:
136
132
 
137
- ``` ruby
133
+ ```ruby
138
134
  trie.words_within? 'ifdxawesome45someword3' # => true
139
135
  trie.words_within? 'tktktktk' # => false
140
136
  ```
@@ -144,7 +140,7 @@ trie.words_within? 'tktktktk' # => false
144
140
  By default, the Rambling Trie works as a standard trie. Starting from version 0.1.0, you can obtain a compressed trie
145
141
  from the standard one, by using the compression feature. Just call the `#compress!` method on the trie instance:
146
142
 
147
- ``` ruby
143
+ ```ruby
148
144
  trie.compress!
149
145
  ```
150
146
 
@@ -157,13 +153,13 @@ non-terminal nodes).
157
153
 
158
154
  If you want, you can also create a new compressed trie and leave the existing one intact. Just use `#compress` instead:
159
155
 
160
- ``` ruby
156
+ ```ruby
161
157
  compressed_trie = trie.compress
162
158
  ```
163
159
 
164
160
  You can find out if a trie instance is compressed by calling the `#compressed?` method. From the `#compress` example:
165
161
 
166
- ``` ruby
162
+ ```ruby
167
163
  trie.compressed? # => false
168
164
  compressed_trie.compressed? # => true
169
165
  ```
@@ -173,7 +169,7 @@ compressed_trie.compressed? # => true
173
169
  Starting from version 0.4.2, you can use any `Enumerable` method over a trie instance, and it will iterate over each
174
170
  word contained in the trie. You can now do things like:
175
171
 
176
- ``` ruby
172
+ ```ruby
177
173
  trie.each { |word| puts word }
178
174
  trie.any? { |word| word.include? 'x' }
179
175
  trie.all? { |word| word.include? 'x' }
@@ -182,21 +178,21 @@ trie.all? { |word| word.include? 'x' }
182
178
 
183
179
  ### Serialization
184
180
 
185
- Starting from version 1.0.0, you can store a full trie instance on disk and retrieve/use it later on. Loading a trie
181
+ Starting from version `1.0.0`, you can store a full trie instance on disk and retrieve/use it later on. Loading a trie
186
182
  from disk takes less time, less cpu and less memory than loading every word into the trie every time. This is
187
183
  particularly useful for production applications, when you have word lists that you know are going to be static, or that
188
184
  change with little frequency.
189
185
 
190
186
  To store a trie on disk, you can use `.dump` like this:
191
187
 
192
- ``` ruby
188
+ ```ruby
193
189
  Rambling::Trie.dump trie, '/path/to/file'
194
190
  ```
195
191
 
196
192
  Then, when you need to use a trie next time, you don't have to create a new one with all the necessary words. Rather,
197
193
  you can retrieve a previously stored one with `.load` like this:
198
194
 
199
- ``` ruby
195
+ ```ruby
200
196
  trie = Rambling::Trie.load '/path/to/file'
201
197
  ```
202
198
 
@@ -206,27 +202,34 @@ Currently, these formats are supported to store tries on disk:
206
202
 
207
203
  * Ruby's [binary (Marshal)][marshal] format
208
204
  * [YAML][yaml]
205
+ * Zip version of any other format ([optional `rubyzip` dependency](#optional-rubyzip-dependency))
209
206
 
210
- > When dumping into or loading from disk, the format is determined
211
- > automatically based on the file extension, so `.yml` or `.yaml` files will be
212
- > handled through `YAML` and `.marshal` files through `Marshal`.
207
+ > When dumping into or loading from disk, the format is determined automatically based on the file extension, so `.yml`
208
+ > or `.yaml` files will be handled through `YAML` and `.marshal` files through `Marshal`.
213
209
 
214
- Optionally, you can use a `.zip` version of the supported formats. In order to do so, you'll have to install
215
- the [`rubyzip`][rubyzip] gem:
210
+ ##### Optional `rubyzip` dependency
216
211
 
217
- ``` bash
212
+ Compressed versions of all other [supported formats](#supported-formats) are available via the [`rubyzip`][rubyzip] gem.
213
+ This is an optional dependency.
214
+
215
+ > ⚠️ Rambling Trie `2.6.0` and above support `rubyzip` `3.x` only.
216
+ > For `rubyzip` `2.x` support, use Rambling Trie `2.5.1` and below.
217
+
218
+ ```shell
218
219
  gem install rubyzip
220
+ # or gem install rubyzip --version '<3` for 2.x
219
221
  ```
220
222
 
221
223
  Or, include it in your `Gemfile` and bundle it:
222
224
 
223
- ``` ruby
225
+ ```ruby
224
226
  gem 'rubyzip'
227
+ # or gem 'rubyzip', '<3' for 2.x
225
228
  ```
226
229
 
227
230
  Then, you can load contents form a `.zip` file like this:
228
231
 
229
- ``` ruby
232
+ ```ruby
230
233
  require 'zip'
231
234
  trie = Rambling::Trie.load '/path/to/file.zip'
232
235
  ```
@@ -274,12 +277,14 @@ want edge documentation, you can go the [GitHub project RubyDoc.info page][rubyd
274
277
 
275
278
  The Rambling Trie has been tested with the following Ruby versions:
276
279
 
280
+ * 4.0.x
281
+ * 3.4.x
277
282
  * 3.3.x
278
283
  * 3.2.x
279
- * 3.1.x
280
284
 
281
285
  **No longer supported**:
282
286
 
287
+ * 3.1.x (EOL'ed)
283
288
  * 3.0.x (EOL'ed)
284
289
  * 2.7.x (EOL'ed)
285
290
  * 2.6.x (EOL'ed)
@@ -292,9 +297,14 @@ The Rambling Trie has been tested with the following Ruby versions:
292
297
  * 1.9.x (EOL'ed)
293
298
  * 1.8.x (EOL'ed)
294
299
 
300
+ ## Compatible RBS and Steep versions
301
+
302
+ Type signatures for `Rambling::Trie` are included in the [`sig` directory](./sig)! The current version (`2.6.0`) was
303
+ checked with RBS `3.10.4` and Steep `1.10.0`.
304
+
295
305
  ## Contributing to Rambling Trie
296
306
 
297
- Take a look at the [contributing guide][rambling_trie_contributing_guide] to get started, or fire a question
307
+ Take a look at the [contributing guide](./CONTRIBUTING.md) to get started, or fire a question
298
308
  to [@gonzedge][github_user_gonzedge].
299
309
 
300
310
  ## License and copyright
@@ -316,7 +326,8 @@ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEM
316
326
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
317
327
  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
318
328
 
319
- [badge_fury_badge]: https://badge.fury.io/rb/rambling-trie.svg?version=2.5.0
329
+ [asdf]: https://asdf-vm.com/
330
+ [badge_fury_badge]: https://badge.fury.io/rb/rambling-trie.svg?version=2.6.0
320
331
  [badge_fury_link]: https://badge.fury.io/rb/rambling-trie
321
332
  [chruby]: https://github.com/postmodern/chruby
322
333
  [code_climate_grade_badge]: https://codeclimate.com/github/gonzedge/rambling-trie/badges/gpa.svg
@@ -337,9 +348,6 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
337
348
  [license_badge]: https://img.shields.io/badge/license-MIT-blue.svg
338
349
  [license_link]: https://opensource.org/licenses/mit-license.php
339
350
  [marshal]: https://ruby-doc.org/3.3.0/Marshal.html
340
- [rambling_trie_configuration]: https://github.com/gonzedge/rambling-trie#configuration
341
- [rambling_trie_contributing_guide]: https://github.com/gonzedge/rambling-trie/blob/main/CONTRIBUTING.md
342
- [rambling_trie_plain_text_reader]: https://github.com/gonzedge/rambling-trie/blob/main/lib/rambling/trie/readers/plain_text.rb
343
351
  [rbenv]: https://github.com/sstephenson/rbenv
344
352
  [rubydoc]: http://rubydoc.info/gems/rambling-trie
345
353
  [rubydoc_github]: http://rubydoc.info/github/gonzedge/rambling-trie
data/Rakefile CHANGED
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/gem_tasks'
4
+ require 'reek/rake/task'
4
5
  require 'rspec/core/rake_task'
5
6
  require 'rubocop/rake_task'
7
+ require 'steep/rake_task'
8
+ require 'yard'
6
9
 
7
10
  require 'rambling-trie'
8
11
  require_relative 'tasks/performance'
@@ -10,6 +13,9 @@ require_relative 'tasks/serialization'
10
13
  require_relative 'tasks/ips'
11
14
 
12
15
  RSpec::Core::RakeTask.new :spec
16
+ Reek::Rake::Task.new :reek
13
17
  RuboCop::RakeTask.new :rubocop
18
+ Steep::RakeTask.new :steep
19
+ YARD::Rake::YardocTask.new :yard
14
20
 
15
21
  task default: :spec
data/Steepfile ADDED
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # D = Steep::Diagnostic
4
+ #
5
+ target :lib do
6
+ signature 'sig'
7
+
8
+ check 'lib'
9
+ # check 'tasks'
10
+
11
+ # check 'Gemfile'
12
+ # check 'Guardfile'
13
+ # check 'Rakefile'
14
+ # check 'Steepfile'
15
+
16
+ # library 'rubyzip'
17
+ library 'yaml'
18
+ library 'securerandom'
19
+
20
+ # configure_code_diagnostics(D::Ruby.default) # `default` diagnostics setting (applies by default)
21
+ # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
22
+ # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
23
+ # configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting
24
+ # configure_code_diagnostics do |hash| # You can setup everything yourself
25
+ # hash[D::Ruby::NoMethod] = :information
26
+ # end
27
+ end
28
+
29
+ # target :test do
30
+ # signature 'sig', 'sig-private'
31
+ #
32
+ # check 'test'
33
+ #
34
+ # # library 'pathname' # Standard libraries
35
+ # end
@@ -6,8 +6,8 @@ module Rambling
6
6
  module Comparable
7
7
  # Compares two nodes.
8
8
  # @param [Nodes::Node] other the node to compare against.
9
- # @return [Boolean] +true+ if the nodes' {Nodes::Node#letter #letter} and
10
- # {Nodes::Node#children_tree #children_tree} are equal, +false+ otherwise.
9
+ # @return [Boolean] `true` if the nodes' {Nodes::Node#letter #letter} and
10
+ # {Nodes::Node#children_tree #children_tree} are equal, `false` otherwise.
11
11
  def == other
12
12
  letter == other.letter &&
13
13
  terminal? == other.terminal? &&
@@ -5,7 +5,7 @@ module Rambling
5
5
  # Provides the compressible behavior for the trie data structure.
6
6
  module Compressible
7
7
  # Indicates if the current {Rambling::Trie::Nodes::Node Node} can be compressed or not.
8
- # @return [Boolean] +true+ for non-{Nodes::Node#terminal? terminal} nodes with one child, +false+ otherwise.
8
+ # @return [Boolean] `true` for non-{Nodes::Node#terminal? terminal} nodes with one child, `false` otherwise.
9
9
  def compressible?
10
10
  !(root? || terminal?) && 1 == children_tree.size
11
11
  end
@@ -5,11 +5,13 @@ module Rambling
5
5
  # Responsible for the compression process of a trie data structure.
6
6
  class Compressor
7
7
  # Compresses a {Nodes::Node Node} from a trie data structure.
8
- # @param [Nodes::Raw] node the node to compress.
9
- # @return [Nodes::Compressed] node the compressed version of the node.
8
+ # @param [Nodes::Node, nil] node the node to compress.
9
+ # @return [Nodes::Compressed, nil] node the compressed version of the node.
10
10
  def compress node
11
+ return unless node
12
+
11
13
  if node.compressible?
12
- compress_child_and_merge node
14
+ compress_only_child_and_merge node
13
15
  else
14
16
  compress_children_and_copy node
15
17
  end
@@ -17,40 +19,51 @@ module Rambling
17
19
 
18
20
  private
19
21
 
20
- def compress_child_and_merge node
21
- merge node, compress(node.first_child)
22
+ # Compresses a {Nodes::Node Node} with an only child from a trie data structure.
23
+ # By this point we already know the node is not nil and that it has an only child,
24
+ # so we use the type annotation because compressed_child will always have a value.
25
+ # @see Rambling::Trie::Compressible#compressible? Compressible#compressible?
26
+ # @param [Nodes::Node] node the node to compress.
27
+ # @return [Nodes::Compressed] node the compressed version of the node.
28
+ def compress_only_child_and_merge node
29
+ compressed_child = compress(node.first_child) || raise(InvalidOperation, 'got nil while compressing only child')
30
+ merge node, compressed_child
22
31
  end
23
32
 
24
33
  def merge node, other
25
- return new_compressed_node node.letter, node.parent, node.children_tree, node.terminal? if other.nil?
26
-
27
34
  letter = node.letter.to_s << other.letter.to_s
28
35
 
29
- new_compressed_node letter.to_sym, node.parent, other.children_tree, other.terminal?
36
+ compressed = Rambling::Trie::Nodes::Compressed.new letter.to_sym, node.parent, other.children_tree
37
+ if other.terminal?
38
+ compressed.terminal!
39
+ value = other.value
40
+ compressed.value = value if value
41
+ end
42
+ compressed
30
43
  end
31
44
 
32
45
  def compress_children_and_copy node
33
- new_compressed_node node.letter, node.parent, compress_children(node.children_tree), node.terminal?
46
+ children_tree = compress_children(node.children_tree)
47
+ compressed = Rambling::Trie::Nodes::Compressed.new node.letter, node.parent, children_tree
48
+ if node.terminal?
49
+ compressed.terminal!
50
+ value = node.value
51
+ compressed.value = value if value
52
+ end
53
+ compressed
34
54
  end
35
55
 
36
56
  def compress_children tree
57
+ # @type var new_tree: Hash[Symbol, Nodes::Node]
37
58
  new_tree = {}
38
59
 
39
60
  tree.each do |letter, child|
40
- compressed_child = compress child
61
+ compressed_child = compress(child) || raise(InvalidOperation, "got nil while compressing #{letter}")
41
62
  new_tree[letter] = compressed_child
42
63
  end
43
64
 
44
65
  new_tree
45
66
  end
46
-
47
- def new_compressed_node letter, parent, tree, terminal
48
- node = Rambling::Trie::Nodes::Compressed.new letter, parent, tree
49
- node.terminal! if terminal
50
-
51
- tree.each_value { |child| child.parent = node }
52
- node
53
- end
54
67
  end
55
68
  end
56
69
  end
@@ -4,6 +4,7 @@ module Rambling
4
4
  module Trie
5
5
  module Configuration
6
6
  # Provides configurable properties for Rambling::Trie.
7
+ # :reek:TooManyInstanceVariables { max_instance_variables: 5 }
7
8
  class Properties
8
9
  # The configured {Readers Readers}.
9
10
  # @return [ProviderCollection<Readers::Reader>] the mapping of configured {Readers Readers}.
@@ -17,12 +18,12 @@ module Rambling
17
18
  # @return [Compressor] the configured compressor.
18
19
  attr_accessor :compressor
19
20
 
20
- # The configured +root_builder+, which returns a {Nodes::Node Node} when called.
21
- # @return [Proc<Nodes::Node>] the configured +root_builder+.
21
+ # The configured `root_builder`, which returns a {Nodes::Node Node} when called.
22
+ # @return [Proc<Nodes::Node>] the configured `root_builder`.
22
23
  attr_accessor :root_builder
23
24
 
24
- # The configured +tmp_path+, which will be used for throwaway files.
25
- # @return [String] the configured +tmp_path+.
25
+ # The configured `tmp_path`, which will be used for throwaway files.
26
+ # @return [String] the configured `tmp_path`.
26
27
  attr_accessor :tmp_path
27
28
 
28
29
  # Returns a new properties instance.
@@ -17,7 +17,7 @@ module Rambling
17
17
  # providers.
18
18
  # @param [TProvider] provider the provider to use as default.
19
19
  # @raise [ArgumentError] when the given provider is not in the provider collection.
20
- # @note If no providers have been configured, +nil+ will be assigned.
20
+ # @note If no providers have been configured, `nil` will be assigned.
21
21
  # @return [TProvider, nil] the default provider to use when a provider cannot be resolved in
22
22
  # {ProviderCollection#resolve #resolve}.
23
23
  attr_reader :default
@@ -58,14 +58,19 @@ module Rambling
58
58
  # @param [String] filepath the filepath to resolve into a provider.
59
59
  # @return [TProvider, nil] the provider for the given file's extension. {#default} if not found.
60
60
  def resolve filepath
61
- providers[file_format filepath] || default
61
+ extension = file_format filepath
62
+ if providers.key? extension
63
+ providers[extension]
64
+ else
65
+ default
66
+ end
62
67
  end
63
68
 
64
69
  # Resets the provider collection to the initial values.
65
70
  # @return [void]
66
71
  def reset
67
72
  providers.clear
68
- configured_providers.each { |k, v| self[k] = v }
73
+ configured_providers.each { |extension, provider| self[extension] = provider }
69
74
  self.default = configured_default
70
75
  end
71
76
 
@@ -98,13 +103,13 @@ module Rambling
98
103
  end
99
104
 
100
105
  def file_format filepath
101
- format = File.extname filepath
102
- format.slice! 0
103
- format.to_sym
106
+ File.extname(filepath).sub(%r{^\.}, '').to_sym
104
107
  end
105
108
 
106
109
  def contains? provider
107
- provider.nil? || (providers.any? && provider_instances.include?(provider))
110
+ return true if provider.nil?
111
+
112
+ providers.any? && provider_instances.include?(provider || raise)
108
113
  end
109
114
 
110
115
  alias_method :provider_instances, :values
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- %w(properties provider_collection).each do |file|
4
- require File.join('rambling', 'trie', 'configuration', file)
5
- end
3
+ path = File.join 'rambling', 'trie', 'configuration'
4
+ %w(properties provider_collection).each { |file| require File.join(path, file) }
6
5
 
7
6
  module Rambling
8
7
  module Trie