emery 0.0.1 → 0.0.7
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 +172 -142
- data/lib/emery/type.rb +151 -142
- data/test/dataclass_test.rb +80 -83
- data/test/enum_test.rb +29 -33
- data/test/jsoner_test.rb +222 -176
- data/test/type_test.rb +162 -129
- 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: 924ace300767e7dd836ccdc9084bd9752d5e068b39889452b8a1d1d2e8dfccfc
|
|
4
|
+
data.tar.gz: e979657cad032c4d3025269a43614cea3400eb2f2505d429922c362a9a014221
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b1833b10580a5c01ea37bba0ba6072fb76151f02fa12b69c235b181313ada403de9b4e32b8813b87bcf1bee0d4f08c32f8e0830e73ee1a3679712250521c8ea
|
|
7
|
+
data.tar.gz: '06908264f18d6c01636280541627217126df75a9a1aeb64840eca4a000a73beb2d9809690e749e907455b5fc6473f0aee9ed0c845c4e4f81d795415af0be8b32'
|
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,188 +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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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")
|
|
47
|
+
end
|
|
48
|
+
if !json_value.is_a?(Hash)
|
|
49
|
+
raise JsonerError.new("JSON value type #{json_value.class} is not Hash")
|
|
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
|
|
54
|
+
end
|
|
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")
|
|
48
58
|
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
|
|
59
|
+
if !value.is_a?(Hash)
|
|
60
|
+
raise JsonerError.new("Value type #{value.class} is not Hash")
|
|
59
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
|
|
60
65
|
end
|
|
66
|
+
end
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
end
|
|
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
|
|
69
74
|
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(', ')}")
|
|
71
|
-
end
|
|
72
|
-
def jsoner_serialize(value)
|
|
73
|
-
T.check(self, value)
|
|
74
|
-
type = types.find {|t| T.instance_of?(t, value) }
|
|
75
|
-
Jsoner.serialize(type, value)
|
|
76
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(', ')}")
|
|
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)
|
|
77
82
|
end
|
|
83
|
+
end
|
|
78
84
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
else
|
|
84
|
-
nil
|
|
85
|
-
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")
|
|
86
89
|
end
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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}")
|
|
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}")
|
|
93
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)
|
|
94
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
|
|
107
|
+
end
|
|
108
|
+
end
|
|
95
109
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
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
|
|
100
116
|
end
|
|
101
|
-
|
|
102
|
-
|
|
117
|
+
end
|
|
118
|
+
def jsoner_serialize(value)
|
|
119
|
+
if value != nil
|
|
120
|
+
Jsoner.serialize(self.type, value)
|
|
121
|
+
else
|
|
122
|
+
nil
|
|
103
123
|
end
|
|
104
124
|
end
|
|
125
|
+
end
|
|
105
126
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
def self.jsoner_serialize(value)
|
|
116
|
-
T.check(DateTime, value)
|
|
117
|
-
value.strftime('%Y-%m-%dT%H:%M:%S')
|
|
118
|
-
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)
|
|
119
134
|
end
|
|
135
|
+
end
|
|
120
136
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
def self.jsoner_serialize(value)
|
|
131
|
-
T.check(Date, value)
|
|
132
|
-
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")
|
|
133
144
|
end
|
|
134
145
|
end
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Date => DateSerializer,
|
|
139
|
-
DateTime => DateTimeSerializer
|
|
140
|
-
}
|
|
141
|
-
def self.add_serializer(type, serializer)
|
|
142
|
-
@@serializers[type] = serializer
|
|
146
|
+
def self.jsoner_serialize(value)
|
|
147
|
+
T.check(DateTime, value)
|
|
148
|
+
value.strftime('%Y-%m-%dT%H:%M:%S')
|
|
143
149
|
end
|
|
150
|
+
end
|
|
144
151
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
|
148
160
|
end
|
|
161
|
+
def self.jsoner_serialize(value)
|
|
162
|
+
T.check(Date, value)
|
|
163
|
+
value.strftime('%Y-%m-%d')
|
|
164
|
+
end
|
|
165
|
+
end
|
|
149
166
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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")
|
|
161
190
|
end
|
|
162
|
-
|
|
163
|
-
raise JsonerError.new(error.message)
|
|
191
|
+
return T.check(type, json_value)
|
|
164
192
|
end
|
|
193
|
+
rescue StandardError => error
|
|
194
|
+
raise JsonerError.new(error.message)
|
|
165
195
|
end
|
|
196
|
+
end
|
|
166
197
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
198
|
+
def Jsoner.to_json(type, value)
|
|
199
|
+
JSON.dump(serialize(type, value))
|
|
200
|
+
end
|
|
170
201
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
end
|
|
181
|
-
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")
|
|
182
211
|
end
|
|
183
|
-
|
|
184
|
-
raise JsonerError.new(error.message)
|
|
212
|
+
return T.check(type, value)
|
|
185
213
|
end
|
|
214
|
+
rescue StandardError => error
|
|
215
|
+
raise JsonerError.new(error.message)
|
|
186
216
|
end
|
|
187
217
|
end
|
|
188
218
|
end
|