lib/representable/definition.rb in representable-1.7.7 vs lib/representable/definition.rb in representable-1.8.0
- old
+ new
@@ -1,82 +1,114 @@
+require 'uber/options'
+require "representable/parse_strategies"
+
module Representable
# Created at class compile time. Keeps configuration options for one property.
- class Definition
- attr_reader :name, :options
+ class Definition < Hash
+ attr_reader :name
alias_method :getter, :name
def initialize(sym, options={})
- @name = sym.to_s
- @options = options
+ super()
+ options = options.clone
+
+ handle_deprecations!(options)
+
+ @name = sym.to_s
+ # defaults:
+ options[:as] ||= @name
+
+ setup!(options)
end
- def clone
- self.class.new(name, options.clone) # DISCUSS: make generic Definition.cloned_attribute that passes list to constructor.
+ # TODO: test merge!.
+ def merge!(options)
+ setup!(options)
+ self
end
+ private :default, :[]=
+
+ def options # TODO: remove in 2.0.
+ warn "Representable::Definition#option is deprecated, use #[] directly."
+ self
+ end
+
def setter
:"#{name}="
end
def typed?
- deserialize_class.is_a?(Class) or representer_module or options[:instance] # also true if only :extend is set, for people who want solely rendering.
+ self[:class] or self[:extend] or self[:instance]
end
+ def representable?
+ return if self[:representable] === false
+ self[:representable] or typed?
+ end
+
def array?
- options[:collection]
+ self[:collection]
end
def hash?
- options[:hash]
+ self[:hash]
end
- def deserialize_class
- options[:class]
- end
-
- def from
- # TODO: deprecate :from.
- (options[:from] || options[:as] || name).to_s
- end
-
def default_for(value)
- return default if skipable_nil_value?(value)
+ return self[:default] if skipable_nil_value?(value)
value
end
def has_default?
- options.has_key?(:default)
+ has_key?(:default)
end
def representer_module
- options[:extend] or options[:decorator]
+ self[:extend]
end
- def attribute
- options[:attribute]
+ def skipable_nil_value?(value)
+ value.nil? and not self[:render_nil]
end
- def content
- options[:content]
+ def create_binding(*args)
+ self[:binding].call(self, *args)
end
- def skipable_nil_value?(value)
- value.nil? and not options[:render_nil]
+ private
+ def setup!(options)
+ handle_extend!(options)
+ handle_as!(options)
+
+ # DISCUSS: we could call more macros here (e.g. for :nested).
+ Representable::ParseStrategy.apply!(options)
+
+ for name, value in options
+ value = Uber::Options::Value.new(value) if dynamic_options.include?(name)
+ self[name] = value
+ end
end
- def default
- options[:default]
+ def dynamic_options
+ [:as, :getter, :setter, :class, :instance, :reader, :writer, :extend, :prepare, :if]
end
- def binding
- options[:binding]
+ def handle_extend!(options)
+ mod = options.delete(:extend) || options.delete(:decorator) and options[:extend] = mod
end
- def create_binding(*args)
- binding.call(self, *args)
+ def handle_as!(options)
+ options[:as] = options[:as].to_s if options[:as].is_a?(Symbol) # Allow symbols for as:
end
- def sync?
- options[:parse_strategy] == :sync
+ # TODO: remove in 2.0.
+ def handle_deprecations!(options)
+ raise "The :from option got replaced by :as in Representable 1.8!" if options[:from]
+
+ if options[:decorator_scope]
+ warn "[Representable] Deprecation: `decorator_scope: true` is deprecated, use `exec_context: :decorator` instead."
+ options.merge!(:exec_context => :decorator)
+ end
end
end
end