module Gapic::PathPattern::Parser

A path pattern parser. takes a pattern and transforms it into a collection of parsed segments @see google.aip.dev/122 @see google.aip.dev/123

Public Class Methods

capture_collection_id_segment(url_pattern) click to toggle source

Captures the first segment of the pattern as a collection id segment This is used as a catch-all, so the collection id segment can contain anything except the path separator / @private

# File lib/gapic/path_pattern/parser.rb, line 134
def self.capture_collection_id_segment url_pattern
  collection_id_regex = %r{^(?<collection_name>[^/]+?)(?:/|$)}
  match = collection_id_regex.match url_pattern

  collection_name = match[:collection_name]

  segment = CollectionIdSegment.new collection_name
  remainder = match.post_match
  [segment, remainder]
end
parse(path_pattern) click to toggle source

@param path_pattern [String] The path pattern to be parsed @return [Gapic::PathPattern::Pattern]

# File lib/gapic/path_pattern/parser.rb, line 32
def self.parse path_pattern
  remainder = path_pattern.sub(%r{^/}, "").sub(%r{/$}, "")

  segments = []
  position = 0
  until remainder.empty?
    segment, position, remainder = parse_first_segment_with_position remainder, position
    segments << segment
  end

  Pattern.new path_pattern, segments
end
parse_first_segment_with_position(url_pattern, position) click to toggle source

@private

# File lib/gapic/path_pattern/parser.rb, line 46
def self.parse_first_segment_with_position url_pattern, position
  # check for the wildcard segment -- either * or **
  # wildcard segments are positional, so the position counter is used and updated
  segment, remainder = try_capture_wildcard_segment url_pattern, position
  return [segment, position + 1, remainder] if segment

  # check for the complex resource id segment, e.g. {foo}-{bar}_{baz}
  segment, remainder = try_capture_complex_resource_id_segment url_pattern
  return [segment, position, remainder] if segment

  # check for the simple resource id segment, e.g. {foo} or {foo=some/pattern/*}
  segment, remainder = try_capture_simple_resource_id_segment url_pattern
  return [segment, position, remainder] if segment

  # if nothing else fits, it's the collection id segment
  segment, remainder = capture_collection_id_segment url_pattern
  [segment, position, remainder]
end
try_capture_complex_resource_id_segment(url_pattern) click to toggle source

Tries to capture the first segment of the pattern as a complex resource id segment The pattern for the complex resource id segments is: {<name_first>}<separator>{<name_second>} etc, e.g. {foo}-{bar}_{baz} see AIP-4231 Parsing resource names, Complex resource ID path segments @private

# File lib/gapic/path_pattern/parser.rb, line 88
def self.try_capture_complex_resource_id_segment url_pattern
  complex_resource_id_regex =
    %r/^(?<segment_pattern>{(?<name_first>[^\/}]+?)}(?:(?<separator>[_\-~.]){(?<name_seq>[^\/}]+?)})+)(?:\/|$)/

  return nil, url_pattern unless complex_resource_id_regex.match? url_pattern

  match = complex_resource_id_regex.match url_pattern
  segment_pattern = match[:segment_pattern]

  resource_name_regex = %r/{(?<name>[^\/}]+?)}/
  resource_names = segment_pattern.scan(resource_name_regex).flatten

  segment = ResourceIdSegment.new :complex_resource_id, segment_pattern, resource_names
  remainder = match.post_match
  [segment, remainder]
end
try_capture_simple_resource_id_segment(url_pattern) click to toggle source

Tries to capture the first segment of the pattern as a simple resource id segment The pattern for the simple resource id segments is: {<name>} or with an optional resource name pattern {<name>=<pattern>} e.g. {foo} or with an optional pattern, e.g. {foo=**} or {foo=bar} notably here the pattern between the = and } can contain the path separator / @private

# File lib/gapic/path_pattern/parser.rb, line 112
def self.try_capture_simple_resource_id_segment url_pattern
  simple_resource_id_regex =
    %r/^(?<segment_pattern>{(?<resource_name>[^\/}]+?)(?:=(?<resource_pattern>.+?))?})(?:\/|$)/
  return nil, url_pattern unless simple_resource_id_regex.match? url_pattern

  match = simple_resource_id_regex.match url_pattern
  segment_pattern = match[:segment_pattern]

  resource_name = match[:resource_name]
  resource_pattern = match[:resource_pattern] if match.names.include? "resource_pattern"
  resource_patterns = resource_pattern.nil? ? [] : [resource_pattern]

  segment = ResourceIdSegment.new :simple_resource_id, segment_pattern, [resource_name], resource_patterns
  remainder = match.post_match
  [segment, remainder]
end
try_capture_wildcard_segment(url_pattern, position) click to toggle source

Tries to capture the first segment of the pattern as a wildcard segment The wildcard segment can be either * or ** @private

# File lib/gapic/path_pattern/parser.rb, line 69
def self.try_capture_wildcard_segment url_pattern, position
  wildcard_capture_regex = %r{^(?<pattern>\*\*|\*)(?:/|$)}
  return nil, url_pattern unless wildcard_capture_regex.match? url_pattern

  match = wildcard_capture_regex.match url_pattern

  wildcard_pattern = match[:pattern]

  segment = PositionalSegment.new position, wildcard_pattern
  remainder = match.post_match
  [segment, remainder]
end