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