lib/eco/language/models/parser_serializer.rb in eco-helpers-1.5.1 vs lib/eco/language/models/parser_serializer.rb in eco-helpers-1.5.2
- old
+ new
@@ -1,68 +1,92 @@
module Eco
module Language
module Models
-
+ # Basic class to define a parser/serializing framework
+ # @attr_reader attr [String, Symbol] the attribute this parser/serializer is linked to.
class ParserSerializer
-
attr_reader :attr
# Parser/seralizer.
# @param attr [String, Symbol] name of the parsed/serialized.
# @param dependencies [Hash] provisioning of _**default dependencies**_ that will be required when calling back to the
- # parsing or serializing functions.
+ # parsing or serializing functions.
def initialize(attr, dependencies: {})
- @attr = attr
+ @attr = attr
@dependencies = dependencies
+ @parser = {}
+ @serializer = {}
end
# Defines the _parser_ of the attribute.
# @note
# 1. the _block_ should expect one or two parameters.
# 2. the final dependencies is a merge of _default dependencies_ with `parse` call dependencies.
+ # @param category [Symbol] a way to classify multiple parsers by category.
# @yield [source_data, dependencies] user defined parser that returns the parsed value.
# @yieldparam source_data [Any] source data that will be parsed.
# @yieldparam dependencies [Hash] hash with the provisioned dependencies.
- def def_parser(&block)
- @parser = block
+ def def_parser(category = :default, &block)
+ @parser[category.to_sym] = block
self
end
# Defines the _serializer_ of the attribute.
# @note
# 1. the block should expect one or two parameters.
# 2. the final dependencies is a merge of _default dependencies_ with `serialize` call dependencies.
+ # @param category [Symbol] a way to classify multiple serializers by category.
# @yield [source_data, dependencies] user defined serialiser that returns the serialised value.
# @yieldparam source_data [Any] source data that will be serialised.
# @yieldparam dependencies [Hash] hash with the provisioned dependencies.
- def def_serializer(&block)
- @serializer = block
+ def def_serializer(category = :default, &block)
+ @serializer[category.to_sym] = block
self
end
# Calls the `parser` of this attribute by passing `source` and resolved dependencies.
# @note
# - the method depenencies override keys of the _default dependencies_.
# @raise [Exception] when there is **no** `parser` defined.
# @param source [Any] source data to be parsed.
# @param dependencies [Hash] _additional dependencies_ that should be merged to the _default dependencies_.
- def parse(source, dependencies: {})
- raise "There is no parser for this attribue '#{attr}'" if !@parser
- @parser.call(source, @dependencies.merge(dependencies), attr)
+ def parse(source, category = :default, dependencies: {})
+ raise "There is no parser of type '#{category}' for this attribue '#{attr}'" unless parser_category?(category)
+ call_block(source, @dependencies.merge(dependencies), attr, &@parser[category.to_sym])
end
# Calls the `serializer` of this attribute by passing `object` and resolved dependencies.
# @note
# - the method depenencies override keys of the _default dependencies_.
# @raise [Exception] when there is **no** `serializer` defined.
# @param object [Any] source data to be serialized.
# @param dependencies [Hash] _additional dependencies_ that should be merged to the _default dependencies_.
- def serialize(object, dependencies: {})
- raise "There is no serializer for this attribue '#{attr}'" if !@serializer
- @serializer.call(object, @dependencies.merge(dependencies), attr)
+ def serialize(object, category = :default, dependencies: {})
+ raise "There is no serializer of type '#{category}' for this attribue '#{attr}'" unless serializer_category?(category)
+ call_block(object, @dependencies.merge(dependencies), attr, &@serializer[category.to_sym])
end
- end
+ # Checks if there's a `parser` defined for `category`
+ # @return [Boolean] `true` if the parser is defined, and `false` otherwise
+ def parser_category?(category = :default)
+ @parser.key?(category.to_sym)
+ end
+ # Checks if there's a `serializer` defined for `category`
+ # @return [Boolean] `true` if the serializer is defined, and `false` otherwise
+ def serializer_category?(category = :default)
+ @serializer.key?(category.to_sym)
+ end
+
+ private
+
+ # The methods may expect less parameters from some type of parsers.
+ # Here, we ensure they are called with the expected number of parameters.
+ def call_block(*args, &block)
+ params = block.parameters.zip(args).map(&:last)
+ yield(*params)
+ end
+
+ end
end
end
end