Method: Path.parse_path_str

Defined in:
lib/path.rb

.parse_path_str(path, regex_opts = nil) ⇒ Object

Parses a path String into an Array of arrays containing matchers for key, value, and any special modifiers such as recursion.

Path.parse_path_str "/path/**/to/*=bar/../../**/last"
#=> [["path",ANY_VALUE,false],["to",ANY_VALUE,true],[/.*/,"bar",false],
#    [PARENT,ANY_VALUE,false],[PARENT,ANY_VALUE,false],
#    ["last",ANY_VALUE,true]]

Note: Path.parse_path_str will slice the original path string until it is empty.



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/path.rb', line 247

def self.parse_path_str path, regex_opts=nil
  path = path.dup
  regex_opts = parse_regex_opts! path, regex_opts

  parsed = []

  escaped   = false
  key       = ""
  value     = nil
  recur     = false
  next_item = false

  until path.empty?
    char = path.slice!(0..0)

    case char
    when DCH
      next_item = true
      char = ""

    when VCH
      value = ""
      next

    when ECH
      escaped = true
      next
    end unless escaped

    char = "#{ECH}#{char}" if escaped

    if value
      value << char
    else
      key << char
    end

    next_item = true if path.empty?

    if next_item
      next_item = false

      if key == RECUR_KEY
        key   = "*"
        recur = true
        key   = "" and next unless value || path.empty?

      elsif key == PARENT_KEY
        key = PARENT

        if recur
          key = "" and next unless value
          key = "*"
        end
      end

      # Make sure we're not trying to access /./thing
      unless key =~ /^\.?$/ && !value
        matcher = Matcher.new :key        => key,
                              :value      => value,
                              :recursive  => recur,
                              :regex_opts => regex_opts

        parsed << matcher
        yield matcher, path.empty? if block_given?
      end

      key   = ""
      value = nil
      recur = false
    end

    escaped = false
  end

  parsed
end