rambling-trie 2.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -0
  3. data/LICENSE +1 -1
  4. data/README.md +25 -11
  5. data/lib/rambling/trie/comparable.rb +2 -2
  6. data/lib/rambling/trie/compressible.rb +3 -3
  7. data/lib/rambling/trie/configuration/properties.rb +10 -9
  8. data/lib/rambling/trie/configuration/provider_collection.rb +15 -13
  9. data/lib/rambling/trie/container.rb +17 -19
  10. data/lib/rambling/trie/enumerable.rb +3 -0
  11. data/lib/rambling/trie/nodes/compressed.rb +3 -3
  12. data/lib/rambling/trie/nodes/node.rb +14 -14
  13. data/lib/rambling/trie/nodes/raw.rb +2 -2
  14. data/lib/rambling/trie/readers/plain_text.rb +9 -4
  15. data/lib/rambling/trie/readers/reader.rb +21 -0
  16. data/lib/rambling/trie/readers.rb +1 -1
  17. data/lib/rambling/trie/serializers/file.rb +1 -1
  18. data/lib/rambling/trie/serializers/marshal.rb +3 -2
  19. data/lib/rambling/trie/serializers/serializer.rb +27 -0
  20. data/lib/rambling/trie/serializers/yaml.rb +3 -2
  21. data/lib/rambling/trie/serializers/zip.rb +9 -5
  22. data/lib/rambling/trie/serializers.rb +1 -1
  23. data/lib/rambling/trie/stringifyable.rb +1 -1
  24. data/lib/rambling/trie/version.rb +1 -1
  25. data/lib/rambling/trie.rb +11 -9
  26. data/rambling-trie.gemspec +5 -1
  27. data/spec/integration/rambling/trie_spec.rb +13 -16
  28. data/spec/lib/rambling/trie/comparable_spec.rb +29 -39
  29. data/spec/lib/rambling/trie/compressor_spec.rb +17 -14
  30. data/spec/lib/rambling/trie/configuration/properties_spec.rb +25 -7
  31. data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +42 -14
  32. data/spec/lib/rambling/trie/container_spec.rb +200 -325
  33. data/spec/lib/rambling/trie/enumerable_spec.rb +18 -10
  34. data/spec/lib/rambling/trie/inspectable_spec.rb +9 -3
  35. data/spec/lib/rambling/trie/nodes/node_spec.rb +1 -1
  36. data/spec/lib/rambling/trie/nodes/raw_spec.rb +26 -23
  37. data/spec/lib/rambling/trie/readers/plain_text_spec.rb +11 -1
  38. data/spec/lib/rambling/trie/readers/reader_spec.rb +14 -0
  39. data/spec/lib/rambling/trie/serializers/file_spec.rb +1 -3
  40. data/spec/lib/rambling/trie/serializers/marshal_spec.rb +1 -3
  41. data/spec/lib/rambling/trie/serializers/serializer_spec.rb +21 -0
  42. data/spec/lib/rambling/trie/serializers/yaml_spec.rb +1 -3
  43. data/spec/lib/rambling/trie/serializers/zip_spec.rb +24 -16
  44. data/spec/lib/rambling/trie/stringifyable_spec.rb +17 -13
  45. data/spec/lib/rambling/trie_spec.rb +106 -44
  46. data/spec/spec_helper.rb +15 -8
  47. data/spec/support/shared_examples/a_compressible_trie.rb +9 -3
  48. data/spec/support/shared_examples/a_container_partial_word.rb +17 -0
  49. data/spec/support/shared_examples/a_container_scan.rb +14 -0
  50. data/spec/support/shared_examples/a_container_word.rb +43 -0
  51. data/spec/support/shared_examples/a_container_words_within.rb +44 -0
  52. data/spec/support/shared_examples/a_serializable_trie.rb +4 -8
  53. data/spec/support/shared_examples/a_serializer.rb +36 -13
  54. data/spec/support/shared_examples/a_trie_data_structure.rb +24 -10
  55. data/spec/support/shared_examples/a_trie_node.rb +19 -12
  56. data/spec/support/shared_examples/a_trie_node_implementation.rb +40 -43
  57. metadata +19 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7acf86172aa12a848c9590aa0ec0aee132b70f30bf15b720d95e7bc675a8d13
4
- data.tar.gz: 8c08f7abfee53e44d9599160397a21b3e8a9e597125ce52feedbc98f4ad65e62
3
+ metadata.gz: 3af7f8936c101be83262b9535524bdcd3381bb76b857e7a44f331c932c67afb4
4
+ data.tar.gz: e1b9dfc8f88822404c82f95b3fac6a376d3433d15535e8fc0dd454b4669f9e52
5
5
  SHA512:
6
- metadata.gz: c697d039484c41aa733eae791f16b4f82e3b7c6048b006ba64281794834ec54cf5b00f555b3bac196df5589d8dbf779f06fa887a659bb9ee61f822bee7fbdee5
7
- data.tar.gz: fcd664c6802aaf8565820a43f52db146b97e010be2c3a2c64c477a4f6643da02fdbe8238678780d9630f9e6877a8772200af7e4c6e0fb0f16bb9028b382d6099
6
+ metadata.gz: 8bc211404f2a209892aa7de20f20ce5b61f481f117f4ac2f3c45cceaf7076e690229487c7f2dd4613d5725fdf38e4a616efe082b27d4055c359f5801457f704d
7
+ data.tar.gz: 21cb664d6abccbc565fa8c2441c54c18d3ab8a4ccf8ae2457f4671b6b2b579ccd4893a400b3756af82bc261afa8c804db352bf68b6aa0105ab91396b90e1f2be
data/Gemfile CHANGED
@@ -17,10 +17,14 @@ end
17
17
 
18
18
  group :test do
19
19
  gem 'coveralls_reborn', '~> 0.27.0', require: false
20
+ gem 'rspec_junit_formatter'
20
21
  gem 'simplecov', require: false
21
22
  end
22
23
 
23
24
  group :local do
24
25
  gem 'guard-rspec'
25
26
  gem 'rubocop', require: false
27
+ gem 'rubocop-performance', require: false
28
+ gem 'rubocop-rake', require: false
29
+ gem 'rubocop-rspec', require: false
26
30
  end
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-2017 Edgar Gonzalez
1
+ Copyright (c) 2012-2023 Edgar Gonzalez
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Rambling Trie
2
2
 
3
- [![Gem Version][badge_fury_badge]][badge_fury_link] [![Build Status][travis_ci_badge]][travis_ci_link] [![Code Climate][code_climate_badge]][code_climage_link] [![Coverage Status][coveralls_badge]][coveralls_link] [![Documentation Status][inch_ci_badge]][inch_ci_link] [![License][license_badge]][license_link]
3
+ [![Gem Version][badge_fury_badge]][badge_fury_link]
4
+ [![Downloads][downloads_badge]][downloads_link]
5
+ [![License][license_badge]][license_link]
6
+
7
+ [![Build Status][github_action_build_badge]][github_action_build_link]
8
+ [![Coverage Status][coveralls_badge]][coveralls_link]
9
+ [![Documentation Status][inch_ci_badge]][rubydoc]
10
+ [![CodeQL Status][github_action_codeql_badge]][github_action_codeql_link]
11
+
12
+ [![Code Climate Grade][code_climate_grade_badge]][code_climate_link]
13
+ [![Code Climate Issue Count][code_climate_issues_badge]][code_climate_link]
4
14
 
5
15
  The Rambling Trie is a Ruby implementation of the [trie data structure][trie_wiki], which includes compression abilities and is designed to be very fast to traverse.
6
16
 
@@ -167,7 +177,7 @@ Rambling::Trie.dump trie, '/path/to/file'
167
177
  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, you can retrieve a previously stored one with `.load` like this:
168
178
 
169
179
  ``` ruby
170
- trie = Rambling::Trie.load trie, '/path/to/file'
180
+ trie = Rambling::Trie.load '/path/to/file'
171
181
  ```
172
182
 
173
183
  #### Supported formats
@@ -197,7 +207,7 @@ Then, you can load contents form a `.zip` file like this:
197
207
 
198
208
  ``` ruby
199
209
  require 'zip'
200
- trie = Rambling::Trie.load trie, '/path/to/file.zip'
210
+ trie = Rambling::Trie.load '/path/to/file.zip'
201
211
  ```
202
212
 
203
213
  > For `.zip` files, the format is also determined automatically based on the
@@ -265,7 +275,7 @@ Take a look at the [contributing guide][rambling_trie_contributing_guide] to get
265
275
 
266
276
  ## License and copyright
267
277
 
268
- Copyright (c) 2012-2017 Edgar Gonzalez
278
+ Copyright (c) 2012-2023 Edgar González
269
279
 
270
280
  MIT License
271
281
 
@@ -275,19 +285,25 @@ The above copyright notice and this permission notice shall be included in all c
275
285
 
276
286
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
277
287
 
278
- [badge_fury_badge]: https://badge.fury.io/rb/rambling-trie.svg
288
+ [badge_fury_badge]: https://badge.fury.io/rb/rambling-trie.svg?version=2.3.0
279
289
  [badge_fury_link]: https://badge.fury.io/rb/rambling-trie
280
290
  [chruby]: https://github.com/postmodern/chruby
281
- [code_climage_link]: https://codeclimate.com/github/gonzedge/rambling-trie
282
- [code_climate_badge]: https://codeclimate.com/github/gonzedge/rambling-trie/badges/gpa.svg
291
+ [code_climate_grade_badge]: https://codeclimate.com/github/gonzedge/rambling-trie/badges/gpa.svg
292
+ [code_climate_issues_badge]: https://codeclimate.com/github/gonzedge/rambling-trie/badges/issue_count.svg
293
+ [code_climate_link]: https://codeclimate.com/github/gonzedge/rambling-trie
283
294
  [coveralls_badge]: https://img.shields.io/coveralls/gonzedge/rambling-trie.svg
284
295
  [coveralls_link]: https://coveralls.io/r/gonzedge/rambling-trie
296
+ [downloads_badge]: https://img.shields.io/gem/dt/rambling-trie.svg
297
+ [downloads_link]: https://rubygems.org/gems/rambling-trie
285
298
  [gemnasium_badge]: https://gemnasium.com/gonzedge/rambling-trie.svg
286
299
  [gemnasium_link]: https://gemnasium.com/gonzedge/rambling-trie
300
+ [github_action_build_badge]: https://github.com/gonzedge/rambling-trie/actions/workflows/ruby.yml/badge.svg
301
+ [github_action_build_link]: https://github.com/gonzedge/rambling-trie/actions/workflows/ruby.yml
302
+ [github_action_codeql_badge]: https://github.com/gonzedge/rambling-trie/actions/workflows/codeql.yml/badge.svg
303
+ [github_action_codeql_link]: https://github.com/gonzedge/rambling-trie/actions/workflows/codeql.yml
287
304
  [github_user_gonzedge]: https://github.com/gonzedge
288
305
  [inch_ci_badge]: https://inch-ci.org/github/gonzedge/rambling-trie.svg?branch=master
289
- [inch_ci_link]: https://inch-ci.org/github/gonzedge/rambling-trie
290
- [license_badge]: https://badges.frapsoft.com/os/mit/mit.svg?v=103
306
+ [license_badge]: https://img.shields.io/badge/license-MIT-blue.svg
291
307
  [license_link]: https://opensource.org/licenses/mit-license.php
292
308
  [marshal]: https://ruby-doc.org/core-2.7.0/Marshal.html
293
309
  [rambling_trie_configuration]: https://github.com/gonzedge/rambling-trie#configuration
@@ -298,7 +314,5 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
298
314
  [rubydoc_github]: http://rubydoc.info/github/gonzedge/rambling-trie
299
315
  [rubyzip]: https://github.com/rubyzip/rubyzip
300
316
  [rvm]: https://rvm.io
301
- [travis_ci_badge]: https://travis-ci.com/gonzedge/rambling-trie.svg?branch=master
302
- [travis_ci_link]: https://travis-ci.com/github/gonzedge/rambling-trie
303
317
  [trie_wiki]: https://en.wikipedia.org/wiki/Trie
304
318
  [yaml]: https://ruby-doc.org/stdlib-2.7.0/libdoc/yaml/rdoc/YAML.html
@@ -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`
9
+ # @return [Boolean] +true+ if the nodes' {Nodes::Node#letter #letter} and
10
+ # {Nodes::Node#children_tree #children_tree} are equal, +false+
11
11
  # otherwise.
12
12
  def == other
13
13
  letter == other.letter &&
@@ -6,10 +6,10 @@ module Rambling
6
6
  module Compressible
7
7
  # Indicates if the current {Rambling::Trie::Nodes::Node Node} can be
8
8
  # compressed or not.
9
- # @return [Boolean] `true` for non-{Nodes::Node#terminal? terminal} nodes
10
- # with one child, `false` otherwise.
9
+ # @return [Boolean] +true+ for non-{Nodes::Node#terminal? terminal} nodes
10
+ # with one child, +false+ otherwise.
11
11
  def compressible?
12
- !(root? || terminal?) && children_tree.size == 1
12
+ !(root? || terminal?) && 1 == children_tree.size
13
13
  end
14
14
  end
15
15
  end
@@ -6,26 +6,26 @@ module Rambling
6
6
  # Provides configurable properties for Rambling::Trie.
7
7
  class Properties
8
8
  # The configured {Readers Readers}.
9
- # @return [ProviderCollection] the mapping of configured {Readers
10
- # Readers}.
9
+ # @return [ProviderCollection<Readers::Reader>] the mapping of
10
+ # configured {Readers Readers}.
11
11
  attr_reader :readers
12
12
 
13
13
  # The configured {Serializers Serializers}.
14
- # @return [ProviderCollection] the mapping of configured {Serializers
15
- # Serializers}.
14
+ # @return [ProviderCollection<Serializers::Serializer>] the mapping of
15
+ # configured {Serializers Serializers}.
16
16
  attr_reader :serializers
17
17
 
18
18
  # The configured {Compressor Compressor}.
19
19
  # @return [Compressor] the configured compressor.
20
20
  attr_accessor :compressor
21
21
 
22
- # The configured root_builder, which should return a {Nodes::Node Node}
23
- # when called.
24
- # @return [Proc<Nodes::Node>] the configured root_builder.
22
+ # The configured +root_builder+, which returns a {Nodes::Node Node}
23
+ # when called.
24
+ # @return [Proc<Nodes::Node>] the configured +root_builder+.
25
25
  attr_accessor :root_builder
26
26
 
27
- # The configured tmp_path, which will be used for throwaway files.
28
- # @return [String] the configured tmp_path.
27
+ # The configured +tmp_path+, which will be used for throwaway files.
28
+ # @return [String] the configured +tmp_path+.
29
29
  attr_accessor :tmp_path
30
30
 
31
31
  # Returns a new properties instance.
@@ -34,6 +34,7 @@ module Rambling
34
34
  end
35
35
 
36
36
  # Resets back to default properties.
37
+ # @return [void]
37
38
  def reset
38
39
  reset_readers
39
40
  reset_serializers
@@ -6,7 +6,7 @@ module Rambling
6
6
  # Collection of configurable providers.
7
7
  class ProviderCollection
8
8
  # The name of this provider collection.
9
- # @return [String] the name of this provider collection.
9
+ # @return [Symbol] the name of this provider collection.
10
10
  attr_reader :name
11
11
 
12
12
  # @overload default
@@ -15,18 +15,18 @@ module Rambling
15
15
  # @overload default=(provider)
16
16
  # Sets the default provider. Needs to be one of the configured
17
17
  # providers.
18
- # @param [Object] provider the provider to use as default.
18
+ # @param [TProvider] provider the provider to use as default.
19
19
  # @raise [ArgumentError] when the given provider is not in the
20
20
  # provider collection.
21
- # @note If no providers have been configured, `nil` will be assigned.
22
- # @return [Object, nil] the default provider to use when a provider
21
+ # @note If no providers have been configured, +nil+ will be assigned.
22
+ # @return [TProvider, nil] the default provider to use when a provider
23
23
  # cannot be resolved in {ProviderCollection#resolve #resolve}.
24
24
  attr_reader :default
25
25
 
26
26
  # Creates a new provider collection.
27
- # @param [String] name the name for this provider collection.
28
- # @param [Hash] providers the configured providers.
29
- # @param [Object] default the configured default provider.
27
+ # @param [Symbol] name the name for this provider collection.
28
+ # @param [Hash<Symbol, TProvider>] providers the configured providers.
29
+ # @param [TProvider, nil] default the configured default provider.
30
30
  def initialize name, providers = {}, default = nil
31
31
  @name = name
32
32
  @configured_providers = providers
@@ -38,8 +38,9 @@ module Rambling
38
38
  # Adds a new provider to the provider collection.
39
39
  # @param [Symbol] extension the extension that the provider will
40
40
  # correspond to.
41
- # @param [provider] provider the provider to add to the provider
41
+ # @param [TProvider] provider the provider to add to the provider
42
42
  # collection.
43
+ # @return [TProvider] the provider just added.
43
44
  def add extension, provider
44
45
  providers[extension] = provider
45
46
  end
@@ -54,21 +55,22 @@ module Rambling
54
55
  end
55
56
 
56
57
  # List of configured providers.
57
- # @return [Hash] the mapping of extensions to their corresponding
58
- # providers.
58
+ # @return [Hash<Symbol, TProvider>] the mapping of extensions to their
59
+ # corresponding providers.
59
60
  def providers
60
61
  @providers ||= {}
61
62
  end
62
63
 
63
64
  # Resolves the provider from a filepath based on the file extension.
64
65
  # @param [String] filepath the filepath to resolve into a provider.
65
- # @return [Object] the provider corresponding to the file extension in
66
- # this provider collection. {#default} if not found.
66
+ # @return [TProvider, nil] the provider for the given file's extension.
67
+ # {#default} if not found.
67
68
  def resolve filepath
68
69
  providers[file_format filepath] || default
69
70
  end
70
71
 
71
72
  # Resets the provider collection to the initial values.
73
+ # @return [void]
72
74
  def reset
73
75
  providers.clear
74
76
  configured_providers.each { |k, v| self[k] = v }
@@ -85,7 +87,7 @@ module Rambling
85
87
 
86
88
  # Get provider corresponding to a given format.
87
89
  # @param [Symbol] format the format to search for in the collection.
88
- # @return [Object] the provider corresponding to that format.
90
+ # @return [TProvider] the provider corresponding to that format.
89
91
  # @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-5B-5D
90
92
  # Hash#[]
91
93
  def [] format
@@ -13,7 +13,7 @@ module Rambling
13
13
  # Creates a new trie.
14
14
  # @param [Nodes::Node] root the root node for the trie
15
15
  # @param [Compressor] compressor responsible for compressing the trie
16
- # @yield [Container] the trie just created.
16
+ # @yield [self] the trie just initialized.
17
17
  def initialize root, compressor
18
18
  @root = root
19
19
  @compressor = compressor
@@ -44,7 +44,7 @@ module Rambling
44
44
  # Compresses the existing trie using redundant node elimination. Marks
45
45
  # the trie as compressed. Does nothing if the trie has already been
46
46
  # compressed.
47
- # @return [Container] self
47
+ # @return [self]
48
48
  # @note This method replaces the root {Nodes::Raw Raw} node with a
49
49
  # {Nodes::Compressed Compressed} version of it.
50
50
  def compress!
@@ -59,25 +59,24 @@ module Rambling
59
59
  # compressed.
60
60
  def compress
61
61
  return self if root.compressed?
62
+
62
63
  Rambling::Trie::Container.new compress_root, compressor
63
64
  end
64
65
 
65
66
  # Checks if a path for a word or partial word exists in the trie.
66
67
  # @param [String] word the word or partial word to look for in the trie.
67
- # @return [Boolean] `true` if the word or partial word is found, `false`
68
+ # @return [Boolean] +true+ if the word or partial word is found, +false+
68
69
  # otherwise.
69
- # @see Nodes::Raw#partial_word?
70
- # @see Nodes::Compressed#partial_word?
70
+ # @see Nodes::Node#partial_word?
71
71
  def partial_word? word = ''
72
72
  root.partial_word? word.chars
73
73
  end
74
74
 
75
75
  # Checks if a whole word exists in the trie.
76
76
  # @param [String] word the word to look for in the trie.
77
- # @return [Boolean] `true` only if the word is found and the last
78
- # character corresponds to a terminal node, `false` otherwise.
79
- # @see Nodes::Raw#word?
80
- # @see Nodes::Compressed#word?
77
+ # @return [Boolean] +true+ only if the word is found and the last
78
+ # character corresponds to a terminal node, +false+ otherwise.
79
+ # @see Nodes::Node#word?
81
80
  def word? word = ''
82
81
  root.word? word.chars
83
82
  end
@@ -86,8 +85,7 @@ module Rambling
86
85
  # @param [String] word the word to look for in the trie.
87
86
  # @return [Array<String>] all the words contained in the trie that start
88
87
  # with the specified characters.
89
- # @see Nodes::Raw#scan
90
- # @see Nodes::Compressed#scan
88
+ # @see Nodes::Node#scan
91
89
  def scan word = ''
92
90
  root.scan(word.chars).to_a
93
91
  end
@@ -98,15 +96,14 @@ module Rambling
98
96
  # @return [Enumerator<String>] all the words in the given string that
99
97
  # match a word in the trie.
100
98
  # @yield [String] each word found in phrase.
101
- # @see Nodes::Node#words_within
102
99
  def words_within phrase
103
100
  words_within_root(phrase).to_a
104
101
  end
105
102
 
106
103
  # Checks if there are any valid words in a given string.
107
104
  # @param [String] phrase the string to look for matching words in.
108
- # @return [Boolean] `true` if any word within phrase is contained in the
109
- # trie, `false` otherwise.
105
+ # @return [Boolean] +true+ if any word within phrase is contained in the
106
+ # trie, +false+ otherwise.
110
107
  # @see Container#words_within
111
108
  def words_within? phrase
112
109
  words_within_root(phrase).any?
@@ -114,13 +111,14 @@ module Rambling
114
111
 
115
112
  # Compares two trie data structures.
116
113
  # @param [Container] other the trie to compare against.
117
- # @return [Boolean] `true` if the tries are equal, `false` otherwise.
114
+ # @return [Boolean] +true+ if the tries are equal, +false+ otherwise.
118
115
  def == other
119
116
  root == other.root
120
117
  end
121
118
 
122
119
  # Iterates over the words contained in the trie.
123
120
  # @yield [String] the words contained in this trie node.
121
+ # @return [self]
124
122
  def each
125
123
  return enum_for :each unless block_given?
126
124
 
@@ -151,8 +149,8 @@ module Rambling
151
149
  end
152
150
 
153
151
  # Root node's children tree.
154
- # @return [Array<Nodes::Node>] the array of children nodes contained in
155
- # the root node.
152
+ # @return [Hash<Symbol, Nodes::Node>] the children tree hash contained in
153
+ # the root node, consisting of +:letter => node+.
156
154
  # @see Nodes::Node#children_tree
157
155
  def children_tree
158
156
  root.children_tree
@@ -160,8 +158,8 @@ module Rambling
160
158
 
161
159
  # Indicates if the root {Nodes::Node Node} can be
162
160
  # compressed or not.
163
- # @return [Boolean] `true` for non-{Nodes::Node#terminal? terminal}
164
- # nodes with one child, `false` otherwise.
161
+ # @return [Boolean] +true+ for non-{Nodes::Node#terminal? terminal}
162
+ # nodes with one child, +false+ otherwise.
165
163
  def compressed?
166
164
  root.compressed?
167
165
  end
@@ -13,6 +13,7 @@ module Rambling
13
13
 
14
14
  # Iterates over the words contained in the trie.
15
15
  # @yield [String] the words contained in this trie node.
16
+ # @return [self]
16
17
  def each
17
18
  return enum_for :each unless block_given?
18
19
 
@@ -23,6 +24,8 @@ module Rambling
23
24
  yield word
24
25
  end
25
26
  end
27
+
28
+ self
26
29
  end
27
30
  end
28
31
  end
@@ -9,14 +9,14 @@ module Rambling
9
9
  # trying to add a word to the current compressed trie node
10
10
  # @param [String] _ the word to add to the trie.
11
11
  # @raise [InvalidOperation] if the trie is already compressed.
12
- # @return [nil] this never returns as it always raises an exception.
12
+ # @return [void]
13
13
  def add _
14
14
  raise Rambling::Trie::InvalidOperation,
15
15
  'Cannot add word to compressed trie'
16
16
  end
17
17
 
18
- # Always return `true` for a compressed node.
19
- # @return [Boolean] always `true` for a compressed node.
18
+ # Always return +true+ for a compressed node.
19
+ # @return [Boolean] always +true+ for a compressed node.
20
20
  def compressed?
21
21
  true
22
22
  end
@@ -22,8 +22,8 @@ module Rambling
22
22
  attr_reader :letter
23
23
 
24
24
  # Child nodes tree.
25
- # @return [Hash] the children_tree hash, consisting of `:letter =>
26
- # node`.
25
+ # @return [Hash<Symbol, Node>] the children tree hash, consisting of
26
+ # +:letter => node+.
27
27
  attr_accessor :children_tree
28
28
 
29
29
  # Parent node.
@@ -31,7 +31,7 @@ module Rambling
31
31
  attr_accessor :parent
32
32
 
33
33
  # Creates a new node.
34
- # @param [Symbol, nil] letter the Node's letter value
34
+ # @param [Symbol, nil] letter the Node's letter value.
35
35
  # @param [Node, nil] parent the parent of the current node.
36
36
  def initialize letter = nil, parent = nil, children_tree = {}
37
37
  @letter = letter
@@ -40,7 +40,7 @@ module Rambling
40
40
  end
41
41
 
42
42
  # Child nodes.
43
- # @return [Array<Node>] the array of children nodes contained
43
+ # @return [Array<Node>] the array of child nodes contained
44
44
  # in the current node.
45
45
  def children
46
46
  children_tree.values
@@ -51,20 +51,20 @@ module Rambling
51
51
  def first_child
52
52
  return if children_tree.empty?
53
53
 
54
- children_tree.each_value do |child|
55
- return child
56
- end
54
+ # rubocop:disable Lint/UnreachableLoop
55
+ children_tree.each_value { |child| return child }
56
+ # rubocop:enable Lint/UnreachableLoop
57
57
  end
58
58
 
59
59
  # Indicates if the current node is the root node.
60
- # @return [Boolean] `true` if the node does not have a parent, `false`
60
+ # @return [Boolean] +true+ if the node does not have a parent, +false+
61
61
  # otherwise.
62
62
  def root?
63
63
  !parent
64
64
  end
65
65
 
66
66
  # Indicates if a {Node Node} is terminal or not.
67
- # @return [Boolean] `true` for terminal nodes, `false` otherwise.
67
+ # @return [Boolean] +true+ for terminal nodes, +false+ otherwise.
68
68
  def terminal?
69
69
  !!terminal
70
70
  end
@@ -82,7 +82,7 @@ module Rambling
82
82
 
83
83
  # Checks if a path for a set of characters exists in the trie.
84
84
  # @param [Array<String>] chars the characters to look for in the trie.
85
- # @return [Boolean] `true` if the characters are found, `false`
85
+ # @return [Boolean] +true+ if the characters are found, +false+
86
86
  # otherwise.
87
87
  def partial_word? chars
88
88
  return true if chars.empty?
@@ -92,8 +92,8 @@ module Rambling
92
92
 
93
93
  # Checks if a path for set of characters represents a word in the trie.
94
94
  # @param [Array<String>] chars the characters to look for in the trie.
95
- # @return [Boolean] `true` if the characters are found and form a word,
96
- # `false` otherwise.
95
+ # @return [Boolean] +true+ if the characters are found and form a word,
96
+ # +false+ otherwise.
97
97
  def word? chars = []
98
98
  return terminal? if chars.empty?
99
99
 
@@ -148,7 +148,7 @@ module Rambling
148
148
  # Check if a {Node Node}'s children tree contains a given
149
149
  # letter.
150
150
  # @param [Symbol] letter the letter to search for in the node.
151
- # @return [Boolean] `true` if the letter is present, `false` otherwise
151
+ # @return [Boolean] +true+ if the letter is present, +false+ otherwise.
152
152
  # @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-has_key-3F
153
153
  # Hash#key?
154
154
  def key? letter
@@ -156,7 +156,7 @@ module Rambling
156
156
  end
157
157
 
158
158
  # Delete a given letter and its corresponding {Node Node} from
159
- # this {Node Node}'s children tree.
159
+ # this {Node Node}'s children tree.
160
160
  # @param [Symbol] letter the letter to delete from the node's children
161
161
  # tree.
162
162
  # @return [Node] the node corresponding to the deleted letter.
@@ -17,8 +17,8 @@ module Rambling
17
17
  end
18
18
  end
19
19
 
20
- # Always return `false` for a raw (uncompressed) node.
21
- # @return [Boolean] always `false` for a raw (uncompressed) node.
20
+ # Always return +false+ for a raw (uncompressed) node.
21
+ # @return [Boolean] always +false+ for a raw (uncompressed) node.
22
22
  def compressed?
23
23
  false
24
24
  end
@@ -3,14 +3,19 @@
3
3
  module Rambling
4
4
  module Trie
5
5
  module Readers
6
- # File reader for .txt files.
7
- class PlainText
8
- # Yields each word read from a .txt file.
6
+ # File reader for +.txt+ files.
7
+ class PlainText < Reader
8
+ # Yields each word read from a +.txt+ file.
9
9
  # @param [String] filepath the full path of the file to load the words
10
10
  # from.
11
11
  # @yield [String] Each line read from the file.
12
+ # @return [self]
12
13
  def each_word filepath
13
- File.foreach(filepath) { |line| yield line.chomp! }
14
+ return enum_for :each_word unless block_given?
15
+
16
+ ::File.foreach(filepath) { |line| yield line.chomp! }
17
+
18
+ self
14
19
  end
15
20
  end
16
21
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rambling
4
+ module Trie
5
+ module Readers
6
+ # Base class for all readers.
7
+ class Reader
8
+ # Yields each word read from given file.
9
+ # @abstract Subclass and override {#each_word} to fit to a particular
10
+ # file format.
11
+ # @param [String] filepath the full path of the file to load the words
12
+ # from.
13
+ # @yield [String] Each line read from the file.
14
+ # @return [self]
15
+ def each_word filepath
16
+ raise NotImplementedError
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- %w(plain_text).each do |file|
3
+ %w(reader plain_text).each do |file|
4
4
  require File.join('rambling', 'trie', 'readers', file)
5
5
  end
6
6
 
@@ -4,7 +4,7 @@ module Rambling
4
4
  module Trie
5
5
  module Serializers
6
6
  # Basic file serializer. Dumps/loads string contents from files.
7
- class File
7
+ class File < Serializer
8
8
  # Loads contents from a specified filepath.
9
9
  # @param [String] filepath the filepath to load contents from.
10
10
  # @return [String] all contents of the file.
@@ -3,13 +3,14 @@
3
3
  module Rambling
4
4
  module Trie
5
5
  module Serializers
6
- # Serializer for Ruby marshal format (.marshal) files.
7
- class Marshal
6
+ # Serializer for Ruby marshal format (+.marshal+) files.
7
+ class Marshal < Serializer
8
8
  # Creates a new Marshal serializer.
9
9
  # @param [Serializer] serializer the serializer responsible to write to
10
10
  # and read from disk.
11
11
  def initialize serializer = nil
12
12
  @serializer = serializer || Rambling::Trie::Serializers::File.new
13
+ super()
13
14
  end
14
15
 
15
16
  # Loads marshaled object from contents in filepath and deserializes it
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rambling
4
+ module Trie
5
+ module Serializers
6
+ # Base class for all serializers.
7
+ class Serializer
8
+ # Loads contents from a specified filepath.
9
+ # @abstract Subclass and override {#load} to parse the desired format.
10
+ # @param [String] filepath the filepath to load contents from.
11
+ # @return [TContents] parsed contents from given file.
12
+ def load filepath
13
+ raise NotImplementedError
14
+ end
15
+
16
+ # Dumps contents into a specified filepath.
17
+ # @abstract Subclass and override {#dump} to output the desired format.
18
+ # @param [TContents] contents the contents to dump into given file.
19
+ # @param [String] filepath the filepath to dump the contents to.
20
+ # @return [Numeric] number of bytes written to disk.
21
+ def dump contents, filepath
22
+ raise NotImplementedError
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -3,13 +3,14 @@
3
3
  module Rambling
4
4
  module Trie
5
5
  module Serializers
6
- # Serializer for Ruby yaml format (.yaml) files.
7
- class Yaml
6
+ # Serializer for Ruby yaml format (+.yaml+, or +.yml+) files.
7
+ class Yaml < Serializer
8
8
  # Creates a new Yaml serializer.
9
9
  # @param [Serializer] serializer the serializer responsible to write to
10
10
  # and read from disk.
11
11
  def initialize serializer = nil
12
12
  @serializer = serializer || Rambling::Trie::Serializers::File.new
13
+ super()
13
14
  end
14
15
 
15
16
  # Loads serialized object from YAML file in filepath and deserializes