Class: FIRM::Serializable::Property

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

Overview

This class encapsulates a serializable property definition.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Property.



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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/firm/serializable.rb', line 16

def initialize(klass, prop, proc=nil, force: false, handler: nil, optional: false, &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
  @optional = optional.nil? || optional
  @default = if @optional
               case optional
               when Proc
                 ::Kernel.raise ArgumentError,
                                'Invalid optional value proc' unless optional.arity.abs == 2
                 optional
               when UnboundMethod
                 ::Kernel.raise ArgumentError,
                                'Invalid optional value method' unless optional.arity.abs == 1
                 ->(obj, id) { optional.bind(obj).call(id) }
               else
                 optional == true ? nil : optional
               end
             else
               nil
             end
  if block || handler
    if handler
      ::Kernel.raise ArgumentError,
                     "Invalid property handler #{handler} for #{prop}" unless ::Proc === handler || ::Symbol === handler || ::String === 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.



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

def id
  @id
end

Instance Method Details

#deserialize(obj, data) ⇒ void

This method returns an undefined value.

Restores the defined property for the given object using the deserialized data extracted from the given data object.

Parameters:

  • obj (Object)
  • data (Object)

    hash-like object



106
107
108
109
110
# File 'lib/firm/serializable.rb', line 106

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

#get(obj) ⇒ Object

Returns the (unserialized) property value for the given object.

Parameters:

  • obj (Object)


97
98
99
# File 'lib/firm/serializable.rb', line 97

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

#serialize(obj, data, excludes) ⇒ Object

Serializes the defined property for the given object and inserts the serialized data into the given data object unless included in the given excludes list.

Parameters:

  • obj (Object)
  • data (Object)

    hash-like object

  • excludes (Array<Symbol>)


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/firm/serializable.rb', line 79

def serialize(obj, data, excludes)
  unless excludes.include?(@id)
    val = getter.call(obj)
    unless optional?(obj, val) || (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