Skip to content

Instantly share code, notes, and snippets.

@a-chernykh
Created January 21, 2014 12:16
Show Gist options
  • Save a-chernykh/8538968 to your computer and use it in GitHub Desktop.
Save a-chernykh/8538968 to your computer and use it in GitHub Desktop.
Extract from pickle gem which adds capture_fields and parse_fields helpers
module CaptureFields
class Matcher
class << self
def match_quoted
'(?:\\\\"|[^\\"]|\\.)*'
end
def match_label
"(?::? \"#{match_quoted}\")"
end
def match_value
"(?:\"#{match_quoted}\"|nil|true|false|[+-]?[0-9_]+(?:\\.\\d+)?)"
end
def match_field
"(?:\\w+: #{match_value})"
end
def match_fields
"(?:#{match_field}, )*#{match_field}"
end
def capture_key_and_value_in_field
"(?:(\\w+): (#{match_value}))"
end
end
end
module Parser
# given a string like 'foo: expr' returns {key => value}
def parse_field(field)
if field =~ /^#{Matcher.capture_key_and_value_in_field}$/
{ $1 => eval($2) }
else
raise ArgumentError, "The field argument is not in the correct format.\n\n'#{field}' did not match: #{match_field}"
end
end
# given a string like 'foo: "bar", bar: "baz"' returns {"foo" => "bar", "bar" => "baz"}
def parse_fields(fields)
if fields.blank?
{}
elsif fields =~ /^#{Matcher.match_fields}$/
fields.scan(/(#{Matcher.match_field})(?:,|$)/).inject({}) do |m, match|
m.merge(parse_field(match[0]))
end
else
raise ArgumentError, "The fields string is not in the correct format.\n\n'#{fields}' did not match: #{match_fields}"
end
end
end
end
World CaptureFields::Parser
def self.capture_fields
"(#{CaptureFields::Matcher.match_fields})"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment