Created
January 21, 2014 12:16
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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