lib/lurker/json/parser.rb
module Lurker
module Json
class Parser
class << self
def plain(options = {})
new(options).plain
end
def typed(options = {})
new(options).typed
end
end
def initialize(options = {})
@root_schema = options[:root_schema]
@parent_schema = options[:parent_schema]
@parent_property = options[:parent_property]
@polymorph_if_empty = options.fetch(:polymorph_if_empty, false)
@uri = options[:uri] || @parent_schema&.uri
@strategy = nil
end
def parse(payload)
parse_once { @strategy.new(schema_options_once).parse(payload) }
end
def parse_property(property, payload)
options = schema_options_once.merge!(parent_property: property)
parse_once { @strategy.new(options).parse(payload) }
end
def plain(options = {})
@options = schema_options.merge!(options)
@strategy = strategy_klass(:plain)
self
end
def typed(options = {})
@options = schema_options.merge!(options)
@strategy = strategy_klass(:typed)
self
end
private
def parse_once(&block)
raise 'Define parsing strategy [plain|typed] before using' unless @strategy.present?
result = block.call
@strategy = nil
result
end
def schema_options_once
options = @options.present? ? @options.dup : schema_options
@options = {}
options
end
def strategy_klass(name)
"lurker/json/parser/#{name}_strategy".camelize.constantize
end
def schema_options
{
uri: @uri, root_schema: @root_schema, polymorph_if_empty: @polymorph_if_empty,
parent_schema: @parent_schema, parent_property: @parent_property
}
end
end
end
end