callable_tree 0.3.4 → 0.3.7
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/CHANGELOG.md +27 -2
- data/Gemfile.lock +2 -2
- data/README.md +47 -47
- data/examples/builder/{hooks-call.rb → hooks-caller.rb} +7 -7
- data/examples/builder/{internal-compose.rb → internal-broadcastable.rb} +3 -3
- data/examples/builder/{internal-broadcast.rb → internal-composable.rb} +3 -3
- data/examples/builder/internal-seekable.rb +93 -0
- data/examples/builder/logging.rb +126 -0
- data/examples/{hooks-call.rb → hooks-caller.rb} +8 -8
- data/examples/{internal-broadcast.rb → internal-broadcastable.rb} +6 -6
- data/examples/{internal-compose.rb → internal-composable.rb} +6 -6
- data/examples/{internal-seek.rb → internal-seekable.rb} +3 -3
- data/lib/callable_tree/node/builder.rb +18 -9
- data/lib/callable_tree/node/external/builder.rb +2 -2
- data/lib/callable_tree/node/external/verbose.rb +1 -1
- data/lib/callable_tree/node/external.rb +15 -0
- data/lib/callable_tree/node/hooks/caller.rb +110 -0
- data/lib/callable_tree/node/hooks/matcher.rb +101 -0
- data/lib/callable_tree/node/internal/builder.rb +1 -1
- data/lib/callable_tree/node/internal.rb +30 -3
- data/lib/callable_tree/node/root.rb +2 -1
- data/lib/callable_tree/node.rb +8 -0
- data/lib/callable_tree/version.rb +1 -1
- data/lib/callable_tree.rb +2 -1
- metadata +14 -12
- data/examples/builder/internal-seek.rb +0 -97
- data/lib/callable_tree/node/hooks/call.rb +0 -81
@@ -14,7 +14,13 @@ module CallableTree
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def terminater(&block)
|
17
|
-
|
17
|
+
warn 'Use CallableTree::Node::Internal::Builder#terminator instead.'
|
18
|
+
@terminator = block
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def terminator(&block)
|
23
|
+
@terminator = block
|
18
24
|
self
|
19
25
|
end
|
20
26
|
|
@@ -26,23 +32,26 @@ module CallableTree
|
|
26
32
|
def build(node_type:)
|
27
33
|
matcher = @matcher
|
28
34
|
caller = @caller
|
29
|
-
|
35
|
+
terminator = @terminator
|
30
36
|
hookable = @hookable
|
31
37
|
|
32
38
|
validate(
|
33
39
|
matcher: matcher,
|
34
40
|
caller: caller,
|
35
|
-
|
41
|
+
terminator: terminator
|
36
42
|
)
|
37
43
|
|
38
44
|
::Class
|
39
45
|
.new do
|
40
46
|
include node_type
|
41
|
-
|
47
|
+
if hookable
|
48
|
+
prepend Hooks::Matcher
|
49
|
+
prepend Hooks::Caller
|
50
|
+
end
|
42
51
|
|
43
52
|
if matcher
|
44
53
|
define_method(:match?) do |*inputs, **options|
|
45
|
-
matcher.call(*inputs, **options) do |*inputs, **options|
|
54
|
+
matcher.call(*inputs, **options, _node_: self) do |*inputs, **options|
|
46
55
|
super(*inputs, **options)
|
47
56
|
end
|
48
57
|
end
|
@@ -50,15 +59,15 @@ module CallableTree
|
|
50
59
|
|
51
60
|
if caller
|
52
61
|
define_method(:call) do |*inputs, **options|
|
53
|
-
caller.call(*inputs, **options) do |*inputs, **options|
|
62
|
+
caller.call(*inputs, **options, _node_: self) do |*inputs, **options|
|
54
63
|
super(*inputs, **options)
|
55
64
|
end
|
56
65
|
end
|
57
66
|
end
|
58
67
|
|
59
|
-
if
|
68
|
+
if terminator
|
60
69
|
define_method(:terminate?) do |output, *inputs, **options|
|
61
|
-
|
70
|
+
terminator.call(output, *inputs, **options, _node_: self) do |output, *inputs, **options|
|
62
71
|
super(output, *inputs, **options)
|
63
72
|
end
|
64
73
|
end
|
@@ -68,7 +77,7 @@ module CallableTree
|
|
68
77
|
|
69
78
|
private
|
70
79
|
|
71
|
-
def validate(matcher:, caller:,
|
80
|
+
def validate(matcher:, caller:, terminator:)
|
72
81
|
raise ::CallableTree::Error, 'Not implemented'
|
73
82
|
end
|
74
83
|
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
module CallableTree
|
4
4
|
module Node
|
5
5
|
module External
|
6
|
-
# TODO: Add :inputs
|
7
6
|
Output = Struct.new(:value, :options, :routes)
|
8
7
|
|
9
8
|
module Verbose
|
@@ -13,6 +12,7 @@ module CallableTree
|
|
13
12
|
|
14
13
|
def call(*inputs, **options)
|
15
14
|
output = super(*inputs, **options)
|
15
|
+
options.delete(:_node_)
|
16
16
|
routes = self.routes
|
17
17
|
|
18
18
|
Output.new(output, options, routes)
|
@@ -5,6 +5,13 @@ module CallableTree
|
|
5
5
|
module External
|
6
6
|
include Node
|
7
7
|
|
8
|
+
def self.included(mod)
|
9
|
+
if mod.include?(Internal)
|
10
|
+
raise ::CallableTree::Error,
|
11
|
+
"#{mod} cannot include #{self} together with #{Internal}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
8
15
|
def self.proxify(callable)
|
9
16
|
Proxy.new(callable)
|
10
17
|
end
|
@@ -41,6 +48,14 @@ module CallableTree
|
|
41
48
|
{ identity => nil }
|
42
49
|
end
|
43
50
|
|
51
|
+
def internal?
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
55
|
+
def external?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
44
59
|
private
|
45
60
|
|
46
61
|
def initialize_copy(_node)
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CallableTree
|
4
|
+
module Node
|
5
|
+
module Hooks
|
6
|
+
module Caller
|
7
|
+
def self.included(_subclass)
|
8
|
+
raise ::CallableTree::Error, "#{self} must be prepended"
|
9
|
+
end
|
10
|
+
|
11
|
+
def before_call(&block)
|
12
|
+
clone.before_call!(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def before_call!(&block)
|
16
|
+
before_caller_callbacks << block
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def around_call(&block)
|
21
|
+
clone.around_call!(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def around_call!(&block)
|
25
|
+
around_caller_callbacks << block
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def after_call(&block)
|
30
|
+
clone.after_call!(&block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def after_call!(&block)
|
34
|
+
after_caller_callbacks << block
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
alias before_caller before_call
|
39
|
+
alias before_caller! before_call!
|
40
|
+
alias around_caller around_call
|
41
|
+
alias around_caller! around_call!
|
42
|
+
alias after_caller after_call
|
43
|
+
alias after_caller! after_call!
|
44
|
+
|
45
|
+
def call(*inputs, **options)
|
46
|
+
input_head, *input_tail = inputs
|
47
|
+
|
48
|
+
input_head = before_caller_callbacks.reduce(input_head) do |input_head, callable|
|
49
|
+
callable.call(input_head, *input_tail, **options, _node_: self)
|
50
|
+
end
|
51
|
+
|
52
|
+
output =
|
53
|
+
if around_caller_callbacks.empty?
|
54
|
+
super(input_head, *input_tail, **options)
|
55
|
+
else
|
56
|
+
around_caller_callbacks_head, *around_caller_callbacks_tail = around_caller_callbacks
|
57
|
+
caller = proc { super(input_head, *input_tail, **options) }
|
58
|
+
|
59
|
+
output =
|
60
|
+
around_caller_callbacks_head
|
61
|
+
.call(
|
62
|
+
input_head,
|
63
|
+
*input_tail,
|
64
|
+
**options,
|
65
|
+
_node_: self
|
66
|
+
) { caller.call }
|
67
|
+
|
68
|
+
around_caller_callbacks_tail.reduce(output) do |output, callable|
|
69
|
+
callable.call(
|
70
|
+
input_head,
|
71
|
+
*input_tail,
|
72
|
+
**options,
|
73
|
+
_node_: self
|
74
|
+
) { output }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
after_caller_callbacks.reduce(output) do |output, callable|
|
79
|
+
callable.call(output, **options, _node_: self)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def before_caller_callbacks
|
84
|
+
@before_caller_callbacks ||= []
|
85
|
+
end
|
86
|
+
|
87
|
+
def around_caller_callbacks
|
88
|
+
@around_caller_callbacks ||= []
|
89
|
+
end
|
90
|
+
|
91
|
+
def after_caller_callbacks
|
92
|
+
@after_caller_callbacks ||= []
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
attr_writer :before_caller_callbacks, :around_caller_callbacks, :after_caller_callbacks
|
98
|
+
|
99
|
+
def initialize_copy(_node)
|
100
|
+
super
|
101
|
+
self.before_caller_callbacks = before_caller_callbacks.map(&:itself)
|
102
|
+
self.around_caller_callbacks = around_caller_callbacks.map(&:itself)
|
103
|
+
self.after_caller_callbacks = after_caller_callbacks.map(&:itself)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
Call = Caller # backward compatibility
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CallableTree
|
4
|
+
module Node
|
5
|
+
module Hooks
|
6
|
+
module Matcher
|
7
|
+
def self.included(_subclass)
|
8
|
+
raise ::CallableTree::Error, "#{self} must be prepended"
|
9
|
+
end
|
10
|
+
|
11
|
+
def before_matcher(&block)
|
12
|
+
clone.before_matcher!(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def before_matcher!(&block)
|
16
|
+
before_matcher_callbacks << block
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def around_matcher(&block)
|
21
|
+
clone.around_matcher!(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def around_matcher!(&block)
|
25
|
+
around_matcher_callbacks << block
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def after_matcher(&block)
|
30
|
+
clone.after_matcher!(&block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def after_matcher!(&block)
|
34
|
+
after_matcher_callbacks << block
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def match?(*inputs, **options)
|
39
|
+
input_head, *input_tail = inputs
|
40
|
+
|
41
|
+
input_head = before_matcher_callbacks.reduce(input_head) do |input_head, callable|
|
42
|
+
callable.call(input_head, *input_tail, **options, _node_: self)
|
43
|
+
end
|
44
|
+
|
45
|
+
matched =
|
46
|
+
if around_matcher_callbacks.empty?
|
47
|
+
super(input_head, *input_tail, **options)
|
48
|
+
else
|
49
|
+
around_matcher_callbacks_head, *around_matcher_callbacks_tail = around_matcher_callbacks
|
50
|
+
matcher = proc { super(input_head, *input_tail, **options) }
|
51
|
+
|
52
|
+
matched =
|
53
|
+
around_matcher_callbacks_head
|
54
|
+
.call(
|
55
|
+
input_head,
|
56
|
+
*input_tail,
|
57
|
+
**options,
|
58
|
+
_node_: self
|
59
|
+
) { matcher.call }
|
60
|
+
|
61
|
+
around_matcher_callbacks_tail.reduce(matched) do |matched, callable|
|
62
|
+
callable.call(
|
63
|
+
input_head,
|
64
|
+
*input_tail,
|
65
|
+
**options,
|
66
|
+
_node_: self
|
67
|
+
) { matched }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
after_matcher_callbacks.reduce(matched) do |matched, callable|
|
72
|
+
callable.call(matched, **options, _node_: self)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def before_matcher_callbacks
|
77
|
+
@before_matcher_callbacks ||= []
|
78
|
+
end
|
79
|
+
|
80
|
+
def around_matcher_callbacks
|
81
|
+
@around_matcher_callbacks ||= []
|
82
|
+
end
|
83
|
+
|
84
|
+
def after_matcher_callbacks
|
85
|
+
@after_matcher_callbacks ||= []
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
attr_writer :before_matcher_callbacks, :around_matcher_callbacks, :after_matcher_callbacks
|
91
|
+
|
92
|
+
def initialize_copy(_node)
|
93
|
+
super
|
94
|
+
self.before_matcher_callbacks = before_matcher_callbacks.map(&:itself)
|
95
|
+
self.around_matcher_callbacks = around_matcher_callbacks.map(&:itself)
|
96
|
+
self.after_matcher_callbacks = after_matcher_callbacks.map(&:itself)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -6,6 +6,13 @@ module CallableTree
|
|
6
6
|
extend ::Forwardable
|
7
7
|
include Node
|
8
8
|
|
9
|
+
def self.included(mod)
|
10
|
+
if mod.include?(External)
|
11
|
+
raise ::CallableTree::Error,
|
12
|
+
"#{mod} cannot include #{self} together with #{External}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
9
16
|
def_delegators :child_nodes, :[], :at
|
10
17
|
|
11
18
|
def children
|
@@ -35,7 +42,7 @@ module CallableTree
|
|
35
42
|
if recursive
|
36
43
|
child_nodes
|
37
44
|
.lazy
|
38
|
-
.select { |node| node.
|
45
|
+
.select { |node| node.internal? }
|
39
46
|
.map { |node| node.find(recursive: true, &block) }
|
40
47
|
.reject(&:nil?)
|
41
48
|
.first
|
@@ -51,7 +58,7 @@ module CallableTree
|
|
51
58
|
|
52
59
|
if recursive
|
53
60
|
child_nodes.each do |node|
|
54
|
-
node.reject!(recursive: true, &block) if node.
|
61
|
+
node.reject!(recursive: true, &block) if node.internal?
|
55
62
|
end
|
56
63
|
end
|
57
64
|
|
@@ -66,7 +73,7 @@ module CallableTree
|
|
66
73
|
reject!(&block) if block_given?
|
67
74
|
|
68
75
|
reject! do |node|
|
69
|
-
node.
|
76
|
+
node.internal? && node.shake!(&block).child_nodes.empty?
|
70
77
|
end
|
71
78
|
end
|
72
79
|
|
@@ -98,6 +105,10 @@ module CallableTree
|
|
98
105
|
end
|
99
106
|
end
|
100
107
|
|
108
|
+
alias seekable? seek?
|
109
|
+
alias seekable seek
|
110
|
+
alias seekable! seek!
|
111
|
+
|
101
112
|
def broadcast?
|
102
113
|
strategy.is_a?(Strategy::Broadcast)
|
103
114
|
end
|
@@ -118,6 +129,10 @@ module CallableTree
|
|
118
129
|
end
|
119
130
|
end
|
120
131
|
|
132
|
+
alias broadcastable? broadcast?
|
133
|
+
alias broadcastable broadcast
|
134
|
+
alias broadcastable! broadcast!
|
135
|
+
|
121
136
|
def compose?
|
122
137
|
strategy.is_a?(Strategy::Compose)
|
123
138
|
end
|
@@ -138,12 +153,24 @@ module CallableTree
|
|
138
153
|
end
|
139
154
|
end
|
140
155
|
|
156
|
+
alias composable? compose?
|
157
|
+
alias composable compose
|
158
|
+
alias composable! compose!
|
159
|
+
|
141
160
|
def outline(&block)
|
142
161
|
key = block ? block.call(self) : identity
|
143
162
|
value = child_nodes.reduce({}) { |memo, node| memo.merge!(node.outline(&block)) }
|
144
163
|
{ key => value }
|
145
164
|
end
|
146
165
|
|
166
|
+
def internal?
|
167
|
+
true
|
168
|
+
end
|
169
|
+
|
170
|
+
def external?
|
171
|
+
false
|
172
|
+
end
|
173
|
+
|
147
174
|
protected
|
148
175
|
|
149
176
|
attr_writer :strategy
|
data/lib/callable_tree/node.rb
CHANGED
data/lib/callable_tree.rb
CHANGED
@@ -7,7 +7,8 @@ end
|
|
7
7
|
require 'forwardable'
|
8
8
|
require_relative 'callable_tree/version'
|
9
9
|
require_relative 'callable_tree/node'
|
10
|
-
require_relative 'callable_tree/node/hooks/
|
10
|
+
require_relative 'callable_tree/node/hooks/matcher'
|
11
|
+
require_relative 'callable_tree/node/hooks/caller'
|
11
12
|
require_relative 'callable_tree/node/internal/strategy'
|
12
13
|
require_relative 'callable_tree/node/internal/strategy/broadcast'
|
13
14
|
require_relative 'callable_tree/node/internal/strategy/seek'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: callable_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jsmmr
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Builds a tree by linking callable nodes. The nodes that match the conditions
|
14
14
|
are called in a chain from the root node to the leaf node. These are like nested
|
@@ -33,20 +33,21 @@ files:
|
|
33
33
|
- bin/console
|
34
34
|
- bin/setup
|
35
35
|
- callable_tree.gemspec
|
36
|
-
- examples/builder/hooks-
|
37
|
-
- examples/builder/internal-
|
38
|
-
- examples/builder/internal-
|
39
|
-
- examples/builder/internal-
|
36
|
+
- examples/builder/hooks-caller.rb
|
37
|
+
- examples/builder/internal-broadcastable.rb
|
38
|
+
- examples/builder/internal-composable.rb
|
39
|
+
- examples/builder/internal-seekable.rb
|
40
|
+
- examples/builder/logging.rb
|
40
41
|
- examples/docs/animals.json
|
41
42
|
- examples/docs/animals.xml
|
42
43
|
- examples/docs/fruits.json
|
43
44
|
- examples/docs/fruits.xml
|
44
45
|
- examples/external-verbosify.rb
|
45
|
-
- examples/hooks-
|
46
|
+
- examples/hooks-caller.rb
|
46
47
|
- examples/identity.rb
|
47
|
-
- examples/internal-
|
48
|
-
- examples/internal-
|
49
|
-
- examples/internal-
|
48
|
+
- examples/internal-broadcastable.rb
|
49
|
+
- examples/internal-composable.rb
|
50
|
+
- examples/internal-seekable.rb
|
50
51
|
- examples/logging.rb
|
51
52
|
- lib/callable_tree.rb
|
52
53
|
- lib/callable_tree/node.rb
|
@@ -54,7 +55,8 @@ files:
|
|
54
55
|
- lib/callable_tree/node/external.rb
|
55
56
|
- lib/callable_tree/node/external/builder.rb
|
56
57
|
- lib/callable_tree/node/external/verbose.rb
|
57
|
-
- lib/callable_tree/node/hooks/
|
58
|
+
- lib/callable_tree/node/hooks/caller.rb
|
59
|
+
- lib/callable_tree/node/hooks/matcher.rb
|
58
60
|
- lib/callable_tree/node/internal.rb
|
59
61
|
- lib/callable_tree/node/internal/builder.rb
|
60
62
|
- lib/callable_tree/node/internal/strategy.rb
|
@@ -69,7 +71,7 @@ licenses:
|
|
69
71
|
metadata:
|
70
72
|
homepage_uri: https://github.com/jsmmr/ruby_callable_tree
|
71
73
|
source_code_uri: https://github.com/jsmmr/ruby_callable_tree
|
72
|
-
changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.
|
74
|
+
changelog_uri: https://github.com/jsmmr/ruby_callable_tree/blob/v0.3.7/CHANGELOG.md
|
73
75
|
post_install_message:
|
74
76
|
rdoc_options: []
|
75
77
|
require_paths:
|
@@ -1,97 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'callable_tree'
|
4
|
-
require 'json'
|
5
|
-
require 'rexml/document'
|
6
|
-
|
7
|
-
module JSONParser
|
8
|
-
def self.build
|
9
|
-
CallableTree::Node::Internal::Builder
|
10
|
-
.new
|
11
|
-
.matcher do |input, **_options|
|
12
|
-
File.extname(input) == '.json'
|
13
|
-
end
|
14
|
-
.caller do |input, **options, &block|
|
15
|
-
File.open(input) do |file|
|
16
|
-
json = ::JSON.load(file)
|
17
|
-
# The following block call is equivalent to calling `super` in the class style.
|
18
|
-
block.call(json, **options)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
.terminater do
|
22
|
-
true
|
23
|
-
end
|
24
|
-
.build
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
module XMLParser
|
29
|
-
def self.build
|
30
|
-
CallableTree::Node::Internal::Builder
|
31
|
-
.new
|
32
|
-
.matcher do |input, **_options|
|
33
|
-
File.extname(input) == '.xml'
|
34
|
-
end
|
35
|
-
.caller do |input, **options, &block|
|
36
|
-
File.open(input) do |file|
|
37
|
-
# The following block call is equivalent to calling `super` in the class style.
|
38
|
-
block.call(REXML::Document.new(file), **options)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
.terminater do
|
42
|
-
true
|
43
|
-
end
|
44
|
-
.build
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
module JSONScraper
|
49
|
-
def self.build(type)
|
50
|
-
CallableTree::Node::External::Builder
|
51
|
-
.new
|
52
|
-
.matcher do |input, **_options|
|
53
|
-
!!input[type.to_s]
|
54
|
-
end
|
55
|
-
.caller do |input, **_options|
|
56
|
-
input[type.to_s]
|
57
|
-
.map { |element| [element['name'], element['emoji']] }
|
58
|
-
.to_h
|
59
|
-
end
|
60
|
-
.build
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
module XMLScraper
|
65
|
-
def self.build(type)
|
66
|
-
CallableTree::Node::External::Builder
|
67
|
-
.new
|
68
|
-
.matcher do |input, **_options|
|
69
|
-
!input.get_elements("//#{type}").empty?
|
70
|
-
end
|
71
|
-
.caller do |input, **_options|
|
72
|
-
input
|
73
|
-
.get_elements("//#{type}")
|
74
|
-
.first
|
75
|
-
.map { |element| [element['name'], element['emoji']] }
|
76
|
-
.to_h
|
77
|
-
end
|
78
|
-
.build
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
tree = CallableTree::Node::Root.new.append(
|
83
|
-
JSONParser.build.new.append(
|
84
|
-
JSONScraper.build(:animals).new,
|
85
|
-
JSONScraper.build(:fruits).new
|
86
|
-
),
|
87
|
-
XMLParser.build.new.append(
|
88
|
-
XMLScraper.build(:animals).new,
|
89
|
-
XMLScraper.build(:fruits).new
|
90
|
-
)
|
91
|
-
)
|
92
|
-
|
93
|
-
Dir.glob("#{__dir__}/../docs/*") do |file|
|
94
|
-
options = { foo: :bar }
|
95
|
-
pp tree.call(file, **options)
|
96
|
-
puts '---'
|
97
|
-
end
|