Class: MappingType::Proxy

Inherits:
Object
  • Object
show all
Extended by:
AttrPublicReadPrivateWrite
Defined in:
lib/0xfacet/typed/mapping_type.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from AttrPublicReadPrivateWrite

attr_public_read_private_write

Constructor Details

#initialize(initial_value = {}, key_type:, value_type:, on_change: nil) ⇒ Proxy

Returns a new instance of Proxy.



40
41
42
43
44
45
46
47
# File 'lib/0xfacet/typed/mapping_type.rb', line 40

def initialize(initial_value = {}, key_type:, value_type:, on_change: nil)
  self.key_type = key_type
  self.value_type = value_type
  
  self.data = initial_value
  self.transformed_keys = Set.new
  self.on_change = on_change
end

Instance Attribute Details

#on_changeObject

Returns the value of attribute on_change.



14
15
16
# File 'lib/0xfacet/typed/mapping_type.rb', line 14

def on_change
  @on_change
end

Instance Method Details

#==(other) ⇒ Object



32
33
34
35
36
37
38
# File 'lib/0xfacet/typed/mapping_type.rb', line 32

def ==(other)
  return false unless other.is_a?(self.class)
  
  other.key_type == key_type &&
  other.value_type == value_type &&
  other.serialize == serialize
end

#[](key_var) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/0xfacet/typed/mapping_type.rb', line 49

def [](key_var)
  raw_key = key_var.is_a?(TypedVariable) ? key_var.value : key_var
  string_key = raw_key.to_s

  typed_key_var = TypedVariable.create_or_validate(key_type, key_var, on_change: on_change)

  # First, attempt a lookup using the typed key
  value = data[typed_key_var]

  # If no value is found, try looking it up as a string (how it would be stored in JSONB)
  if value.nil? && data.key?(string_key)
    value = TypedVariable.create_or_validate(value_type, data[string_key], on_change: on_change)
    
    data.delete(string_key)
    set_value(typed_key_var, value)
  end

  # If the value is still nil, it truly doesn't exist; create a new default value
  if value.nil?
    value = TypedVariable.create_or_validate(value_type, on_change: on_change)
    set_value(typed_key_var, value)
  end
  
  value
end

#[]=(key_var, value) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/0xfacet/typed/mapping_type.rb', line 75

def []=(key_var, value)
  key_var = TypedVariable.create_or_validate(key_type, key_var, on_change: on_change)
  val_var = TypedVariable.create_or_validate(value_type, value, on_change: on_change)

  if value_type.mapping?
    raise TypeError, "Mappings cannot be assigned to mappings"
  end
  
  old_value = self.data[key_var]
  
  if old_value != val_var
    on_change&.call
    
    transformed_keys.add(key_var)

    data[key_var] ||= val_var
    data[key_var].value = val_var.value
  end
end

#serializeObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/0xfacet/typed/mapping_type.rb', line 17

def serialize
  serialized_dirty_data = {}
  
  transformed_keys.each do |key|
    value = data[key]
    
    unless value.value == value.type.default_value
      serialized_dirty_data[key.serialize.to_s] = value.serialize
    end
  end
  
  clean_data = data.except(*transformed_keys)
  clean_data.merge(serialized_dirty_data).deep_dup
end