Module: LazyGraph::PathParser
- Defined in:
- lib/lazy_graph/path_parser.rb,
lib/lazy_graph/path_parser/path.rb,
lib/lazy_graph/path_parser/path_part.rb,
lib/lazy_graph/path_parser/path_group.rb
Defined Under Namespace
Classes: Path, PathGroup, PathPart
Constant Summary
collapse
- INDEX_REGEXP =
/\A-?\d+\z/
Class Method Summary
collapse
-
.append_parsed(parsed, parts) ⇒ Object
-
.find_matching_bracket(path, start) ⇒ Object
-
.handle_char(char, path, structure) ⇒ Object
-
.handle_close_bracket(structure) ⇒ Object
-
.handle_comma(structure) ⇒ Object
-
.handle_dot(path, structure) ⇒ Object
-
.handle_open_bracket(path, structure) ⇒ Object
-
.handle_range_dot(path, structure) ⇒ Object
-
.handle_single_dot(structure) ⇒ Object
-
.parse(path, strip_root: false) ⇒ Object
This module is responsible for parsing complex path strings into structured components.
-
.parse_buffer(buffer) ⇒ Object
-
.parse_finalize(structure) ⇒ Object
-
.parse_main_loop(path, parse_structure) ⇒ Object
-
.parse_range(buffer, delimiter, exclude_end) ⇒ Object
-
.parse_recursive(path, start) ⇒ Object
Recursively parses the path starting from index ‘start’ Returns [Path object, new_index].
-
.split_by_comma(str) ⇒ Object
Class Method Details
.append_parsed(parsed, parts) ⇒ Object
96
97
98
99
100
101
102
103
104
|
# File 'lib/lazy_graph/path_parser.rb', line 96
def append_parsed(parsed, parts)
if parsed.is_a?(Array)
parsed.each { |p| parts << p }
elsif parsed.is_a?(Range)
parts << PathGroup.new(options: parsed.map { |p| Path.new(parts: [PathPart.new(part: p.to_sym)]) })
else
parts << parsed
end
end
|
.find_matching_bracket(path, start) ⇒ Object
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/lazy_graph/path_parser.rb', line 148
def find_matching_bracket(path, start)
depth = 1
i = start + 1
while i < path.length
if path[i] == '['
depth += 1
elsif path[i] == ']'
depth -= 1
return i if depth.zero?
end
i += 1
end
-1 end
|
.handle_char(char, path, structure) ⇒ Object
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/lazy_graph/path_parser.rb', line 52
def handle_char(char, path, structure)
case char
when '.'
handle_dot(path, structure)
when '['
handle_open_bracket(path, structure)
when ','
handle_comma(structure)
when ']'
handle_close_bracket(structure)
else
structure[:buffer] += char
structure[:i] += 1
end
end
|
.handle_close_bracket(structure) ⇒ Object
133
134
135
136
137
138
139
|
# File 'lib/lazy_graph/path_parser.rb', line 133
def handle_close_bracket(structure)
raise 'Unbalanced closing bracket in path.' if structure[:buffer].strip.empty?
parsed = parse_buffer(structure[:buffer].strip)
append_parsed(parsed, structure[:parts])
structure[:buffer] = ''.dup
end
|
.handle_comma(structure) ⇒ Object
124
125
126
127
128
129
130
131
|
# File 'lib/lazy_graph/path_parser.rb', line 124
def handle_comma(structure)
unless structure[:buffer].strip.empty?
parsed = parse_buffer(structure[:buffer].strip)
append_parsed(parsed, structure[:parts])
structure[:buffer] = ''.dup
end
structure[:i] += 1
end
|
.handle_dot(path, structure) ⇒ Object
68
69
70
71
72
73
74
75
|
# File 'lib/lazy_graph/path_parser.rb', line 68
def handle_dot(path, structure)
if path[structure[:i] + 1] == '.'
handle_range_dot(path, structure)
else
handle_single_dot(structure)
end
end
|
.handle_open_bracket(path, structure) ⇒ Object
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/lazy_graph/path_parser.rb', line 106
def handle_open_bracket(path, structure)
unless structure[:buffer].strip.empty?
paths = structure[:buffer].strip.split('.').map(&:strip)
paths.each { |p| structure[:parts] << PathPart.new(part: p.to_sym) }
structure[:buffer] = ''.dup
end
closing_bracket = find_matching_bracket(path, structure[:i])
raise 'Unbalanced brackets in path.' if closing_bracket == -1
inside = path[(structure[:i] + 1)...closing_bracket]
elements = split_by_comma(inside)
parsed_elements = elements.map { |el| parse_recursive(el, 0) }
path_group = PathGroup.new(options: parsed_elements)
structure[:parts] << path_group
structure[:i] = closing_bracket + 1
end
|
.handle_range_dot(path, structure) ⇒ Object
77
78
79
80
81
82
83
84
85
|
# File 'lib/lazy_graph/path_parser.rb', line 77
def handle_range_dot(path, structure)
if path[structure[:i] + 2] == '.'
structure[:buffer] += '...'
structure[:i] += 3
else
structure[:buffer] += '..'
structure[:i] += 2
end
end
|
.handle_single_dot(structure) ⇒ Object
87
88
89
90
91
92
93
94
|
# File 'lib/lazy_graph/path_parser.rb', line 87
def handle_single_dot(structure)
unless structure[:buffer].strip.empty?
parsed = parse_buffer(structure[:buffer].strip)
append_parsed(parsed, structure[:parts])
structure[:buffer] = ''.dup
end
structure[:i] += 1
end
|
.parse(path, strip_root: false) ⇒ Object
This module is responsible for parsing complex path strings into structured components. Public class method to parse the path string
22
23
24
25
26
27
|
# File 'lib/lazy_graph/path_parser.rb', line 22
def self.parse(path, strip_root: false)
return Path::BLANK if path.nil? || path.empty?
start = strip_root && path.to_s.start_with?('$.') ? 2 : 0
parse_recursive(path, start)
end
|
.parse_buffer(buffer) ⇒ Object
190
191
192
193
194
195
196
197
198
199
200
201
|
# File 'lib/lazy_graph/path_parser.rb', line 190
def parse_buffer(buffer)
if buffer.include?('...')
parse_range(buffer, '...', true)
elsif buffer.include?('..')
parse_range(buffer, '..', false)
elsif buffer.include?('.')
paths = buffer.split('.').map(&:strip)
paths.map { |p| PathPart.new(part: p.to_sym) }
else
PathPart.new(part: buffer.to_sym)
end
end
|
.parse_finalize(structure) ⇒ Object
141
142
143
144
145
146
|
# File 'lib/lazy_graph/path_parser.rb', line 141
def parse_finalize(structure)
return if structure[:buffer].strip.empty?
parsed = parse_buffer(structure[:buffer].strip)
append_parsed(parsed, structure[:parts])
end
|
.parse_main_loop(path, parse_structure) ⇒ Object
45
46
47
48
49
50
|
# File 'lib/lazy_graph/path_parser.rb', line 45
def parse_main_loop(path, parse_structure)
while parse_structure[:i] < path.length
char = path[parse_structure[:i]]
handle_char(char, path, parse_structure)
end
end
|
.parse_range(buffer, delimiter, exclude_end) ⇒ Object
203
204
205
206
207
208
|
# File 'lib/lazy_graph/path_parser.rb', line 203
def parse_range(buffer, delimiter, exclude_end)
parts = buffer.split(delimiter)
return buffer unless parts.size == 2
Range.new(parts[0].strip, parts[1].strip, exclude_end)
end
|
.parse_recursive(path, start) ⇒ Object
Recursively parses the path starting from index ‘start’ Returns [Path object, new_index]
32
33
34
35
36
37
38
39
40
41
42
43
|
# File 'lib/lazy_graph/path_parser.rb', line 32
def parse_recursive(path, start)
parse_structure = {
parts: [],
buffer: ''.dup,
i: start
}
parse_main_loop(path, parse_structure)
parse_finalize(parse_structure)
Path.new(parts: parse_structure[:parts])
end
|
.split_by_comma(str) ⇒ Object
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
# File 'lib/lazy_graph/path_parser.rb', line 163
def split_by_comma(str)
elements = []
buffer = ''.dup
depth = 0
str.each_char do |c|
case c
when '['
depth += 1
buffer << c
when ']'
depth -= 1
buffer << c
when ','
if depth.zero?
elements << buffer.strip
buffer = ''.dup
else
buffer << c
end
else
buffer << c
end
end
elements << buffer.strip unless buffer.strip.empty?
elements
end
|