psychgus 1.2.0 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,11 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: UTF-8
2
+ # frozen_string_literal: true
3
3
 
4
4
  #--
5
5
  # This file is part of Psychgus.
6
- # Copyright (c) 2019 Jonathan Bradley Whited (@esotericpig)
7
- #
8
- # Psychgus is free software: you can redistribute it and/or modify
9
- # it under the terms of the GNU Lesser General Public License as published by
10
- # the Free Software Foundation, either version 3 of the License, or
11
- # (at your option) any later version.
12
- #
13
- # Psychgus is distributed in the hope that it will be useful,
14
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- # GNU Lesser General Public License for more details.
17
- #
18
- # You should have received a copy of the GNU Lesser General Public License
19
- # along with Psychgus. If not, see <http://www.gnu.org/licenses/>.
6
+ # Copyright (c) 2019-2021 Jonathan Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: LGPL-3.0-or-later
20
9
  #++
21
10
 
22
11
 
@@ -26,12 +15,11 @@ module Psychgus
26
15
  class SuperSniffer
27
16
  ###
28
17
  # An empty {SuperSniffer} used for speed when you don't need sniffing in {StyledTreeBuilder}.
29
- #
30
- # @author Jonathan Bradley Whited (@esotericpig)
18
+ #
19
+ # @author Jonathan Bradley Whited
31
20
  # @since 1.0.0
32
21
  ###
33
22
  class Empty < SuperSniffer
34
- def initialize(*) end
35
23
  def add_alias(*) end
36
24
  def add_scalar(*) end
37
25
  def end_document(*) end
@@ -44,29 +32,31 @@ module Psychgus
44
32
  def start_stream(*) end
45
33
  end
46
34
  end
47
-
35
+
48
36
  ###
49
37
  # This is used in {StyledTreeBuilder} to "sniff" information about the YAML.
50
- #
38
+ #
51
39
  # Then this information can be used in a {Styler} and/or a {Blueberry}.
52
- #
40
+ #
53
41
  # Most information is straightforward:
54
42
  # - {#aliases} # Array of Psych::Nodes::Alias processed so far
43
+ # - {#documents} # Array of Psych::Nodes::Document processed so far
55
44
  # - {#mappings} # Array of Psych::Nodes::Mapping processed so far
56
- # - {#nodes} # Array of all Psych::Nodes::Node processed so far
45
+ # - {#nodes} # Array of Psych::Nodes::Node processed so far
57
46
  # - {#scalars} # Array of Psych::Nodes::Scalar processed so far
58
47
  # - {#sequences} # Array of Psych::Nodes::Sequence processed so far
59
- #
48
+ # - {#streams} # Array of Psych::Nodes::Stream processed so far
49
+ #
60
50
  # {#parent} is the current {SuperSniffer::Parent} of the node being processed,
61
- # which is nil for the first node.
62
- #
51
+ # which is an empty Parent for the first node (not nil).
52
+ #
63
53
  # {#parents} are all of the (grand){SuperSniffer::Parent}(s) for the current node,
64
- # which is empty for the first node.
65
- #
54
+ # which is an Array that just contains an empty Parent for the first node.
55
+ #
66
56
  # A parent is a Mapping or Sequence, or a Key (Scalar) in a Mapping.
67
- #
57
+ #
68
58
  # {#level} and {#position} can be best understood by an example.
69
- #
59
+ #
70
60
  # If you have this YAML:
71
61
  # Burgers:
72
62
  # Classic:
@@ -85,10 +75,10 @@ module Psychgus
85
75
  # - Mushrooms
86
76
  # - [Lettuce, Onions, Pickles, Tomatoes]
87
77
  # - [[Ketchup,Mustard], [Salt,Pepper]]
88
- #
78
+ #
89
79
  # Then the levels and positions will be as follows:
90
80
  # # (level:position):current_node - <parent:(parent_level:parent_position)>
91
- #
81
+ #
92
82
  # (1:1):Psych::Nodes::Stream - <root:(0:0)>
93
83
  # (1:1):Psych::Nodes::Document - <stream:(1:1)>
94
84
  # (1:1):Psych::Nodes::Mapping - <doc:(1:1)>
@@ -135,37 +125,37 @@ module Psychgus
135
125
  # (5:2):Psych::Nodes::Sequence - <seq:(4:3)>
136
126
  # (6:1):Salt - <seq:(5:2)>
137
127
  # (6:2):Pepper - <seq:(5:2)>
138
- #
139
- # The "Super Sniffer" is the nickname for Gus's nose from the TV show Psych
128
+ #
129
+ # "The Super Sniffer" is the nickname for Gus's nose from the TV show Psych
140
130
  # because he has a very refined sense of smell.
141
- #
131
+ #
142
132
  # @note You should never call the methods that are not readers, like {#add_alias}, {#start_mapping}, etc.
143
133
  # unless you are extending this class (creating a subclass).
144
- #
145
- # @author Jonathan Bradley Whited (@esotericpig)
134
+ #
135
+ # @author Jonathan Bradley Whited
146
136
  # @since 1.0.0
147
- #
137
+ #
148
138
  # @see StyledTreeBuilder
149
139
  # @see Styler
150
140
  # @see Blueberry#psychgus_stylers
151
141
  ###
152
142
  class SuperSniffer
153
- EMPTY = Empty.new().freeze()
154
-
155
- attr_reader :aliases
156
- attr_reader :documents
157
- attr_reader :level
158
- attr_reader :mappings
159
- attr_reader :nodes
160
- attr_reader :parent
161
- attr_reader :parents
162
- attr_reader :position
163
- attr_reader :scalars
164
- attr_reader :sequences
165
- attr_reader :streams
166
-
143
+ EMPTY = Empty.new.freeze
144
+
145
+ attr_reader :aliases # @return [Array<Psych::Nodes::Alias>] the aliases processed so far
146
+ attr_reader :documents # @return [Array<Psych::Nodes::Document>] the documents processed so far
147
+ attr_reader :level # @return [Integer] the current level
148
+ attr_reader :mappings # @return [Array<Psych::Nodes::Mapping>] the mappings processed so far
149
+ attr_reader :nodes # @return [Array<Psych::Nodes::Node>] the nodes processed so far
150
+ attr_reader :parent # @return [Parent] the current parent
151
+ attr_reader :parents # @return [Array<Parent>] the current (grand)parents
152
+ attr_reader :position # @return [Integer] the current position
153
+ attr_reader :scalars # @return [Array<Psych::Nodes::Scalar>] the scalars processed so far
154
+ attr_reader :sequences # @return [Array<Psych::Nodes::Sequence>] the sequences processed so far
155
+ attr_reader :streams # @return [Array<Psych::Nodes::Stream>] the streams processed so far
156
+
167
157
  # Initialize this class for sniffing.
168
- def initialize()
158
+ def initialize
169
159
  @aliases = []
170
160
  @documents = []
171
161
  @level = 0
@@ -177,240 +167,240 @@ module Psychgus
177
167
  @scalars = []
178
168
  @sequences = []
179
169
  @streams = []
180
-
170
+
181
171
  # Do not pass in "top_level: true"
182
172
  start_parent(nil,debug_tag: :root)
183
173
  end
184
-
174
+
185
175
  # Add a Psych::Nodes::Alias to this class only (not to the YAML).
186
- #
176
+ #
187
177
  # A {Styler} should probably never call this.
188
- #
178
+ #
189
179
  # @param node [Psych::Nodes::Alias] the alias to add
190
- #
180
+ #
191
181
  # @see add_child
192
182
  def add_alias(node)
193
183
  add_child(node)
194
184
  @aliases.push(node)
195
185
  end
196
-
186
+
197
187
  # Add a Psych::Nodes::Scalar to this class only (not to the YAML).
198
- #
188
+ #
199
189
  # A {Styler} should probably never call this.
200
- #
190
+ #
201
191
  # @param node [Psych::Nodes::Scalar] the scalar to add
202
- #
192
+ #
203
193
  # @see add_child
204
194
  def add_scalar(node)
205
195
  add_child(node)
206
196
  @scalars.push(node)
207
197
  end
208
-
198
+
209
199
  # End a Psych::Nodes::Document started with {#start_document}.
210
- #
200
+ #
211
201
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
212
202
  # {#level} and {#position} are reset according to the last parent.
213
- #
203
+ #
214
204
  # A {Styler} should probably never call this.
215
- def end_document()
205
+ def end_document
216
206
  end_parent(top_level: true)
217
207
  end
218
-
208
+
219
209
  # End a Psych::Nodes::Mapping started with {#start_mapping}.
220
- #
210
+ #
221
211
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
222
212
  # {#level} and {#position} are reset according to the last parent.
223
- #
213
+ #
224
214
  # A {Styler} should probably never call this.
225
- #
215
+ #
226
216
  # @see end_parent
227
- def end_mapping()
217
+ def end_mapping
228
218
  end_parent(mapping_value: true)
229
219
  end
230
-
220
+
231
221
  # End a Psych::Nodes::Sequence started with {#start_sequence}.
232
- #
222
+ #
233
223
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
234
224
  # {#level} and {#position} are reset according to the last parent.
235
- #
225
+ #
236
226
  # A {Styler} should probably never call this.
237
- #
227
+ #
238
228
  # @see end_parent
239
- def end_sequence()
229
+ def end_sequence
240
230
  end_parent(mapping_value: true)
241
231
  end
242
-
232
+
243
233
  # End a Psych::Nodes::Stream started with {#start_stream}.
244
- #
234
+ #
245
235
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
246
236
  # {#level} and {#position} are reset according to the last parent.
247
- #
237
+ #
248
238
  # A {Styler} should probably never call this.
249
- def end_stream()
239
+ def end_stream
250
240
  end_parent(top_level: true)
251
241
  end
252
-
242
+
253
243
  # Start a Psych::Nodes::Document.
254
- #
244
+ #
255
245
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
256
246
  # {#level} and {#position} are incremented/set accordingly.
257
- #
247
+ #
258
248
  # A {Styler} should probably never call this.
259
- #
249
+ #
260
250
  # @param node [Psych::Nodes::Document] the Document to start
261
- #
251
+ #
262
252
  # @see start_parent
263
253
  def start_document(node)
264
254
  start_parent(node,debug_tag: :doc,top_level: true)
265
255
  @documents.push(node)
266
256
  end
267
-
257
+
268
258
  # Start a Psych::Nodes::Mapping.
269
- #
259
+ #
270
260
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
271
261
  # {#level} and {#position} are incremented/set accordingly.
272
- #
262
+ #
273
263
  # A {Styler} should probably never call this.
274
- #
264
+ #
275
265
  # @param node [Psych::Nodes::Mapping] the Mapping to start
276
- #
266
+ #
277
267
  # @see start_parent
278
268
  def start_mapping(node)
279
269
  start_parent(node,debug_tag: :map,child_type: :key)
280
270
  @mappings.push(node)
281
271
  end
282
-
272
+
283
273
  # Start a Psych::Nodes::Sequence.
284
- #
274
+ #
285
275
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
286
276
  # {#level} and {#position} are incremented/set accordingly.
287
- #
277
+ #
288
278
  # A {Styler} should probably never call this.
289
- #
279
+ #
290
280
  # @param node [Psych::Nodes::Sequence] the Sequence to start
291
- #
281
+ #
292
282
  # @see start_parent
293
283
  def start_sequence(node)
294
284
  start_parent(node,debug_tag: :seq)
295
285
  @sequences.push(node)
296
286
  end
297
-
287
+
298
288
  # Start a Psych::Nodes::Stream.
299
- #
289
+ #
300
290
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
301
291
  # {#level} and {#position} are incremented/set accordingly.
302
- #
292
+ #
303
293
  # A {Styler} should probably never call this.
304
- #
294
+ #
305
295
  # @param node [Psych::Nodes::Stream] the Stream to start
306
- #
296
+ #
307
297
  # @see start_parent
308
298
  def start_stream(node)
309
299
  start_parent(node,debug_tag: :stream,top_level: true)
310
300
  @streams.push(node)
311
301
  end
312
-
302
+
313
303
  protected
314
-
304
+
315
305
  # Add a non-parent node.
316
- #
306
+ #
317
307
  # This will increment {#position} accordingly, and if the child is a Key to a Mapping,
318
308
  # create a fake "{SuperSniffer::Parent}".
319
- #
309
+ #
320
310
  # @param node [Psych::Nodes::Node] the non-parent Node to add
321
- #
311
+ #
322
312
  # @see end_mapping_value
323
313
  def add_child(node)
324
- if !@parent.nil?()
314
+ if !@parent.nil?
325
315
  # Fake a "parent" if necessary
326
316
  case @parent.child_type
327
317
  when :key
328
318
  start_mapping_key(node)
329
319
  return
330
320
  when :value
331
- end_mapping_value()
321
+ end_mapping_value
332
322
  return
333
323
  else
334
324
  @parent.child_position += 1
335
325
  end
336
326
  end
337
-
327
+
338
328
  @position += 1
339
-
329
+
340
330
  @nodes.push(node)
341
331
  end
342
-
332
+
343
333
  # End a fake "{SuperSniffer::Parent}" that is a Key/Value to a Mapping.
344
- #
334
+ #
345
335
  # @see add_child
346
- def end_mapping_value()
347
- end_parent() # Do not pass in "mapping_value: true" and/or "top_level: true"
348
-
349
- @parent.child_type = :key unless @parent.nil?()
336
+ def end_mapping_value
337
+ end_parent # Do not pass in "mapping_value: true" and/or "top_level: true"
338
+
339
+ @parent.child_type = :key unless @parent.nil?
350
340
  end
351
-
341
+
352
342
  # End a {SuperSniffer::Parent}.
353
- #
343
+ #
354
344
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
355
345
  # {#level} and {#position} are reset according to the last parent.
356
- #
346
+ #
357
347
  # @param mapping_value [true,false] true if parent can be the value of a Mapping's key
358
348
  # @param top_level [true,false] true if a top-level parent (i.e., encapsulating the main data)
359
349
  def end_parent(mapping_value: false,top_level: false)
360
- @parents.pop()
350
+ @parents.pop
361
351
  @parent = @parents.last
362
-
352
+
363
353
  @level = top_level ? 1 : (@level - 1)
364
-
365
- if !@parent.nil?()
354
+
355
+ if !@parent.nil?
366
356
  @parent.child_position += 1
367
357
  @position = @parent.child_position
368
-
358
+
369
359
  # add_child() will not be called again, so end a fake "parent" manually with a fake "value"
370
360
  # - This is necessary for any parents that can be the value of a map's key (e.g., Sequence)
371
- end_mapping_value() if mapping_value && !@parent.child_type.nil?()
361
+ end_mapping_value if mapping_value && !@parent.child_type.nil?
372
362
  end
373
363
  end
374
-
364
+
375
365
  # Start a fake "{SuperSniffer::Parent}" that is a Key/Value to a Mapping.
376
- #
366
+ #
377
367
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
378
368
  # {#level} and {#position} are incremented/set accordingly.
379
- #
369
+ #
380
370
  # @param node [Psych::Nodes::Node] the Node to start
381
- #
371
+ #
382
372
  # @see start_parent
383
373
  def start_mapping_key(node)
384
374
  debug_tag = nil
385
-
375
+
386
376
  # Value must be first because Scalar also has an anchor
387
377
  if node.respond_to?(:value)
388
378
  debug_tag = node.value
389
379
  elsif node.respond_to?(:anchor)
390
380
  debug_tag = node.anchor
391
381
  end
392
-
393
- debug_tag = :noface if debug_tag.nil?()
394
-
382
+
383
+ debug_tag = :noface if debug_tag.nil?
384
+
395
385
  start_parent(node,debug_tag: debug_tag,child_type: :value)
396
386
  end
397
-
387
+
398
388
  # Start a {SuperSniffer::Parent}.
399
- #
389
+ #
400
390
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
401
391
  # {#level} and {#position} are incremented/set accordingly.
402
- #
392
+ #
403
393
  # @param node [Psych::Nodes::Node] the parent Node to start
404
394
  # @param top_level [true,false] true if a top-level parent (i.e., encapsulating the main data)
405
395
  # @param extra [Hash] the extra keyword args to pass to {SuperSniffer::Parent#initialize}
406
- #
396
+ #
407
397
  # @see SuperSniffer::Parent#initialize
408
398
  def start_parent(node,top_level: false,**extra)
409
399
  @parent = Parent.new(self,node,**extra)
410
-
400
+
411
401
  @parents.push(@parent)
412
- @nodes.push(node) unless node.nil?()
413
-
402
+ @nodes.push(node) unless node.nil?
403
+
414
404
  if top_level
415
405
  @level = 1
416
406
  @position = @parent.position