lib/representable/binding.rb in representable-1.6.1 vs lib/representable/binding.rb in representable-1.7.0

- old
+ new

@@ -1,6 +1,8 @@ -require 'delegate' +require "delegate" +require "representable/deserializer" +require "representable/serializer" module Representable # The Binding wraps the Definition instance for this property and provides methods to read/write fragments. class Binding < SimpleDelegator class FragmentNotFound @@ -24,11 +26,11 @@ # Main entry point for rendering/parsing a property object. def serialize(value) value end - def deserialize(fragment) + def deserialize(fragment, *args) fragment end # Retrieve value and write fragment to the doc. def compile_fragment(doc) @@ -82,10 +84,12 @@ represented_exec_for(:setter, value) do exec_context.send(setter, value) end end + # the remaining methods in this class are format-independent and should be in Definition. + private attr_reader :exec_context # Execute the block for +option_name+ on the represented object. # Executes passed block when there's no lambda for option. @@ -101,59 +105,35 @@ args << user_options # DISCUSS: we assume user_options is a Hash! exec_context.instance_exec(*args, &proc) end - # Hooks into #serialize and #deserialize to setup (extend/decorate) typed properties - # at runtime. module Prepare - # Extends the object with its representer before serialization. - def serialize(*) - prepare(super) - end - - def deserialize(*) - prepare(super) - end - - def prepare(object) - return object unless mod = representer_module_for(object) # :extend. - - mod = mod.first if mod.is_a?(Array) # TODO: deprecate :extend => [..] - mod.prepare(object) - end - - private def representer_module_for(object, *args) call_proc_for(representer_module, object) # TODO: how to pass additional data to the computing block?` end end + include Prepare - # Overrides #serialize/#deserialize to call #to_*/from_*. - # Computes :class in #deserialize. # TODO: shouldn't this be in a separate module? ObjectSerialize/ObjectDeserialize? - module Object - include Binding::Prepare + # Delegates to call #to_*/from_*. + module Object def serialize(object) - return object if object.nil? - - super.send(serialize_method, @user_options.merge!({:wrap => false})) # TODO: pass :binding => self + ObjectSerializer.new(self, object).call end - def deserialize(data) + def deserialize(data, object=lambda { get }) # DISCUSS: does it make sense to skip deserialization of nil-values here? - create_object(data).tap do |obj| - super(obj).send(deserialize_method, data, @user_options) - end + ObjectDeserializer.new(self, object).call(data) end def create_object(fragment) instance_for(fragment) or class_for(fragment) end private def class_for(fragment, *args) - item_class = class_from(fragment) or return fragment # DISCUSS: is it legal to return the very fragment here? + item_class = class_from(fragment) or return fragment item_class.new end def class_from(fragment, *args) call_proc_for(sought_type, fragment)