class Apia::FieldSpec::Parser

Public Class Methods

new(string) click to toggle source
# File lib/apia/field_spec.rb, line 54
def initialize(string)
  @string = string
  @paths = Set.new
  @excludes = Set.new
  @type = :normal
  @last_word = ''
  @sections = []
end

Public Instance Methods

parse() click to toggle source
# File lib/apia/field_spec.rb, line 63
def parse
  @string.each_char do |character|
    case character
    when ','
      next if @last_word.empty?

      add_last_word

    when '['
      if @last_word.empty?
        raise FieldSpecParseError, '[ requires a word before it'
      end

      @sections << @last_word
      @paths << @sections.join('.')
      @last_word = ''

    when ']'
      if @sections.last.nil?
        raise FieldSpecParseError, 'unopened bracket closure'
      end

      add_last_word unless @last_word.empty?

      @sections.pop

    when /\s+/
      # Ignore whitespace

    when '-'
      if @last_word.empty?
        @type = :exclude
      else
        add_last_word
      end

    when 'a'..'z', '0'..'9', '_', '*'
      @last_word += character

    else
      raise FieldSpecParseError, "invalid character #{character}"
    end
  end

  unless @sections.empty?
    raise FieldSpecParseError, 'unbalanced brackets'
  end

  add_last_word

  FieldSpec.new(@paths, excludes: @excludes, parsed_string: @string)
end

Private Instance Methods

add_last_word() click to toggle source
# File lib/apia/field_spec.rb, line 118
def add_last_word
  return if @last_word.empty?

  case @type
  when :exclude
    destination = @excludes
  else
    destination = @paths
  end

  if @sections.empty?
    destination << @last_word
  else
    destination << "#{@sections.join('.')}.#{@last_word}"
  end

  @last_word = ''
  @type = :normal
end