Class: FIRM::Serializable::Property

Inherits:
Object
  • Object
show all
Defined in:
lib/firm/serializable.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, prop, proc = nil, force: false, handler: nil, &block) ⇒ Property

Returns a new instance of Property.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/firm/serializable.rb', line 15

def initialize(klass, prop, proc=nil, force: false, handler: nil, &block)
  ::Kernel.raise ArgumentError, "Invalid property id [#{prop}]" unless ::String === prop || ::Symbol === prop
  ::Kernel.raise ArgumentError, "Duplicate property id [#{prop}]" if klass.has_serializer_property?(prop)
  @klass = klass
  @id = prop.to_sym
  @forced = force
  if block || handler
    if handler
      ::Kernel.raise ArgumentError,
                     "Invalid property handler #{handler} for #{prop}" unless ::Proc === handler || ::Symbol === handler
      if handler.is_a?(::Proc)
        ::Kernel.raise ArgumentError, "Invalid property block #{proc} for #{prop}" unless block.arity == -3
        @getter = ->(obj) { handler.call(@id, obj) }
        @setter = ->(obj, val) { handler.call(@id, obj, val) }
      else
        @getter = ->(obj) { obj.send(handler, @id) }
        @setter = ->(obj, val) { obj.send(handler, @id, val) }
      end
    else
      # any property block MUST accept 2 or 3 args; property name, instance and value (for setter)
      ::Kernel.raise ArgumentError, "Invalid property block #{proc} for #{prop}" unless block.arity == -3
      @getter = ->(obj) { block.call(@id, obj) }
      @setter = ->(obj, val) { block.call(@id, obj, val) }
    end
  elsif proc
    ::Kernel.raise ArgumentError,
                   "Invalid property proc #{proc} for #{prop}" unless ::Proc === proc || ::Symbol === proc
    if ::Proc === proc
      # any property proc should be callable with a single arg (instance)
      @getter = proc
      # a property proc combining getter/setter functionality should accept a single or more args (instance + value)
      @setter = (proc.arity == -2) ? proc : nil
    else
      @getter = ->(obj) { obj.send(proc) }
      @setter = ->(obj, val) { obj.send(proc, val) }
    end
  end
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



54
55
56
# File 'lib/firm/serializable.rb', line 54

def id
  @id
end

Instance Method Details

#deserialize(obj, data) ⇒ Object



72
73
74
75
76
# File 'lib/firm/serializable.rb', line 72

def deserialize(obj, data)
  if data.has_key?(@id)
    setter.call(obj, data[@id])
  end
end

#get(obj) ⇒ Object



78
79
80
# File 'lib/firm/serializable.rb', line 78

def get(obj)
  getter.call(obj)
end

#serialize(obj, data, excludes) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/firm/serializable.rb', line 56

def serialize(obj, data, excludes)
  unless excludes.include?(@id)
    val = getter.call(obj)
    unless Serializable === val && val.serialize_disabled? && !@forced
      data[@id] = case val
                  when ::Array
                    val.select { |elem| !(Serializable === elem && elem.serialize_disabled?) }
                  when ::Set
                    ::Set.new(val.select { |elem| !(Serializable === elem && elem.serialize_disabled?) })
                  else
                    val
                  end
    end
  end
end