cli-dispatcher 1.1.11 → 1.2.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.
- checksums.yaml +4 -4
- data/lib/structured.rb +101 -56
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 850d024672db8785ec7d329961a30baf9e8d4f1724189f6cf6250472cc17e5e8
|
4
|
+
data.tar.gz: 11e2ab38ddd9cc99d7ec2b66bf4b97d229a470ded4295ef2e7ecddca99bca74e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f5a3f85f1f64785b526df560efe2ef2ee94b031d0ef9bd47d43fd6500eaf4faba0b70a6230d1ccbc49db4d9a8d0681a1ba17edd847c105ab0b8d106568ccb2f
|
7
|
+
data.tar.gz: e6c3a31bd0825b3ae234dd68b6432e5a5b7f0fe4daf76a9494545018d264615630f89368b1c352d950be23a66be76e36fa5a3059bb38ad411d37f91912480f5a
|
data/lib/structured.rb
CHANGED
@@ -172,7 +172,8 @@ module Structured
|
|
172
172
|
# raises an error, but classes may override this method to use the undefined
|
173
173
|
# elements.
|
174
174
|
#
|
175
|
-
# @param element The unknown element name,
|
175
|
+
# @param element The unknown element name. For a YAML file, this is typically
|
176
|
+
# a string.
|
176
177
|
#
|
177
178
|
# @param val The value associated with the unknown element.
|
178
179
|
#
|
@@ -212,6 +213,7 @@ module Structured
|
|
212
213
|
def reset_elements
|
213
214
|
@elements = {}
|
214
215
|
@default_element = nil
|
216
|
+
@default_key = nil
|
215
217
|
@class_description = nil
|
216
218
|
end
|
217
219
|
|
@@ -266,14 +268,32 @@ module Structured
|
|
266
268
|
|
267
269
|
#
|
268
270
|
# Accepts a default element for this class. The arguments are the same as
|
269
|
-
# those for element_data.
|
271
|
+
# those for element_data except as noted below.
|
270
272
|
#
|
271
|
-
#
|
272
|
-
#
|
273
|
+
# If this method is called, then for any keys found in an input hash that
|
274
|
+
# have no corresponding #element declaration in the Structured class, the
|
275
|
+
# method receive_any will be invoked. The value from the input hash
|
276
|
+
# will be processed based on any type declaration, `preproc`, and `check`
|
277
|
+
# given to default_element.
|
278
|
+
#
|
279
|
+
# The default element keys can be processed based on the argument `key`,
|
280
|
+
# which should be a hash corresponding to the element_data arguments plus
|
281
|
+
# the key :type with the default key's expected type. If `key` is not given,
|
282
|
+
# then the key must be and is automatically converted to a Symbol.
|
283
|
+
#
|
284
|
+
# **Caution**: The `type` argument should almost always be a single class,
|
285
|
+
# and not a hash. This is because the default arguments are automatically
|
273
286
|
# treated like a hash, with the otherwise-undefined element names being the
|
274
287
|
# keys of the hash.
|
275
288
|
#
|
276
289
|
def default_element(*args, **params)
|
290
|
+
if (key_params = params.delete(:key))
|
291
|
+
@default_key = element_data(
|
292
|
+
key_params.delete(:type) || Object, key_params
|
293
|
+
)
|
294
|
+
else
|
295
|
+
@default_key = element_data(Symbol, preproc: proc { |s| s.to_sym })
|
296
|
+
end
|
277
297
|
@default_element = element_data(*args, **params)
|
278
298
|
end
|
279
299
|
|
@@ -384,47 +404,28 @@ module Structured
|
|
384
404
|
input_err("Initializer is not a Hash") unless hash.is_a?(Hash)
|
385
405
|
hash = try_read_file(hash)
|
386
406
|
|
387
|
-
@elements.each do |
|
388
|
-
Structured.trace(
|
389
|
-
val = hash[
|
390
|
-
|
391
|
-
|
392
|
-
if data[:preproc]
|
393
|
-
val = try_run(data[:preproc], obj, val, "preproc")
|
394
|
-
next if process_nil_val(obj, elt, val, data)
|
395
|
-
end
|
396
|
-
|
397
|
-
cval = convert_item(val, data[:type], obj)
|
398
|
-
|
399
|
-
# Check for validity after preproc and conversion are run
|
400
|
-
if data[:check] && !try_run(data[:check], obj, cval, "check")
|
401
|
-
input_err "Value #{cval} failed check for #{elt}"
|
402
|
-
end
|
403
|
-
|
404
|
-
# Use the converted value
|
405
|
-
apply_val(obj, elt, cval)
|
407
|
+
@elements.each do |key, data|
|
408
|
+
Structured.trace(key.to_s) do
|
409
|
+
val = hash[key] || hash[key.to_s]
|
410
|
+
cval = process_value(obj, val, data)
|
411
|
+
apply_val(obj, key, cval) if cval
|
406
412
|
end
|
407
413
|
end
|
408
414
|
|
409
415
|
# Process unknown elements
|
410
|
-
|
411
|
-
return if
|
416
|
+
unknown_keys = hash.keys.reject { |k| @elements.include?(k.to_sym) }
|
417
|
+
return if unknown_keys.empty?
|
412
418
|
unless @default_element
|
413
|
-
input_err("Unexpected element(s): #{
|
419
|
+
input_err("Unexpected element(s): #{unknown_keys.join(', ')}")
|
414
420
|
end
|
415
|
-
|
416
|
-
Structured.trace(
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
if de[:check] && !try_run(de[:check], obj, item, "check")
|
424
|
-
input_err "Value #{item} failed default element check"
|
425
|
-
end
|
426
|
-
item.receive_key(elt) if item.is_a?(Structured)
|
427
|
-
obj.receive_any(elt, item)
|
421
|
+
unknown_keys.each do |key|
|
422
|
+
Structured.trace(key.to_s) do
|
423
|
+
val = hash[key]
|
424
|
+
ckey = process_value(obj, key, @default_key)
|
425
|
+
cval = process_value(obj, val, @default_element)
|
426
|
+
next unless cval
|
427
|
+
cval.receive_key(ckey) if cval.is_a?(Structured)
|
428
|
+
obj.receive_any(ckey, cval)
|
428
429
|
end
|
429
430
|
end
|
430
431
|
end
|
@@ -450,24 +451,53 @@ module Structured
|
|
450
451
|
end
|
451
452
|
end
|
452
453
|
|
453
|
-
|
454
|
-
#
|
454
|
+
|
455
|
+
#
|
456
|
+
# Given an element value and an #element_data hash of processing tools
|
457
|
+
# element, applies those processing tools. Namely, apply any preproc, check
|
458
|
+
# the type and perform other checks, and perform any conversions. The return
|
459
|
+
# value should be usable as the received value for the corresponding
|
460
|
+
# element.
|
455
461
|
#
|
456
|
-
#
|
462
|
+
# If this method returns nil, then there is no element to process. This
|
463
|
+
# method may also raise an InputError.
|
464
|
+
#
|
465
|
+
def process_value(obj, val, data)
|
466
|
+
val, ret = process_nil_val(val, data)
|
467
|
+
return val if ret
|
468
|
+
if data[:preproc]
|
469
|
+
val = try_run(data[:preproc], obj, val, "preproc")
|
470
|
+
val, ret = process_nil_val(val, data)
|
471
|
+
return val if ret
|
472
|
+
end
|
473
|
+
|
474
|
+
cval = convert_item(val, data[:type], obj)
|
475
|
+
if data[:check] && !try_run(data[:check], obj, cval, "check")
|
476
|
+
input_err "Value #{cval} failed check"
|
477
|
+
end
|
478
|
+
return cval
|
479
|
+
end
|
480
|
+
|
481
|
+
#
|
482
|
+
# Performs processing of an element value to deal with the possibility that
|
483
|
+
# the value is nil. This method returns [ the new value, boolean of whether
|
484
|
+
# to stop processing ] according to the following rules:
|
485
|
+
#
|
486
|
+
# * If val is non-nil, then this method returns val itself, and processing
|
487
|
+
# should not stop.
|
457
488
|
# * If val is nil and this element is non-optional, then this method raises
|
458
489
|
# an error.
|
459
|
-
# * If val is nil and the element is optional,
|
460
|
-
#
|
461
|
-
#
|
462
|
-
#
|
463
|
-
#
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
return true
|
490
|
+
# * If val is nil and the element is optional, then the object's default
|
491
|
+
# value is returned, and processing should stop.
|
492
|
+
# * If there is no default value for an optional element, then nil is
|
493
|
+
# returned, and processing should also stop.
|
494
|
+
#
|
495
|
+
def process_nil_val(val, data)
|
496
|
+
return [ val, false ] if val
|
497
|
+
unless data[:optional]
|
498
|
+
input_err("Required element is missing (or was deleted by a preproc)")
|
499
|
+
end
|
500
|
+
return [ data[:default], true ]
|
471
501
|
end
|
472
502
|
|
473
503
|
# Applies a value to an element for an object, after all processing for the
|
@@ -542,12 +572,22 @@ module Structured
|
|
542
572
|
end
|
543
573
|
end
|
544
574
|
|
575
|
+
#
|
576
|
+
# Several types can be automatically converted:
|
577
|
+
#
|
578
|
+
# * Symbol into String
|
579
|
+
# * String into Regexp
|
580
|
+
#
|
545
581
|
def try_autoconvert(type, item)
|
546
582
|
|
547
583
|
if type == String && item.is_a?(Symbol)
|
548
584
|
return item.to_s
|
549
585
|
end
|
550
586
|
|
587
|
+
if type == Symbol && item.is_a?(String)
|
588
|
+
return item.to_sym
|
589
|
+
end
|
590
|
+
|
551
591
|
# Special case in which strings will be converted to Regexps
|
552
592
|
if type == Regexp && item.is_a?(String)
|
553
593
|
begin
|
@@ -563,7 +603,11 @@ module Structured
|
|
563
603
|
# Receive hash values that are to be converted to Structured objects
|
564
604
|
def convert_structured(item, type, parent)
|
565
605
|
unless item.is_a?(Hash)
|
566
|
-
|
606
|
+
if type.include?(Structured)
|
607
|
+
input_err("#{item.inspect} not a Structured hash for #{type}")
|
608
|
+
else
|
609
|
+
input_err("#{item.inspect} not a #{type}")
|
610
|
+
end
|
567
611
|
end
|
568
612
|
|
569
613
|
unless type.include?(Structured) || type.include?(StructuredPolymorphic)
|
@@ -604,7 +648,8 @@ module Structured
|
|
604
648
|
|
605
649
|
if @default_element
|
606
650
|
io.puts(
|
607
|
-
" All other elements: #{describe_type(@
|
651
|
+
" All other elements: #{describe_type(@default_key[:type])} => " \
|
652
|
+
"#{describe_type(@default_element[:type])}"
|
608
653
|
)
|
609
654
|
if @default_element[:description]
|
610
655
|
io.puts(TextTools.line_break(
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cli-dispatcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Duan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
Library for creating command-line programs that accept commands. Also
|
@@ -26,7 +26,8 @@ files:
|
|
26
26
|
homepage: https://github.com/charlesduan/cli-dispatcher
|
27
27
|
licenses:
|
28
28
|
- MIT
|
29
|
-
metadata:
|
29
|
+
metadata:
|
30
|
+
source_code_uri: https://github.com/charlesduan/cli-dispatcher
|
30
31
|
post_install_message:
|
31
32
|
rdoc_options: []
|
32
33
|
require_paths:
|