nrser 0.0.30 → 0.1.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/nrser.rb +56 -12
- data/lib/nrser/collection.rb +4 -7
- data/lib/nrser/ext.rb +5 -0
- data/lib/nrser/{refinements → ext}/enumerable.rb +11 -9
- data/lib/nrser/ext/pathname.rb +74 -0
- data/lib/nrser/{refinements → ext}/tree.rb +2 -26
- data/lib/nrser/functions.rb +18 -0
- data/lib/nrser/{array.rb → functions/array.rb} +2 -3
- data/lib/nrser/{binding.rb → functions/binding.rb} +0 -2
- data/lib/nrser/functions/enumerable.rb +355 -0
- data/lib/nrser/functions/enumerable/find_all_map.rb +33 -0
- data/lib/nrser/functions/enumerable/find_map.rb +53 -0
- data/lib/nrser/functions/exception.rb +17 -0
- data/lib/nrser/{hash.rb → functions/hash.rb} +0 -0
- data/lib/nrser/functions/hash/bury.rb +147 -0
- data/lib/nrser/{hash → functions/hash}/deep_merge.rb +5 -5
- data/lib/nrser/{hash → functions/hash}/except_keys.rb +2 -0
- data/lib/nrser/{hash → functions/hash}/guess_label_key_type.rb +3 -1
- data/lib/nrser/{hash → functions/hash}/slice_keys.rb +3 -1
- data/lib/nrser/{hash → functions/hash}/stringify_keys.rb +2 -0
- data/lib/nrser/{hash → functions/hash}/symbolize_keys.rb +3 -1
- data/lib/nrser/{hash → functions/hash}/transform_keys.rb +3 -1
- data/lib/nrser/functions/merge_by.rb +29 -0
- data/lib/nrser/{object.rb → functions/object.rb} +0 -0
- data/lib/nrser/{object → functions/object}/as_array.rb +2 -0
- data/lib/nrser/{object → functions/object}/as_hash.rb +7 -5
- data/lib/nrser/{object → functions/object}/truthy.rb +46 -7
- data/lib/nrser/{open_struct.rb → functions/open_struct.rb} +0 -0
- data/lib/nrser/functions/path.rb +150 -0
- data/lib/nrser/{proc.rb → functions/proc.rb} +1 -22
- data/lib/nrser/functions/string.rb +297 -0
- data/lib/nrser/functions/string/looks_like.rb +44 -0
- data/lib/nrser/{text.rb → functions/text.rb} +0 -0
- data/lib/nrser/{text → functions/text}/indentation.rb +2 -16
- data/lib/nrser/{text → functions/text}/lines.rb +1 -2
- data/lib/nrser/{text → functions/text}/word_wrap.rb +2 -4
- data/lib/nrser/{tree.rb → functions/tree.rb} +0 -0
- data/lib/nrser/{tree → functions/tree}/each_branch.rb +6 -7
- data/lib/nrser/functions/tree/leaves.rb +92 -0
- data/lib/nrser/{tree → functions/tree}/map_branches.rb +31 -32
- data/lib/nrser/functions/tree/map_leaves.rb +56 -0
- data/lib/nrser/{tree → functions/tree}/map_tree.rb +9 -20
- data/lib/nrser/{tree → functions/tree}/transform.rb +0 -10
- data/lib/nrser/logger.rb +9 -10
- data/lib/nrser/message.rb +3 -7
- data/lib/nrser/meta.rb +2 -0
- data/lib/nrser/meta/class_attrs.rb +3 -9
- data/lib/nrser/meta/props.rb +19 -19
- data/lib/nrser/meta/props/base.rb +4 -10
- data/lib/nrser/meta/props/prop.rb +12 -28
- data/lib/nrser/no_arg.rb +1 -3
- data/lib/nrser/refinements.rb +5 -0
- data/lib/nrser/refinements/array.rb +5 -17
- data/lib/nrser/refinements/enumerator.rb +1 -3
- data/lib/nrser/refinements/hash.rb +3 -15
- data/lib/nrser/refinements/object.rb +2 -2
- data/lib/nrser/refinements/open_struct.rb +0 -2
- data/lib/nrser/refinements/pathname.rb +3 -46
- data/lib/nrser/refinements/set.rb +2 -6
- data/lib/nrser/refinements/string.rb +2 -2
- data/lib/nrser/rspex.rb +16 -13
- data/lib/nrser/types.rb +6 -20
- data/lib/nrser/types/any.rb +0 -1
- data/lib/nrser/types/booleans.rb +1 -1
- data/lib/nrser/types/combinators.rb +5 -5
- data/lib/nrser/types/in.rb +0 -21
- data/lib/nrser/types/responds.rb +1 -0
- data/lib/nrser/types/trees.rb +1 -0
- data/lib/nrser/version.rb +2 -3
- data/spec/nrser/{template_spec.rb → functions/binding/template_spec.rb} +0 -0
- data/spec/nrser/functions/enumerable/find_all_map_spec.rb +28 -0
- data/spec/nrser/functions/enumerable/find_bounded_spec.rb +70 -0
- data/spec/nrser/functions/enumerable/find_map_spec.rb +38 -0
- data/spec/nrser/functions/enumerable/find_only_spec.rb +25 -0
- data/spec/nrser/functions/enumerable/to_h_by_spec.rb +28 -0
- data/spec/nrser/{format_exception_spec.rb → functions/exception/format_exception_spec.rb} +0 -0
- data/spec/nrser/{hash → functions/hash}/bury_spec.rb +0 -0
- data/spec/nrser/{hash → functions/hash}/guess_label_key_type_spec.rb +0 -0
- data/spec/nrser/{hash_spec.rb → functions/hash_spec.rb} +0 -7
- data/spec/nrser/{merge_by_spec.rb → functions/merge_by_spec.rb} +0 -0
- data/spec/nrser/{truthy_spec.rb → functions/object/truthy_spec.rb} +0 -0
- data/spec/nrser/{open_struct_spec.rb → functions/open_struct_spec.rb} +0 -0
- data/spec/nrser/{string → functions/string}/common_prefix_spec.rb +0 -0
- data/spec/nrser/{string → functions/string}/looks_like_spec.rb +0 -0
- data/spec/nrser/{truncate_spec.rb → functions/string/truncate_spec.rb} +0 -0
- data/spec/nrser/{text → functions/text}/dedent/gotchas_spec.rb +0 -0
- data/spec/nrser/{text → functions/text}/dedent_spec.rb +0 -0
- data/spec/nrser/{indent_spec.rb → functions/text/indent_spec.rb} +0 -0
- data/spec/nrser/{tree → functions/tree}/each_branch_spec.rb +0 -0
- data/spec/nrser/{tree → functions/tree}/leaves_spec.rb +0 -0
- data/spec/nrser/{tree → functions/tree}/map_branch_spec.rb +0 -0
- data/spec/nrser/{tree → functions/tree}/map_tree_spec.rb +0 -0
- data/spec/nrser/{tree → functions/tree}/transform_spec.rb +0 -0
- data/spec/nrser/{tree → functions/tree}/transformer_spec.rb +0 -0
- data/spec/nrser/meta/class_attrs_spec.rb +12 -14
- data/spec/spec_helper.rb +2 -3
- metadata +136 -110
- data/lib/nrser/enumerable.rb +0 -288
- data/lib/nrser/exception.rb +0 -7
- data/lib/nrser/hash/bury.rb +0 -154
- data/lib/nrser/merge_by.rb +0 -26
- data/lib/nrser/string.rb +0 -294
- data/lib/nrser/string/looks_like.rb +0 -51
- data/lib/nrser/tree/leaves.rb +0 -92
- data/lib/nrser/tree/map_leaves.rb +0 -63
- data/spec/nrser/enumerable_spec.rb +0 -111
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Functional methods that try to tell what format a string that
|
|
5
|
+
# is presumed to encode structural data is encoded in.
|
|
6
|
+
##
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Definitions
|
|
10
|
+
# =======================================================================
|
|
11
|
+
|
|
12
|
+
module NRSER
|
|
13
|
+
|
|
14
|
+
# @!group String Functions
|
|
15
|
+
|
|
16
|
+
# Constants
|
|
17
|
+
# =====================================================================
|
|
18
|
+
|
|
19
|
+
# Regexp used to guess if a string is a JSON-encoded array.
|
|
20
|
+
#
|
|
21
|
+
# @return [Regexp]
|
|
22
|
+
#
|
|
23
|
+
JSON_ARRAY_RE = /\A\s*\[.*\]\s*\z/m.freeze
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Functions
|
|
27
|
+
# ============================================================================
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Test if a string looks like it might encode an array in JSON format by
|
|
31
|
+
# seeing if it's first non-whitespace character is `[` and last
|
|
32
|
+
# non-whitespace character is `]`.
|
|
33
|
+
#
|
|
34
|
+
# @param [String] string
|
|
35
|
+
# String to test.
|
|
36
|
+
#
|
|
37
|
+
# @return [Boolean]
|
|
38
|
+
# `true` if we think `string` encodes a JSON array.
|
|
39
|
+
#
|
|
40
|
+
def self.looks_like_json_array? string
|
|
41
|
+
!!( string =~ JSON_ARRAY_RE )
|
|
42
|
+
end # #looks_like_json_array
|
|
43
|
+
|
|
44
|
+
end # module NRSER
|
|
File without changes
|
|
@@ -1,19 +1,5 @@
|
|
|
1
|
-
# Requirements
|
|
2
|
-
# =======================================================================
|
|
3
|
-
|
|
4
|
-
# Stdlib
|
|
5
|
-
# -----------------------------------------------------------------------
|
|
6
|
-
|
|
7
|
-
# Deps
|
|
8
|
-
# -----------------------------------------------------------------------
|
|
9
|
-
|
|
10
|
-
# Project / Package
|
|
11
|
-
# -----------------------------------------------------------------------
|
|
12
|
-
require_relative './lines'
|
|
13
|
-
|
|
14
|
-
|
|
15
1
|
module NRSER
|
|
16
|
-
# @!group Text
|
|
2
|
+
# @!group Text Functions
|
|
17
3
|
|
|
18
4
|
|
|
19
5
|
# Constants
|
|
@@ -109,7 +95,7 @@ module NRSER
|
|
|
109
95
|
# `marker` and `separator` can be configured via keyword arguments, but they
|
|
110
96
|
# default to:
|
|
111
97
|
#
|
|
112
|
-
# - `marker` - {NRSER::INDENT_TAG_MARKER}, the no-printable ASCII
|
|
98
|
+
# - `marker` - {NRSER::INDENT_TAG_MARKER}, the no-printable ASCII
|
|
113
99
|
# *record separator* (ASCII character 30, "\x1E" / "\u001E").
|
|
114
100
|
#
|
|
115
101
|
# - `separator` - {NRSER::INDENT_TAG_SEPARATOR}, the non-printable ASCII
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
1
|
module NRSER
|
|
3
|
-
# @!group Text
|
|
2
|
+
# @!group Text Functions
|
|
4
3
|
|
|
5
4
|
# Split text at whitespace to fit in line length. Lifted from Rails'
|
|
6
5
|
# ActionView.
|
|
@@ -24,6 +23,5 @@ module NRSER
|
|
|
24
23
|
line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1#{break_sequence}").strip : line
|
|
25
24
|
end * break_sequence
|
|
26
25
|
end # .word_wrap
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
|
|
29
27
|
end # module NRSER
|
|
File without changes
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
# Definitions
|
|
2
|
-
# =======================================================================
|
|
3
|
-
|
|
4
1
|
module NRSER
|
|
5
2
|
|
|
3
|
+
# @!group Tree Functions
|
|
4
|
+
|
|
6
5
|
# Enumerate over the immediate "branches" of a structure that can be used
|
|
7
6
|
# to compose our idea of a *tree*: nested hash-like and array-like structures
|
|
8
7
|
# like you would get from parsing a JSON document.
|
|
@@ -35,7 +34,7 @@ module NRSER
|
|
|
35
34
|
# `#each_with_index` call.
|
|
36
35
|
#
|
|
37
36
|
# @raise [NoMethodError]
|
|
38
|
-
# If `tree` does not respond to `#each_pair` or to `#each_index` and
|
|
37
|
+
# If `tree` does not respond to `#each_pair` or to `#each_index` and
|
|
39
38
|
# `#each_with_index`.
|
|
40
39
|
#
|
|
41
40
|
def self.each_branch tree, &block
|
|
@@ -44,13 +43,13 @@ module NRSER
|
|
|
44
43
|
tree.each_pair &block
|
|
45
44
|
|
|
46
45
|
elsif tree.respond_to? :each_index
|
|
47
|
-
# Array-like... we test for `each_index` because - unintuitively -
|
|
46
|
+
# Array-like... we test for `each_index` because - unintuitively -
|
|
48
47
|
# `#each_with_index` is a method of {Enumerable}, meaning that {Set}
|
|
49
48
|
# responds to it, though sets are unordered and the values can't be
|
|
50
|
-
# accessed via those indexes. Hence we look for `#each_index`, which
|
|
49
|
+
# accessed via those indexes. Hence we look for `#each_index`, which
|
|
51
50
|
# {Set} does not respond to.
|
|
52
51
|
|
|
53
|
-
if block.nil?
|
|
52
|
+
if block.nil?
|
|
54
53
|
index_enumerator = tree.each_with_index
|
|
55
54
|
|
|
56
55
|
Enumerator.new( index_enumerator.size ) { |yielder|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module NRSER
|
|
2
|
+
|
|
3
|
+
# @!group Tree Functions
|
|
4
|
+
|
|
5
|
+
# Create a new hash where all the values are the scalar "leaves" of the
|
|
6
|
+
# possibly nested `hash` param. Leaves are keyed by "key path" arrays
|
|
7
|
+
# representing the sequence of keys to dig that leaf out of the has param.
|
|
8
|
+
#
|
|
9
|
+
# In abstract, if `h` is the `hash` param and
|
|
10
|
+
#
|
|
11
|
+
# l = NRSER.leaves h
|
|
12
|
+
#
|
|
13
|
+
# then for each key `k` and corresponding value `v` in `l`
|
|
14
|
+
#
|
|
15
|
+
# h.dig( *k ) == v
|
|
16
|
+
#
|
|
17
|
+
# @pure
|
|
18
|
+
# Return value depends only on parameters.
|
|
19
|
+
#
|
|
20
|
+
# @example Simple "flat" hash
|
|
21
|
+
#
|
|
22
|
+
# NRSER.leaves( {a: 1, b: 2} )
|
|
23
|
+
# => {
|
|
24
|
+
# [:a] => 1,
|
|
25
|
+
# [:b] => 2,
|
|
26
|
+
# }
|
|
27
|
+
#
|
|
28
|
+
# @example Nested hash
|
|
29
|
+
#
|
|
30
|
+
# NRSER.leaves(
|
|
31
|
+
# 1 => {
|
|
32
|
+
# name: 'Neil',
|
|
33
|
+
# fav_color: 'blue',
|
|
34
|
+
# },
|
|
35
|
+
# 2 => {
|
|
36
|
+
# name: 'Mica',
|
|
37
|
+
# fav_color: 'red',
|
|
38
|
+
# }
|
|
39
|
+
# )
|
|
40
|
+
# # => {
|
|
41
|
+
# # [1, :name] => 'Neil',
|
|
42
|
+
# # [1, :fav_color] => 'blue',
|
|
43
|
+
# # [2, :name] => 'Mica',
|
|
44
|
+
# # [2, :fav_color] => 'red',
|
|
45
|
+
# # }
|
|
46
|
+
#
|
|
47
|
+
# @param [#each_pair | (#each_index & #each_with_index)] tree
|
|
48
|
+
#
|
|
49
|
+
# @return [Hash<Array, Object>]
|
|
50
|
+
#
|
|
51
|
+
def self.leaves tree
|
|
52
|
+
{}.tap { |results|
|
|
53
|
+
_internal_leaves tree, path: [], results: results
|
|
54
|
+
}
|
|
55
|
+
end # .leaves
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Internal recursive implementation for {NRSER.leaves}.
|
|
59
|
+
#
|
|
60
|
+
# @private
|
|
61
|
+
#
|
|
62
|
+
# @pure
|
|
63
|
+
# Return value depends only on parameters.
|
|
64
|
+
#
|
|
65
|
+
# @param [#each_pair | (#each_index & #each_with_index)] tree
|
|
66
|
+
# Tree to walk.
|
|
67
|
+
#
|
|
68
|
+
# @param [Array] path
|
|
69
|
+
# Key path down to `tree`.
|
|
70
|
+
#
|
|
71
|
+
# @param [Hash<Array, Object>] results
|
|
72
|
+
# New hash to stick results in.
|
|
73
|
+
#
|
|
74
|
+
# @return [nil]
|
|
75
|
+
#
|
|
76
|
+
def self._internal_leaves tree, path:, results:
|
|
77
|
+
NRSER.each_branch( tree ) { |key, value|
|
|
78
|
+
new_path = [*path, key]
|
|
79
|
+
|
|
80
|
+
if NRSER::Types.tree.test value
|
|
81
|
+
_internal_leaves value, path: new_path, results: results
|
|
82
|
+
else
|
|
83
|
+
results[new_path] = value
|
|
84
|
+
end
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
nil
|
|
88
|
+
end # ._internal_leaves
|
|
89
|
+
|
|
90
|
+
private_class_method :_internal_leaves
|
|
91
|
+
|
|
92
|
+
end # module NRSER
|
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
# Requirements
|
|
2
|
-
# =======================================================================
|
|
3
|
-
|
|
4
|
-
# Project / Package
|
|
5
|
-
# -----------------------------------------------------------------------
|
|
6
|
-
require 'nrser/types/trees'
|
|
7
|
-
|
|
8
|
-
require_relative './each_branch'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# Definitions
|
|
12
|
-
# =======================================================================
|
|
13
|
-
|
|
14
1
|
module NRSER
|
|
15
2
|
|
|
3
|
+
# @!group Tree Functions
|
|
4
|
+
|
|
16
5
|
# Map the immediate "branches" of a structure that can be used
|
|
17
6
|
# to compose our idea of a *tree*: nested hash-like and array-like structures
|
|
18
7
|
# like you would get from parsing a JSON document.
|
|
@@ -20,8 +9,8 @@ module NRSER
|
|
|
20
9
|
# The `block` **MUST** return a pair ({Array} of length 2), the first value
|
|
21
10
|
# of which is the key or index in the new {Hash} or {Array}.
|
|
22
11
|
#
|
|
23
|
-
# These pairs are then converted into a {Hash} or {Array} depending on it
|
|
24
|
-
# `tree` was {NRSER::Types.hash_like} or {NRSER::Types.array_like}, and
|
|
12
|
+
# These pairs are then converted into a {Hash} or {Array} depending on it
|
|
13
|
+
# `tree` was {NRSER::Types.hash_like} or {NRSER::Types.array_like}, and
|
|
25
14
|
# that value is returned.
|
|
26
15
|
#
|
|
27
16
|
# Uses {NRSER.each_branch} internally.
|
|
@@ -34,20 +23,20 @@ module NRSER
|
|
|
34
23
|
# 2. *array-like* that responds to `#each_index` and `#each_with_index`
|
|
35
24
|
# appropriately.
|
|
36
25
|
#
|
|
37
|
-
# @
|
|
26
|
+
# @pure
|
|
27
|
+
# Return value depends only on parameters.
|
|
28
|
+
#
|
|
29
|
+
# @note
|
|
30
|
+
# Not sure what will happen if the tree has circular references!
|
|
38
31
|
#
|
|
39
32
|
# @todo
|
|
40
33
|
# Might be nice to have an option to preserve the tree class that creates
|
|
41
|
-
# a new instance of *whatever* it was and populates that, though I could
|
|
34
|
+
# a new instance of *whatever* it was and populates that, though I could
|
|
42
35
|
# see this relying on problematic assumptions and producing confusing
|
|
43
36
|
# results depending on the actual classes.
|
|
44
37
|
#
|
|
45
38
|
# Maybe this could be encoded in a mixin that we would detect or something.
|
|
46
39
|
#
|
|
47
|
-
# @example
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
40
|
# @param [#each_pair | (#each_index & #each_with_index)] tree
|
|
52
41
|
# Structure representing a tree via hash-like and array-like containers.
|
|
53
42
|
#
|
|
@@ -65,10 +54,13 @@ module NRSER
|
|
|
65
54
|
# @return [Array | Hash]
|
|
66
55
|
# If no block is provided.
|
|
67
56
|
#
|
|
68
|
-
# @raise [NoMethodError]
|
|
69
|
-
# If `tree` does not respond to `#each_pair` or to `#each_index` and
|
|
57
|
+
# @raise [TypeError | NoMethodError]
|
|
58
|
+
# If `tree` does not respond to `#each_pair` or to `#each_index` and
|
|
70
59
|
# `#each_with_index`.
|
|
71
60
|
#
|
|
61
|
+
# @raise [ArgumentError]
|
|
62
|
+
# If `&block` is not provided.
|
|
63
|
+
#
|
|
72
64
|
def self.map_branches tree, &block
|
|
73
65
|
if block.nil?
|
|
74
66
|
raise ArgumentError, "Must provide block"
|
|
@@ -76,16 +68,23 @@ module NRSER
|
|
|
76
68
|
|
|
77
69
|
pairs = each_branch( tree ).map &block
|
|
78
70
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Types.array_like, ->( _ ) {
|
|
85
|
-
pairs.each_with_object( [] ) { |(index, value), array|
|
|
86
|
-
array[index] = value
|
|
87
|
-
}
|
|
71
|
+
if hash_like? tree
|
|
72
|
+
pairs.to_h
|
|
73
|
+
elsif array_like? tree
|
|
74
|
+
pairs.each_with_object( [] ) { |(index, value), array|
|
|
75
|
+
array[index] = value
|
|
88
76
|
}
|
|
77
|
+
else
|
|
78
|
+
raise TypeError.new erb binding, <<-END
|
|
79
|
+
Excepted `tree` arg to be array or hash-like.
|
|
80
|
+
|
|
81
|
+
Received (<%= tree.class %>):
|
|
82
|
+
|
|
83
|
+
<%= tree.pretty_inspect %>
|
|
84
|
+
|
|
85
|
+
END
|
|
86
|
+
end
|
|
87
|
+
|
|
89
88
|
end # .map_branches
|
|
90
89
|
|
|
91
90
|
end # module NRSER
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module NRSER
|
|
2
|
+
|
|
3
|
+
# @!group Tree Functions
|
|
4
|
+
|
|
5
|
+
def self.map_leaves tree, &block
|
|
6
|
+
NRSER::Types.tree.check tree
|
|
7
|
+
|
|
8
|
+
_internal_map_leaves tree, key_path: [], &block
|
|
9
|
+
end # #map_leaves
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Internal recursive implementation for {NRSER.leaves}.
|
|
13
|
+
#
|
|
14
|
+
# @param [#each_pair | (#each_index & #each_with_index)] tree
|
|
15
|
+
# Tree to walk.
|
|
16
|
+
#
|
|
17
|
+
# @param [Array] path
|
|
18
|
+
# Key path down to `tree`.
|
|
19
|
+
#
|
|
20
|
+
# @param [Hash<Array, Object>] results
|
|
21
|
+
# New hash to stick results in.
|
|
22
|
+
#
|
|
23
|
+
# @return [nil]
|
|
24
|
+
#
|
|
25
|
+
def self._internal_map_leaves tree, key_path:, &block
|
|
26
|
+
NRSER::Types.match tree,
|
|
27
|
+
NRSER::Types.hash_like, ->( hash_like ) {
|
|
28
|
+
hash_like.map { |key, value|
|
|
29
|
+
new_key_path = [*key_path, key]
|
|
30
|
+
|
|
31
|
+
new_value = if NRSER::Types.tree.test( value )
|
|
32
|
+
_internal_map_leaves value, key_path: new_key_path, &block
|
|
33
|
+
else
|
|
34
|
+
block.call new_key_path, value
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
[key, new_value]
|
|
38
|
+
}.to_h
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
NRSER::Types.array_like, ->( array_like ) {
|
|
42
|
+
array_like.each_with_index.map { |value, index|
|
|
43
|
+
new_key_path = [*key_path, index]
|
|
44
|
+
|
|
45
|
+
if NRSER::Types.tree.test( value )
|
|
46
|
+
_internal_map_leaves value, key_path: new_key_path, &block
|
|
47
|
+
else
|
|
48
|
+
block.call new_key_path, value
|
|
49
|
+
end
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
end # #_internal_leaves
|
|
53
|
+
|
|
54
|
+
private_class_method :_internal_map_leaves
|
|
55
|
+
|
|
56
|
+
end # module NRSER
|
|
@@ -1,31 +1,20 @@
|
|
|
1
|
-
# Requirements
|
|
2
|
-
# =======================================================================
|
|
3
|
-
|
|
4
|
-
# Project / Package
|
|
5
|
-
# -----------------------------------------------------------------------
|
|
6
|
-
require_relative './map_branches'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# Definitions
|
|
10
|
-
# =======================================================================
|
|
11
|
-
|
|
12
1
|
module NRSER
|
|
13
2
|
# Recursively descend through a tree mapping *all* non-structural elements
|
|
14
3
|
# - anything not {NRSER::Types.hash_like} or {NRSER::Types.array_like}, both
|
|
15
|
-
# hash keys *and* values, as well as array entries - through `block` to
|
|
4
|
+
# hash keys *and* values, as well as array entries - through `block` to
|
|
16
5
|
# produce a new structure.
|
|
17
6
|
#
|
|
18
7
|
# Useful when you want to translate pieces of a tree structure depending on
|
|
19
|
-
# their type or some other property that can be determined *from the element
|
|
20
|
-
# alone* - `block` receives only the value as an argument, no location
|
|
8
|
+
# their type or some other property that can be determined *from the element
|
|
9
|
+
# alone* - `block` receives only the value as an argument, no location
|
|
21
10
|
# information (because it's weirder to represent for keys and I didn't need
|
|
22
11
|
# it for the {NRSER.transformer} stuff this was written for).
|
|
23
12
|
#
|
|
24
13
|
# @note
|
|
25
14
|
# Array indexes **are not mapped** through `block` and can not be changed
|
|
26
|
-
# via this method. This makes it easier to do things like "convert all the
|
|
27
|
-
# integers to strings" when you mean the data entries, not the array
|
|
28
|
-
# indexes (which would fail since the new array wouldn't accept string
|
|
15
|
+
# via this method. This makes it easier to do things like "convert all the
|
|
16
|
+
# integers to strings" when you mean the data entries, not the array
|
|
17
|
+
# indexes (which would fail since the new array wouldn't accept string
|
|
29
18
|
# indices).
|
|
30
19
|
#
|
|
31
20
|
# If you don't want to map hash keys use {NRSER.map_leaves}.
|
|
@@ -40,7 +29,7 @@ module NRSER
|
|
|
40
29
|
#
|
|
41
30
|
# @yieldparam [Object] element
|
|
42
31
|
# Anything reached from the root that is not structural (hash-like or
|
|
43
|
-
# array-like), including / inside hash keys (though array
|
|
32
|
+
# array-like), including / inside hash keys (though array
|
|
44
33
|
# indexes are **not** passed).
|
|
45
34
|
#
|
|
46
35
|
def self.map_tree tree, prune: false, &block
|
|
@@ -49,7 +38,7 @@ module NRSER
|
|
|
49
38
|
mapped = tree.map { |element|
|
|
50
39
|
# Recur if `element` is a tree.
|
|
51
40
|
#
|
|
52
|
-
# Since `element` will be an {Array} of `key`, `value` when `tree` is a
|
|
41
|
+
# Since `element` will be an {Array} of `key`, `value` when `tree` is a
|
|
53
42
|
# {Hash} (or similar), this will descend into hash keys that are also
|
|
54
43
|
# trees, as well as into hash values and array entries.
|
|
55
44
|
#
|
|
@@ -61,7 +50,7 @@ module NRSER
|
|
|
61
50
|
end
|
|
62
51
|
}
|
|
63
52
|
|
|
64
|
-
# If `tree` is hash-like, we want to convert the array of pair arrays
|
|
53
|
+
# If `tree` is hash-like, we want to convert the array of pair arrays
|
|
65
54
|
# back into a hash.
|
|
66
55
|
if Types.hash_like.test tree
|
|
67
56
|
if prune
|