module Eco module Language module Models 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. def initialize(attr, dependencies: {}) @attr = attr @dependencies = dependencies 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. # @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 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. # @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 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) 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) end end end end end