module Cistern::Attributes def self.parsers @parsers ||= { :string => lambda { |v,opts| v.to_s }, :time => lambda { |v,opts| v.is_a?(Time) ? v : v && Time.parse(v.to_s) }, :integer => lambda { |v,opts| v && v.to_i }, :float => lambda { |v,opts| v && v.to_f }, :array => lambda { |v,opts| [*v] }, :boolean => lambda { |v,opts| ['true', '1'].include?(v.to_s.downcase) } } end def self.transforms @transforms ||= { :squash => Proc.new do |k, v, options| squash = options[:squash] if v.is_a?(::Hash) && squash.is_a?(Array) travel = lambda do |tree, path| if tree.is_a?(::Hash) subtree = tree[path.shift] travel.call(subtree, path) else tree end end travel.call(v, squash.dup) elsif v.is_a?(::Hash) if v.key?(squash.to_s.to_sym) v[squash.to_s.to_sym] elsif v.has_key?(squash.to_s) v[squash.to_s] else v end else v end end, :none => lambda { |k, v, opts| v }, } end def self.default_parser @default_parser ||= lambda { |v, opts| v } end module ClassMethods def _load(marshalled) new(Marshal.load(marshalled)) end def aliases @aliases ||= {} end def attributes @attributes ||= {} end def attribute(_name, options = {}) if defined? Cistern::Coverage attribute_call = Cistern::Coverage.find_caller_before("cistern/attributes.rb") # Only use DSL attribute calls from within a model if attribute_call and attribute_call.label.start_with? "