Class: Algebrick::Serializers::BenevolentToHash
- Inherits:
-
AbstractToHash
show all
- Defined in:
- lib/algebrick/serializers/benevolent_to_hash.rb,
lib/algebrick/serializers2/benevolent_to_hash.rb
Constant Summary
- CANNOT =
Algebrick.atom
Instance Attribute Summary
#fields_key, #type_key
Instance Method Summary
(collapse)
#initialize
Methods included from TypeCheck
#Child!, #Child?, #Match!, #Match?, #Type!, #Type?, error
Instance Method Details
131
132
133
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 131
def can?(v)
v != CANNOT
end
|
- (Boolean) can_be?(type, object)
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 33
def can_be?(type, object)
Type! type, Module
could? do
cannot! unless object.is_a?(::Hash)
cannot! unless object[type_key] || object[type_key.to_s]
return object
end
could? { return can_be_atom? type, object }
could? { return can_be_product_variant? type, object }
return object if object.is_a?(type)
cannot!
end
|
- (Boolean) can_be_atom?(type, object)
83
84
85
86
87
88
89
90
91
92
93
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 83
def can_be_atom?(type, object)
Type! type, Module
cannot! unless type.is_a?(Atom)
cannot! unless object.is_a?(String) || object.is_a?(Symbol)
last_name = type.name.split('::').last
possible_representations = [type.name, last_name.downcase, underscore(last_name)]
cannot! unless possible_representations.any? { |v| v == object.to_s }
return type_key => type.name
end
|
- (Boolean) can_be_product?(type, object)
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 95
def can_be_product?(type, object)
Type! type, Module
could? do
cannot! unless object.is_a?(::Array) && !type.field_names?
cannot! unless type.fields.size == object.size
fields = many_can_by? type.fields.zip(object)
return { type_key => type.name, fields_key => fields }
end
could? do
cannot! unless object.is_a?(::Hash) && type.field_names?
candidates = type.field_names.map do |field_name|
v1 = object.fetch(field_name, CANNOT)
v2 = object.fetch(field_name.to_s, CANNOT)
(v = [v1, v2].find { |v| v != CANNOT }) or cannot!
end
values = many_can_by? type.fields.zip(candidates)
fields = type.field_names.zip(values).
each_with_object({}) { |(name, value), fields| fields[name] = value }
return { type_key => type.name }.update(fields)
end
cannot!
end
|
- (Boolean) can_be_product_variant?(type, object)
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 56
def can_be_product_variant?(type, object)
Type! type, Module
cannot! unless type.is_a? ProductVariant
if type.variants
self_variant = type.variants.find { |v| v == type }
other_variants = type.variants - [self_variant]
possibilities = [
*other_variants.map { |v| could? { can_be? v, object } },
could? do
cannot! unless self_variant
can_be_atom? self_variant, object
end,
could? do
cannot! unless self_variant
can_be_product? self_variant, object
end
].select { |v| can? v }
cannot! if possibilities.empty?
raise "multiple options #{possibilities}" if possibilities.size > 1
possibilities.first
else
can_be_product? type, object
end
end
|
135
136
137
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 135
def cannot!
throw CANNOT, CANNOT
end
|
125
126
127
128
129
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 125
def could?
catch CANNOT do
yield
end
end
|
- (Object) dump(object, options = {})
18
19
20
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 18
def dump(object, options = {})
object
end
|
- (Object) load(object, options = {})
22
23
24
25
26
27
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 22
def load(object, options = {})
expected_type = Type! options[:expected_type], Module
could? { can_be? expected_type, object }.tap do |v|
raise "type mismatch #{object} is not #{expected_type} " unless can? v
end
end
|
- (Boolean) many_can_by?(hash)
50
51
52
53
54
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 50
def many_can_by?(hash)
hash.map do |type, value|
can_be? type, value
end
end
|
- (Object) underscore(string)
139
140
141
|
# File 'lib/algebrick/serializers/benevolent_to_hash.rb', line 139
def underscore(string)
string[0].downcase + string[1..-1].gsub(/([A-Z])/) { |m| '_' + m.downcase }
end
|