emery 0.0.2 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/emery.rb +1 -3
- data/lib/emery/dataclass.rb +67 -65
- data/lib/emery/enum.rb +73 -75
- data/lib/emery/jsoner.rb +169 -164
- data/lib/emery/type.rb +149 -151
- data/test/dataclass_test.rb +80 -83
- data/test/enum_test.rb +29 -33
- data/test/jsoner_test.rb +217 -192
- data/test/type_test.rb +153 -155
- metadata +2 -4
- data/lib/emery/tod.rb +0 -262
- data/test/tod_test.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ba8d10d1763e47f1372846069228199447b003b5aa230752d55dc1092003a56
|
4
|
+
data.tar.gz: af14a3412051287a95b22253a553001c0efeca0e57454006ac650d6f78f9b346
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a9f566c1d0d2d92e8a176dc2b278ffacb05408919cb769c6ffed636e4fcbb7dc6a6ec02c2ceff49490954383c01cb3fca3d9cc2fded07a69c7b6abf61853cef
|
7
|
+
data.tar.gz: 1a9fce0a295c3dec3cef3f1d20397ffbae415d42948f573d39ac5c1523cee67b797ba8b51fa62f1097e0d15aa089864891a17dde61e29deb2fa8d12a9bbbf11b
|
data/lib/emery.rb
CHANGED
data/lib/emery/dataclass.rb
CHANGED
@@ -1,86 +1,88 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
self.instance_variable_set("@#{attr}", T.check_var(attr, attr_type, attr_value))
|
7
|
-
end
|
1
|
+
module DataClass
|
2
|
+
def initialize(params)
|
3
|
+
self.class.json_attributes.each do |attr, attr_type|
|
4
|
+
attr_value = params[attr]
|
5
|
+
self.instance_variable_set("@#{attr}", T.check_var(attr, attr_type, attr_value))
|
8
6
|
end
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
9
|
+
def ==(other)
|
10
|
+
begin
|
11
|
+
T.check(self.class, other)
|
12
|
+
self.class.json_attributes.keys.each do |attr|
|
13
|
+
if self.instance_variable_get("@#{attr}") != other.instance_variable_get("@#{attr}")
|
14
|
+
return false
|
17
15
|
end
|
18
|
-
return true
|
19
|
-
rescue
|
20
|
-
return false
|
21
16
|
end
|
17
|
+
return true
|
18
|
+
rescue
|
19
|
+
return false
|
22
20
|
end
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
23
|
+
def copy(params)
|
24
|
+
params.each do |attr, attr_value|
|
25
|
+
if !self.class.json_attributes.key?(attr)
|
26
|
+
raise TypeError.new("Non existing attribute #{attr}")
|
29
27
|
end
|
30
|
-
new_params =
|
31
|
-
self.class.json_attributes.map do |attr, attr_type|
|
32
|
-
attr_value =
|
33
|
-
if params.key?(attr)
|
34
|
-
params[attr]
|
35
|
-
else
|
36
|
-
self.instance_variable_get("@#{attr}")
|
37
|
-
end
|
38
|
-
[attr, attr_value]
|
39
|
-
end.to_h
|
40
|
-
return self.class.new(new_params)
|
41
28
|
end
|
29
|
+
new_params =
|
30
|
+
self.class.json_attributes.map do |attr, attr_type|
|
31
|
+
attr_value =
|
32
|
+
if params.key?(attr)
|
33
|
+
params[attr]
|
34
|
+
else
|
35
|
+
self.instance_variable_get("@#{attr}")
|
36
|
+
end
|
37
|
+
[attr, attr_value]
|
38
|
+
end.to_h
|
39
|
+
return self.class.new(new_params)
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
def to_json
|
43
|
+
return Jsoner.serialize(self.class, self)
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
46
|
+
def self.included(base)
|
47
|
+
base.extend ClassMethods
|
48
|
+
end
|
51
49
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
module ClassMethods
|
51
|
+
def json_attributes
|
52
|
+
@json_attributes
|
53
|
+
end
|
54
|
+
|
55
|
+
def val(name, type)
|
56
|
+
if @json_attributes == nil
|
57
|
+
@json_attributes = {}
|
58
58
|
end
|
59
|
+
@json_attributes[name] = type
|
60
|
+
attr_reader name
|
61
|
+
end
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
-
@json_attributes[name] = type
|
65
|
-
attr_accessor name
|
63
|
+
def var(name, type)
|
64
|
+
if @json_attributes == nil
|
65
|
+
@json_attributes = {}
|
66
66
|
end
|
67
|
+
@json_attributes[name] = type
|
68
|
+
attr_accessor name
|
69
|
+
end
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
return self.new parameters.to_h
|
71
|
+
def jsoner_deserialize(json_value)
|
72
|
+
T.check(T.hash(String, NilableUntyped), json_value)
|
73
|
+
parameters = @json_attributes.map do |attr, attr_type|
|
74
|
+
attr_value = json_value[attr.to_s]
|
75
|
+
[attr, Jsoner.deserialize(attr_type, attr_value)]
|
75
76
|
end
|
77
|
+
return self.new parameters.to_h
|
78
|
+
end
|
76
79
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
return attrs.to_h
|
80
|
+
def jsoner_serialize(value)
|
81
|
+
T.check(self, value)
|
82
|
+
attrs = @json_attributes.map do |attr, attr_type|
|
83
|
+
[attr, Jsoner.serialize(attr_type, value.send(attr))]
|
83
84
|
end
|
85
|
+
return attrs.to_h
|
84
86
|
end
|
85
87
|
end
|
86
88
|
end
|
data/lib/emery/enum.rb
CHANGED
@@ -1,101 +1,99 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
attr_reader :key, :value
|
1
|
+
module Enum
|
2
|
+
attr_reader :key, :value
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
def initialize(key, value)
|
5
|
+
@key = key
|
6
|
+
@value = value
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def self.included(base)
|
10
|
+
base.extend Enumerable
|
11
|
+
base.extend ClassMethods
|
13
12
|
|
14
|
-
|
15
|
-
|
13
|
+
base.private_class_method(:new)
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
16
|
+
module ClassMethods
|
17
|
+
def check(value)
|
18
|
+
T.check_not_nil(self, value)
|
19
|
+
if !value?(value)
|
20
|
+
raise TypeError.new("Value '#{value.inspect.to_s}' is not a member of enum #{self}")
|
23
21
|
end
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
def jsoner_deserialize(json_value)
|
25
|
+
T.check(self, json_value)
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
def jsoner_serialize(value)
|
29
|
+
T.check(self, value)
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
def define(key, value)
|
33
|
+
@_enum_hash ||= {}
|
34
|
+
@_enums_by_value ||= {}
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
if @_enum_hash.key?(key) then
|
37
|
+
raise TypeError.new("Duplicate key: #{key}")
|
38
|
+
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
if @_enums_by_value.key?(value) then
|
41
|
+
raise TypeError.new("Duplicate value: #{value}")
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
new_instance = new(key, value)
|
45
|
+
@_enum_hash[key] = new_instance
|
46
|
+
@_enums_by_value[value] = new_instance
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
48
|
+
if key.to_s == key.to_s.upcase
|
49
|
+
const_set key, value
|
50
|
+
else
|
51
|
+
define_singleton_method(key) { value }
|
54
52
|
end
|
53
|
+
end
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
def each(&block)
|
56
|
+
@_enum_hash.each(&block)
|
57
|
+
end
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
nil
|
59
|
+
def parse(k)
|
60
|
+
k = k.to_s.upcase
|
61
|
+
each do |key, enum|
|
62
|
+
return enum.value if key.to_s.upcase == k
|
66
63
|
end
|
64
|
+
nil
|
65
|
+
end
|
67
66
|
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
def key?(k)
|
68
|
+
@_enum_hash.key?(k)
|
69
|
+
end
|
71
70
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
def value(k)
|
72
|
+
enum = @_enum_hash[k]
|
73
|
+
enum.value if enum
|
74
|
+
end
|
76
75
|
|
77
|
-
|
78
|
-
|
79
|
-
|
76
|
+
def value?(v)
|
77
|
+
@_enums_by_value.key?(v)
|
78
|
+
end
|
80
79
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
def key(v)
|
81
|
+
enum = @_enums_by_value[v]
|
82
|
+
enum.key if enum
|
83
|
+
end
|
85
84
|
|
86
|
-
|
87
|
-
|
88
|
-
|
85
|
+
def keys
|
86
|
+
@_enum_hash.values.map(&:key)
|
87
|
+
end
|
89
88
|
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
def values
|
90
|
+
@_enum_hash.values.map(&:value)
|
91
|
+
end
|
93
92
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
93
|
+
def to_h
|
94
|
+
Hash[@_enum_hash.map do |key, enum|
|
95
|
+
[key, enum.value]
|
96
|
+
end]
|
99
97
|
end
|
100
98
|
end
|
101
99
|
end
|
data/lib/emery/jsoner.rb
CHANGED
@@ -1,213 +1,218 @@
|
|
1
1
|
require "json"
|
2
2
|
require "date"
|
3
3
|
|
4
|
-
|
4
|
+
class JsonerError < StandardError
|
5
|
+
end
|
5
6
|
|
6
|
-
module
|
7
|
-
|
7
|
+
module Jsoner
|
8
|
+
T::StringFormatted.class_eval do
|
9
|
+
def jsoner_deserialize(json_value)
|
10
|
+
T.check(self, json_value)
|
11
|
+
end
|
12
|
+
def jsoner_serialize(value)
|
13
|
+
T.check(self, value)
|
14
|
+
end
|
8
15
|
end
|
9
16
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
T.check(self, json_value)
|
14
|
-
end
|
15
|
-
def jsoner_serialize(value)
|
16
|
-
T.check(self, value)
|
17
|
-
end
|
17
|
+
T::UntypedType.class_eval do
|
18
|
+
def jsoner_deserialize(json_value)
|
19
|
+
json_value
|
18
20
|
end
|
21
|
+
def jsoner_serialize(value)
|
22
|
+
value
|
23
|
+
end
|
24
|
+
end
|
19
25
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
json_value.map { |item_json_value| Jsoner.deserialize(self.item_type, item_json_value) }
|
26
|
+
T::ArrayType.class_eval do
|
27
|
+
def jsoner_deserialize(json_value)
|
28
|
+
T.check_not_nil(self, json_value)
|
29
|
+
if !json_value.is_a?(Array)
|
30
|
+
raise JsonerError.new("JSON value type #{json_value.class} is not Array")
|
27
31
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
json_value.map { |item_json_value| Jsoner.deserialize(self.item_type, item_json_value) }
|
33
|
+
end
|
34
|
+
def jsoner_serialize(value)
|
35
|
+
if !value.is_a?(Array)
|
36
|
+
raise JsonerError.new("Value type #{json_value.class} is not Array")
|
33
37
|
end
|
38
|
+
value.map { |item| Jsoner.serialize(self.item_type, item) }
|
34
39
|
end
|
40
|
+
end
|
35
41
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
if !json_value.is_a?(Hash)
|
43
|
-
raise JsonerError.new("JSON value type #{json_value.class} is not Hash")
|
44
|
-
end
|
45
|
-
json_value.map do |key, value|
|
46
|
-
[T.check(self.key_type, key), Jsoner.deserialize(self.value_type, value)]
|
47
|
-
end.to_h
|
42
|
+
T::HashType.class_eval do
|
43
|
+
def jsoner_deserialize(json_value)
|
44
|
+
T.check_not_nil(self, json_value)
|
45
|
+
if self.key_type != String
|
46
|
+
raise JsonerError.new("Hash key type #{self.key_type} is not supported for JSON (de)serialization - key should be String")
|
48
47
|
end
|
49
|
-
|
50
|
-
|
51
|
-
raise JsonerError.new("Hash key type #{self.key_type} is not supported for JSON (de)serialization - key should be String")
|
52
|
-
end
|
53
|
-
if !value.is_a?(Hash)
|
54
|
-
raise JsonerError.new("Value type #{value.class} is not Hash")
|
55
|
-
end
|
56
|
-
value.map do |key, value|
|
57
|
-
[T.check(self.key_type, key), Jsoner.serialize(self.value_type, value)]
|
58
|
-
end.to_h
|
48
|
+
if !json_value.is_a?(Hash)
|
49
|
+
raise JsonerError.new("JSON value type #{json_value.class} is not Hash")
|
59
50
|
end
|
51
|
+
json_value.map do |key, value|
|
52
|
+
[T.check(self.key_type, key), Jsoner.deserialize(self.value_type, value)]
|
53
|
+
end.to_h
|
60
54
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
types.each do |type|
|
65
|
-
begin
|
66
|
-
return Jsoner.deserialize(type, json_value)
|
67
|
-
rescue TypeError
|
68
|
-
end
|
69
|
-
end
|
70
|
-
raise JsonerError.new("Value '#{json_value.inspect.to_s}' can not be deserialized as any of #{@types.map { |t| t.to_s}.join(', ')}")
|
55
|
+
def jsoner_serialize(value)
|
56
|
+
if self.key_type != String
|
57
|
+
raise JsonerError.new("Hash key type #{self.key_type} is not supported for JSON (de)serialization - key should be String")
|
71
58
|
end
|
72
|
-
|
73
|
-
|
74
|
-
type = types.find {|t| T.instance_of?(t, value) }
|
75
|
-
Jsoner.serialize(type, value)
|
59
|
+
if !value.is_a?(Hash)
|
60
|
+
raise JsonerError.new("Value type #{value.class} is not Hash")
|
76
61
|
end
|
62
|
+
value.map do |key, value|
|
63
|
+
[T.check(self.key_type, key), Jsoner.serialize(self.value_type, value)]
|
64
|
+
end.to_h
|
77
65
|
end
|
66
|
+
end
|
78
67
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
raise JsonerError.new("JSON value #{json_value} should have only one key to represent union type, found #{json_value.keys.length}")
|
86
|
-
end
|
87
|
-
case_key = json_value.keys[0]
|
88
|
-
if not cases.key? case_key.to_sym
|
89
|
-
raise JsonerError.new("JSON key '#{case_key}' does not match any case in union type #{self}")
|
68
|
+
T::AnyType.class_eval do
|
69
|
+
def jsoner_deserialize(json_value)
|
70
|
+
types.each do |type|
|
71
|
+
begin
|
72
|
+
return Jsoner.deserialize(type, json_value)
|
73
|
+
rescue JsonerError
|
90
74
|
end
|
91
|
-
type = cases[case_key.to_sym]
|
92
|
-
case_json_value = json_value[case_key]
|
93
|
-
return Jsoner.deserialize(type, case_json_value)
|
94
|
-
end
|
95
|
-
def jsoner_serialize(value)
|
96
|
-
T.check(self, value)
|
97
|
-
type = types.find {|t| T.instance_of?(t, value) }
|
98
|
-
case_key = cases.key(type)
|
99
|
-
result = { case_key => Jsoner.serialize(type, value) }
|
100
|
-
result
|
101
75
|
end
|
76
|
+
raise JsonerError.new("Value '#{json_value.inspect.to_s}' can not be deserialized as any of #{@types.map { |t| t.to_s}.join(', ')}")
|
102
77
|
end
|
78
|
+
def jsoner_serialize(value)
|
79
|
+
T.check(self, value)
|
80
|
+
type = types.find {|t| T.instance_of?(t, value) }
|
81
|
+
Jsoner.serialize(type, value)
|
82
|
+
end
|
83
|
+
end
|
103
84
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
else
|
109
|
-
nil
|
110
|
-
end
|
85
|
+
T::UnionType.class_eval do
|
86
|
+
def jsoner_deserialize(json_value)
|
87
|
+
if !json_value.is_a?(Hash)
|
88
|
+
raise JsonerError.new("JSON value type #{json_value.class} is not Hash")
|
111
89
|
end
|
112
|
-
|
113
|
-
|
114
|
-
Jsoner.serialize(self.type, value)
|
115
|
-
else
|
116
|
-
nil
|
117
|
-
end
|
90
|
+
if json_value.keys.length != 1
|
91
|
+
raise JsonerError.new("JSON value #{json_value} should have only one key to represent union type, found #{json_value.keys.length}")
|
118
92
|
end
|
93
|
+
case_key = json_value.keys[0]
|
94
|
+
if not cases.key? case_key.to_sym
|
95
|
+
raise JsonerError.new("JSON key '#{case_key}' does not match any case in union type #{self}")
|
96
|
+
end
|
97
|
+
type = cases[case_key.to_sym]
|
98
|
+
case_json_value = json_value[case_key]
|
99
|
+
return Jsoner.deserialize(type, case_json_value)
|
100
|
+
end
|
101
|
+
def jsoner_serialize(value)
|
102
|
+
T.check(self, value)
|
103
|
+
type = types.find {|t| T.instance_of?(t, value) }
|
104
|
+
case_key = cases.key(type)
|
105
|
+
result = { case_key => Jsoner.serialize(type, value) }
|
106
|
+
result
|
119
107
|
end
|
108
|
+
end
|
120
109
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
json_value
|
110
|
+
T::Nilable.class_eval do
|
111
|
+
def jsoner_deserialize(json_value)
|
112
|
+
if json_value != nil
|
113
|
+
Jsoner.deserialize(self.type, json_value)
|
114
|
+
else
|
115
|
+
nil
|
125
116
|
end
|
126
|
-
|
127
|
-
|
117
|
+
end
|
118
|
+
def jsoner_serialize(value)
|
119
|
+
if value != nil
|
120
|
+
Jsoner.serialize(self.type, value)
|
121
|
+
else
|
122
|
+
nil
|
128
123
|
end
|
129
124
|
end
|
125
|
+
end
|
130
126
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
139
|
-
end
|
140
|
-
def self.jsoner_serialize(value)
|
141
|
-
T.check(DateTime, value)
|
142
|
-
value.strftime('%Y-%m-%dT%H:%M:%S')
|
143
|
-
end
|
127
|
+
module FloatSerializer
|
128
|
+
def self.jsoner_deserialize(json_value)
|
129
|
+
T.check(T.any(Float, Integer), json_value)
|
130
|
+
json_value.to_f
|
131
|
+
end
|
132
|
+
def self.jsoner_serialize(value)
|
133
|
+
T.check(Float, value)
|
144
134
|
end
|
135
|
+
end
|
145
136
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
end
|
154
|
-
end
|
155
|
-
def self.jsoner_serialize(value)
|
156
|
-
T.check(Date, value)
|
157
|
-
value.strftime('%Y-%m-%d')
|
137
|
+
module DateTimeSerializer
|
138
|
+
def self.jsoner_deserialize(json_value)
|
139
|
+
T.check(String, json_value)
|
140
|
+
begin
|
141
|
+
DateTime.strptime(json_value, '%Y-%m-%dT%H:%M:%S')
|
142
|
+
rescue
|
143
|
+
raise JsonerError.new("Failed to parse DateTime from '#{json_value.inspect.to_s}' format %Y-%m-%dT%H:%M:%S is required")
|
158
144
|
end
|
159
145
|
end
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
Date => DateSerializer,
|
164
|
-
DateTime => DateTimeSerializer
|
165
|
-
}
|
166
|
-
def self.add_serializer(type, serializer)
|
167
|
-
@@serializers[type] = serializer
|
146
|
+
def self.jsoner_serialize(value)
|
147
|
+
T.check(DateTime, value)
|
148
|
+
value.strftime('%Y-%m-%dT%H:%M:%S')
|
168
149
|
end
|
150
|
+
end
|
169
151
|
|
170
|
-
|
171
|
-
|
172
|
-
|
152
|
+
module DateSerializer
|
153
|
+
def self.jsoner_deserialize(json_value)
|
154
|
+
T.check(String, json_value)
|
155
|
+
begin
|
156
|
+
Date.strptime(json_value, '%Y-%m-%d')
|
157
|
+
rescue
|
158
|
+
raise JsonerError.new("Failed to parse Date from '#{json_value.inspect.to_s}' format %Y-%m-%d is required")
|
159
|
+
end
|
173
160
|
end
|
161
|
+
def self.jsoner_serialize(value)
|
162
|
+
T.check(Date, value)
|
163
|
+
value.strftime('%Y-%m-%d')
|
164
|
+
end
|
165
|
+
end
|
174
166
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
167
|
+
@@serializers = {
|
168
|
+
Float => FloatSerializer,
|
169
|
+
Date => DateSerializer,
|
170
|
+
DateTime => DateTimeSerializer
|
171
|
+
}
|
172
|
+
def self.add_serializer(type, serializer)
|
173
|
+
@@serializers[type] = serializer
|
174
|
+
end
|
175
|
+
|
176
|
+
def Jsoner.from_json(type, json)
|
177
|
+
data = JSON.parse(json)
|
178
|
+
return deserialize(type, data)
|
179
|
+
end
|
180
|
+
|
181
|
+
def Jsoner.deserialize(type, json_value)
|
182
|
+
begin
|
183
|
+
if type.methods.include? :jsoner_deserialize
|
184
|
+
return type.jsoner_deserialize(json_value)
|
185
|
+
elsif @@serializers.include? type
|
186
|
+
return @@serializers[type].jsoner_deserialize(json_value)
|
187
|
+
else
|
188
|
+
if ![String, Float, Integer, TrueClass, FalseClass, NilClass].include? type
|
189
|
+
raise JsonerError.new("Type #{type} is not supported in Jsoner deserialization")
|
186
190
|
end
|
187
|
-
|
188
|
-
raise JsonerError.new(error.message)
|
191
|
+
return T.check(type, json_value)
|
189
192
|
end
|
193
|
+
rescue StandardError => error
|
194
|
+
raise JsonerError.new(error.message)
|
190
195
|
end
|
196
|
+
end
|
191
197
|
|
192
|
-
|
193
|
-
|
194
|
-
|
198
|
+
def Jsoner.to_json(type, value)
|
199
|
+
JSON.dump(serialize(type, value))
|
200
|
+
end
|
195
201
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
end
|
206
|
-
return T.check(type, value)
|
202
|
+
def Jsoner.serialize(type, value)
|
203
|
+
begin
|
204
|
+
if type.methods.include? :jsoner_serialize
|
205
|
+
return type.jsoner_serialize(value)
|
206
|
+
elsif @@serializers.include? type
|
207
|
+
return @@serializers[type].jsoner_serialize(value)
|
208
|
+
else
|
209
|
+
if ![String, Float, Integer, TrueClass, FalseClass, NilClass].include? type
|
210
|
+
raise JsonerError.new("Type #{type} is not supported in Jsoner serialization")
|
207
211
|
end
|
208
|
-
|
209
|
-
raise JsonerError.new(error.message)
|
212
|
+
return T.check(type, value)
|
210
213
|
end
|
214
|
+
rescue StandardError => error
|
215
|
+
raise JsonerError.new(error.message)
|
211
216
|
end
|
212
217
|
end
|
213
218
|
end
|