module QueryStringSearch
  class SearchOption
    attr_reader :attribute, :desired_value, :operator

    def initialize(raw_query)
      parsed_query = /(?<attribute>\w+)(?<operator>\W+)(?<value>.+)/.match(raw_query)
      if parsed_query
        self.attribute     = parsed_query[:attribute]
        self.desired_value = parsed_query[:value]
        self.operator      = parsed_query[:operator]
      end
    end

    def attribute
      @attribute ? @attribute.to_sym : nil
    end

    private

    attr_writer :attribute, :desired_value, :operator
  end
end

module QueryStringSearch
  class SearchOption
    attr_reader :attribute, :desired_value, :operator

    def initialize(raw_query)
      parsed_query       = KeyValue.parse(raw_query)
      self.attribute     = parsed_query.attribute
      self.desired_value = parsed_query.desired_value
      self.operator      = parsed_query.operator
    end

    def attribute
      @attribute ? @attribute.to_sym : nil
    end

    private

    attr_writer :attribute, :desired_value, :operator
  end

  class KeyValue
    attr_accessor :attribute, :desired_value, :operator

    def self.parse(raw_query)
      new(/(?<attribute>\w+)(?<operator>\W+)(?<desired_value>.+)/.match(raw_query))
    end

    def initialize(match_data)
      match_data = match_data ? match_data : {}
      self.attribute = match_data[:attribute]
      self.desired_value = match_data[:desired_value]
      self.operator = match_data[:operator]
    end
  end
end

Move parsing into its own class
Move parsing into its own class

This is mostly a fix for a RuboCop complaint, but I do like having this
one class responsible for the parsing and the handling of unparsable
key/value pairs
