lib/dupervisor/parser.rb
require_relative 'formats'
module DuperVisor
#
# This class is responsible for coordination of parsing attempts of a
# given contet with diffirent format parsers.
#
class Parser
class ParseError < StandardError; end
class FormatNotFound < ParseError; end
include DuperVisor::Formats::Accessors
attr_accessor :content, :parse_errors
def initialize(body)
self.content = Content.new(body: body)
end
def parse(input_format = nil)
self.parse_errors = {}
content.parse_result = nil
formats_to_check = input_format ? [ formats[input_format] ] : format_classes
formats_to_check.each do |format_class|
format = format_class.format
parse_result = try_format(format, format_class)
if parse_result
content.parse_result = parse_result
content.format = format
break
end
end
unless content.parse_result || parse_errors.empty?
if input_format
raise ParseError.new("Can not parse from format #{input_format}. Format exception:" +
parse_errors.values.map(&:inspect).join("\n"))
else
raise FormatNotFound.new('No suitable format detected. Query #parse_errors for specifics.')
end
end
content
end
def try_format(format, format_class)
format_class.from.call(content.body)
rescue *(format_class.errors) => e
self.parse_errors[format] = e
nil
end
end
end