datory 1.0.0.rc11 → 1.0.0.rc13
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/README.md +126 -3
- data/lib/datory/attributes/attribute.rb +70 -63
- data/lib/datory/attributes/collection.rb +16 -2
- data/lib/datory/attributes/descriptor.rb +7 -6
- data/lib/datory/attributes/deserialization/service_factory.rb +2 -18
- data/lib/datory/attributes/dsl.rb +28 -0
- data/lib/datory/attributes/options/base.rb +31 -0
- data/lib/datory/attributes/options/from.rb +15 -0
- data/lib/datory/attributes/options/to.rb +27 -0
- data/lib/datory/attributes/serialization/serializator.rb +7 -10
- data/lib/datory/attributes/serialization/service_factory.rb +2 -18
- data/lib/datory/base.rb +1 -0
- data/lib/datory/context/callable.rb +2 -2
- data/lib/datory/info/dsl.rb +27 -0
- data/lib/datory/info/result.rb +13 -0
- data/lib/datory/service/base.rb +6 -2
- data/lib/datory/service/builder.rb +64 -0
- data/lib/datory/version.rb +1 -1
- metadata +10 -6
- data/lib/datory/utils.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: ad1cc00d4916767ce4e99d5cd52cde2f9640c4ea536f602e0ade8e5008b61820
|
4
|
+
data.tar.gz: 012e57a2c905b6de960fb1cd32e1719f1f876c630cc77b37ea7e8ee31427dae8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 271166881cb4e4e5b673d05ed180b2a09e0523aab2739d9c8127894981b34d5d37486a74aaa029524f13dbb03206dbf924c96f7983f28a985738e41ae96b64f2
|
7
|
+
data.tar.gz: 0b5a6b6cbbf3db6f505ebf629ff33e2bd57f72d7840295cc35660fcba5f8ee497db538fb699b75a8db2676f6064bc67aa0533c78049dd958cb1a1e0573b6e559
|
data/README.md
CHANGED
@@ -44,7 +44,7 @@ class UserDto < Datory::Base
|
|
44
44
|
string :phone
|
45
45
|
string :website
|
46
46
|
|
47
|
-
|
47
|
+
date :birthDate, to: :birth_date
|
48
48
|
|
49
49
|
one :login, include: UserLoginDto
|
50
50
|
one :company, include: UserCompanyDto
|
@@ -62,16 +62,139 @@ class UserLoginDto < Datory::Base
|
|
62
62
|
|
63
63
|
string :md5
|
64
64
|
string :sha1
|
65
|
+
|
66
|
+
duration :lifetime
|
65
67
|
|
66
|
-
|
68
|
+
datetime :registered_at
|
67
69
|
end
|
68
70
|
```
|
69
71
|
|
72
|
+
## Attribute declaration
|
73
|
+
|
74
|
+
### Basic
|
75
|
+
|
76
|
+
#### attribute
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
attribute :firstname, from: String, to: :first_name, as: String
|
80
|
+
```
|
81
|
+
|
82
|
+
#### string
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
string :first_name
|
86
|
+
```
|
87
|
+
|
88
|
+
#### integer
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
integer :attempts, min: 1, max: 10
|
92
|
+
```
|
93
|
+
|
94
|
+
#### float
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
float :interest_rate
|
98
|
+
```
|
99
|
+
|
100
|
+
### Helpers
|
101
|
+
|
102
|
+
#### uuid
|
103
|
+
|
104
|
+
It will also check that the value matches the UUID format.
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
uuid :id
|
108
|
+
```
|
109
|
+
|
110
|
+
#### money
|
111
|
+
|
112
|
+
It will prepare two attributes `*_cents` and `*_currency`.
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
money :price
|
116
|
+
```
|
117
|
+
|
118
|
+
#### duration
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
duration :lifetime
|
122
|
+
```
|
123
|
+
|
124
|
+
#### date
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
date :birth_date
|
128
|
+
```
|
129
|
+
|
130
|
+
#### time
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
time :registered_at
|
134
|
+
```
|
135
|
+
|
136
|
+
#### datetime
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
datetime :registered_at
|
140
|
+
```
|
141
|
+
|
142
|
+
### Nesting
|
143
|
+
|
144
|
+
#### one
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
one :company, include: UserCompanyDto
|
148
|
+
```
|
149
|
+
|
150
|
+
#### many
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
many :addresses, include: UserAddressDto
|
154
|
+
```
|
155
|
+
|
156
|
+
## Object information
|
157
|
+
|
158
|
+
### Info
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
UserDto.info
|
162
|
+
```
|
163
|
+
|
164
|
+
```
|
165
|
+
#<Datory::Info::Result:0x000000011eecd7d0 @attributes={:id=>{:from=>{:name=>:id, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:uuid}, :to=>{:name=>:id, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:uuid, :required=>true, :include=>nil}}, :firstname=>{:from=>{:name=>:firstname, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:first_name, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}, :lastname=>{:from=>{:name=>:lastname, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:last_name, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}, :email=>{:from=>{:name=>:email, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:email, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}, :phone=>{:from=>{:name=>:phone, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:phone, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}, :website=>{:from=>{:name=>:website, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:website, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}, :birthDate=>{:from=>{:name=>:birthDate, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:date}, :to=>{:name=>:birth_date, :type=>Date, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}, :login=>{:from=>{:name=>:login, :type=>Hash, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:login, :type=>[Datory::Result, Hash], :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>Usual::Example1::UserLogin}}, :company=>{:from=>{:name=>:company, :type=>Hash, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:company, :type=>[Datory::Result, Hash], :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>Usual::Example1::UserCompany}}, :addresses=>{:from=>{:name=>:addresses, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Datory::Result, Hash], :format=>nil}, :to=>{:name=>:addresses, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Datory::Result, Hash], :format=>nil, :required=>true, :include=>Usual::Example1::UserAddress}}}>
|
166
|
+
```
|
167
|
+
|
168
|
+
### Describe
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
UserDto.describe
|
172
|
+
```
|
173
|
+
|
174
|
+
```
|
175
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
176
|
+
| UserDto |
|
177
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
178
|
+
| Attribute | From | To | As | Include |
|
179
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
180
|
+
| id | String | id | String | |
|
181
|
+
| firstname | String | first_name | String | |
|
182
|
+
| lastname | String | last_name | String | |
|
183
|
+
| email | String | email | String | |
|
184
|
+
| phone | String | phone | String | |
|
185
|
+
| website | String | website | String | |
|
186
|
+
| birthDate | String | birth_date | Date | |
|
187
|
+
| login | Hash | login | [Datory::Result, Hash] | Usual::Example1::UserLogin |
|
188
|
+
| company | Hash | company | [Datory::Result, Hash] | Usual::Example1::UserCompany |
|
189
|
+
| addresses | Array | addresses | Array | Usual::Example1::UserAddress |
|
190
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
191
|
+
```
|
192
|
+
|
70
193
|
## Contributing
|
71
194
|
|
72
195
|
This project is intended to be a safe, welcoming space for collaboration.
|
73
196
|
Contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
74
|
-
We recommend reading the [contributing guide](./
|
197
|
+
We recommend reading the [contributing guide](./CONTRIBUTING.md) as well.
|
75
198
|
|
76
199
|
## License
|
77
200
|
|
@@ -3,97 +3,104 @@
|
|
3
3
|
module Datory
|
4
4
|
module Attributes
|
5
5
|
class Attribute
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :from, :to
|
7
7
|
|
8
|
-
def initialize(name, **options)
|
9
|
-
@
|
10
|
-
|
8
|
+
def initialize(name, **options) # rubocop:disable Metrics/MethodLength
|
9
|
+
@from = Options::From.new(
|
10
|
+
name: name,
|
11
|
+
type: options.fetch(:from),
|
12
|
+
consists_of: options.fetch(:consists_of, false),
|
13
|
+
min: options.fetch(:min, nil),
|
14
|
+
max: options.fetch(:max, nil),
|
15
|
+
format: options.fetch(:format, nil)
|
16
|
+
)
|
17
|
+
|
18
|
+
@to = Options::To.new(
|
19
|
+
name: options.fetch(:to, name),
|
20
|
+
type: options.fetch(:as, @from.type),
|
21
|
+
# TODO: It is necessary to implement NilClass support for optional
|
22
|
+
required: options.fetch(:required, true),
|
23
|
+
consists_of: @from.consists_of,
|
24
|
+
min: @from.min,
|
25
|
+
max: @from.max,
|
26
|
+
format: options.fetch(:format, nil),
|
27
|
+
include_class: options.fetch(:include, nil)
|
28
|
+
)
|
11
29
|
end
|
12
30
|
|
13
|
-
|
31
|
+
##########################################################################
|
32
|
+
|
33
|
+
def input_serialization_options # rubocop:disable Metrics/AbcSize
|
14
34
|
hash = {
|
15
|
-
as:
|
16
|
-
type:
|
17
|
-
required:
|
18
|
-
consists_of:
|
35
|
+
as: to.name,
|
36
|
+
type: to.type,
|
37
|
+
required: to.required,
|
38
|
+
consists_of: to.consists_of
|
19
39
|
}
|
20
40
|
|
21
|
-
|
22
|
-
|
23
|
-
|
41
|
+
hash[:min] = to.min if to.min.present?
|
42
|
+
|
43
|
+
hash[:max] = to.max if to.max.present?
|
44
|
+
|
45
|
+
hash[:format] = to.format if to.format.present?
|
24
46
|
|
25
47
|
hash
|
26
48
|
end
|
27
49
|
|
28
|
-
def
|
50
|
+
def output_serialization_options # rubocop:disable Metrics/AbcSize
|
29
51
|
hash = {
|
30
|
-
|
31
|
-
type:
|
32
|
-
|
33
|
-
consists_of: options.fetch(:consists_of, false),
|
34
|
-
prepare: (lambda do |value:|
|
35
|
-
include_class = options.fetch(:include, nil)
|
36
|
-
return value unless include_class.present?
|
52
|
+
consists_of: to.consists_of == Hash ? Datory::Result : from.consists_of,
|
53
|
+
type: to.type == Datory::Result ? Hash : from.type
|
54
|
+
}
|
37
55
|
|
38
|
-
|
56
|
+
hash[:min] = from.min if from.min.present?
|
39
57
|
|
40
|
-
|
41
|
-
value.map { |item| include_class.deserialize(**item) }
|
42
|
-
else
|
43
|
-
include_class.deserialize(**value)
|
44
|
-
end
|
45
|
-
end)
|
46
|
-
}
|
58
|
+
hash[:max] = from.max if from.max.present?
|
47
59
|
|
48
|
-
|
49
|
-
hash[:format] = format
|
50
|
-
end
|
60
|
+
hash[:format] = from.format if from.format.present?
|
51
61
|
|
52
62
|
hash
|
53
63
|
end
|
54
64
|
|
55
|
-
|
65
|
+
##########################################################################
|
66
|
+
|
67
|
+
def input_deserialization_options # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
56
68
|
hash = {
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
as: to.name,
|
70
|
+
type: from.type,
|
71
|
+
required: to.required,
|
72
|
+
consists_of: from.consists_of,
|
73
|
+
prepare: (lambda do |value:|
|
74
|
+
return value unless to.include_class.present?
|
75
|
+
|
76
|
+
if [Set, Array].include?(from.type)
|
77
|
+
value.map { |item| to.include_class.deserialize(**item) }
|
78
|
+
else
|
79
|
+
to.include_class.deserialize(**value)
|
80
|
+
end
|
81
|
+
end)
|
69
82
|
}
|
70
83
|
|
71
|
-
|
72
|
-
|
73
|
-
|
84
|
+
hash[:min] = from.min if from.min.present?
|
85
|
+
|
86
|
+
hash[:max] = from.max if from.max.present?
|
87
|
+
|
88
|
+
hash[:format] = from.format if from.format.present?
|
74
89
|
|
75
90
|
hash
|
76
91
|
end
|
77
92
|
|
78
|
-
def output_deserialization_options # rubocop:disable Metrics/
|
93
|
+
def output_deserialization_options # rubocop:disable Metrics/AbcSize
|
79
94
|
hash = {
|
80
|
-
consists_of:
|
81
|
-
|
82
|
-
else
|
83
|
-
consists_of_type
|
84
|
-
end,
|
85
|
-
type: if (from_type = options.fetch(:from)) == Hash
|
86
|
-
Datory::Result
|
87
|
-
elsif (option_as = options.fetch(:as, nil)).present?
|
88
|
-
option_as
|
89
|
-
else
|
90
|
-
from_type
|
91
|
-
end
|
95
|
+
consists_of: from.consists_of == Hash ? Datory::Result : to.consists_of,
|
96
|
+
type: from.type == Hash ? Datory::Result : to.type
|
92
97
|
}
|
93
98
|
|
94
|
-
|
95
|
-
|
96
|
-
|
99
|
+
hash[:min] = to.min if to.min.present?
|
100
|
+
|
101
|
+
hash[:max] = to.max if to.max.present?
|
102
|
+
|
103
|
+
hash[:format] = to.format if to.format.present?
|
97
104
|
|
98
105
|
hash
|
99
106
|
end
|
@@ -4,7 +4,7 @@ module Datory
|
|
4
4
|
module Attributes
|
5
5
|
class Collection
|
6
6
|
extend Forwardable
|
7
|
-
def_delegators :@collection, :<<, :each, :map, :to_h, :merge
|
7
|
+
def_delegators :@collection, :<<, :each, :map, :filter, :to_h, :merge
|
8
8
|
|
9
9
|
def initialize(collection = Set.new)
|
10
10
|
@collection = collection
|
@@ -15,7 +15,21 @@ module Datory
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def internal_names
|
18
|
-
map { |attribute| attribute.
|
18
|
+
map { |attribute| attribute.to.name }
|
19
|
+
end
|
20
|
+
|
21
|
+
def include_class_exist?
|
22
|
+
@include_class_exist ||= filter do |attribute| # rubocop:disable Performance/Count
|
23
|
+
include_class = attribute.to.include_class
|
24
|
+
|
25
|
+
next false if include_class.nil?
|
26
|
+
|
27
|
+
if [Set, Array].include?(include_class)
|
28
|
+
include_class.any? { |item| item <= Datory::Base }
|
29
|
+
else
|
30
|
+
include_class <= Datory::Base
|
31
|
+
end
|
32
|
+
end.size.positive?
|
19
33
|
end
|
20
34
|
end
|
21
35
|
end
|
@@ -15,17 +15,18 @@ module Datory
|
|
15
15
|
headings << "From"
|
16
16
|
headings << "To"
|
17
17
|
headings << "As"
|
18
|
+
headings << "Include" if collection_of_attributes.include_class_exist?
|
18
19
|
|
19
20
|
collection_of_attributes.each do |attribute|
|
20
21
|
row = []
|
21
22
|
|
22
|
-
|
23
|
+
include_class = attribute.to.include_class.presence || attribute.from.type
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
row <<
|
27
|
-
row << attribute.
|
28
|
-
row <<
|
25
|
+
row << attribute.from.name
|
26
|
+
row << attribute.from.type
|
27
|
+
row << attribute.to.name
|
28
|
+
row << attribute.to.type
|
29
|
+
row << (include_class if include_class <= Datory::Base) if collection_of_attributes.include_class_exist?
|
29
30
|
|
30
31
|
rows << row
|
31
32
|
end
|
@@ -21,28 +21,12 @@ module Datory
|
|
21
21
|
@model_class.const_set(ServiceBuilder::SERVICE_CLASS_NAME, class_sample)
|
22
22
|
end
|
23
23
|
|
24
|
-
def create_service_class
|
24
|
+
def create_service_class
|
25
25
|
collection_of_attributes = @collection_of_attributes
|
26
26
|
|
27
27
|
Class.new(Datory::Service::Builder) do
|
28
28
|
collection_of_attributes.each do |attribute|
|
29
|
-
|
30
|
-
|
31
|
-
input attribute.name, **attribute.input_deserialization_options
|
32
|
-
|
33
|
-
output input_internal_name, **attribute.output_deserialization_options
|
34
|
-
|
35
|
-
make :"assign_#{input_internal_name}_output"
|
36
|
-
|
37
|
-
define_method(:"assign_#{input_internal_name}_output") do
|
38
|
-
value = inputs.public_send(input_internal_name)
|
39
|
-
|
40
|
-
type_as = attribute.options.fetch(:as, nil)
|
41
|
-
|
42
|
-
value = Datory::Utils.transform_value_with(:d, value, type_as)
|
43
|
-
|
44
|
-
outputs.public_send(:"#{input_internal_name}=", value)
|
45
|
-
end
|
29
|
+
prepare_deserialization_data_for(attribute)
|
46
30
|
end
|
47
31
|
end
|
48
32
|
end
|
@@ -51,6 +51,34 @@ module Datory
|
|
51
51
|
string(name, **options)
|
52
52
|
end
|
53
53
|
|
54
|
+
def money(name, **options)
|
55
|
+
options_for_cents = options.merge(from: Integer)
|
56
|
+
options_for_currency = options.merge(from: [Symbol, String])
|
57
|
+
|
58
|
+
attribute(:"#{name}_cents", **options_for_cents)
|
59
|
+
attribute(:"#{name}_currency", **options_for_currency)
|
60
|
+
end
|
61
|
+
|
62
|
+
def duration(name, **options)
|
63
|
+
options = options.merge(from: String, as: ActiveSupport::Duration, format: { from: :duration })
|
64
|
+
string(name, **options)
|
65
|
+
end
|
66
|
+
|
67
|
+
def date(name, **options)
|
68
|
+
options = options.merge(from: String, as: Date, format: { from: :date })
|
69
|
+
string(name, **options)
|
70
|
+
end
|
71
|
+
|
72
|
+
def time(name, **options)
|
73
|
+
options = options.merge(from: String, as: Time, format: { from: :time })
|
74
|
+
string(name, **options)
|
75
|
+
end
|
76
|
+
|
77
|
+
def datetime(name, **options)
|
78
|
+
options = options.merge(from: String, as: DateTime, format: { from: :datetime })
|
79
|
+
string(name, **options)
|
80
|
+
end
|
81
|
+
|
54
82
|
########################################################################
|
55
83
|
|
56
84
|
def string(name, **options)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datory
|
4
|
+
module Attributes
|
5
|
+
module Options
|
6
|
+
class Base
|
7
|
+
attr_reader :name, :type, :consists_of, :min, :max, :format
|
8
|
+
|
9
|
+
def initialize(name:, type:, consists_of:, min:, max:, format:)
|
10
|
+
@name = name
|
11
|
+
@type = type
|
12
|
+
@consists_of = consists_of
|
13
|
+
@min = min
|
14
|
+
@max = max
|
15
|
+
@format = format
|
16
|
+
end
|
17
|
+
|
18
|
+
def info
|
19
|
+
{
|
20
|
+
name: name,
|
21
|
+
type: type,
|
22
|
+
min: min,
|
23
|
+
max: max,
|
24
|
+
consists_of: consists_of,
|
25
|
+
format: format
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datory
|
4
|
+
module Attributes
|
5
|
+
module Options
|
6
|
+
class From < Base
|
7
|
+
def initialize(name:, type:, consists_of:, min:, max:, format:)
|
8
|
+
format = format.fetch(:from, nil) if format.is_a?(Hash)
|
9
|
+
|
10
|
+
super(name: name, type: type, consists_of: consists_of, min: min, max: max, format: format)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datory
|
4
|
+
module Attributes
|
5
|
+
module Options
|
6
|
+
class To < Base
|
7
|
+
attr_reader :required, :include_class
|
8
|
+
|
9
|
+
def initialize(name:, type:, required:, consists_of:, min:, max:, format:, include_class:)
|
10
|
+
@required = required
|
11
|
+
@include_class = include_class
|
12
|
+
|
13
|
+
format = format.fetch(:to, nil) if format.is_a?(Hash)
|
14
|
+
|
15
|
+
super(name: name, type: type, consists_of: consists_of, min: min, max: max, format: format)
|
16
|
+
end
|
17
|
+
|
18
|
+
def info
|
19
|
+
super.merge(
|
20
|
+
required: required,
|
21
|
+
include: include_class
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -20,23 +20,20 @@ module Datory
|
|
20
20
|
end
|
21
21
|
else
|
22
22
|
@collection_of_attributes.to_h do |attribute|
|
23
|
-
attribute.
|
24
|
-
|
25
|
-
output_formatter = attribute.options.fetch(:output, nil)
|
23
|
+
include_class = attribute.to.include_class
|
24
|
+
# output_formatter = attribute.options.fetch(:output, nil) # TODO
|
26
25
|
|
27
|
-
value = model.public_send(attribute.name)
|
26
|
+
value = model.public_send(attribute.from.name)
|
28
27
|
|
29
28
|
value =
|
30
29
|
if include_class.present?
|
31
|
-
|
32
|
-
|
33
|
-
if [Set, Array].include?(from_type)
|
30
|
+
if [Set, Array].include?(attribute.from.type)
|
34
31
|
value.map { |item| include_class.serialize(item) }
|
35
32
|
else
|
36
33
|
include_class.serialize(value)
|
37
34
|
end
|
38
|
-
elsif output_formatter.is_a?(Proc)
|
39
|
-
|
35
|
+
# elsif output_formatter.is_a?(Proc) # TODO
|
36
|
+
# output_formatter.call(value: value)
|
40
37
|
elsif [Date, Time, DateTime].include?(value.class)
|
41
38
|
value.to_s
|
42
39
|
elsif value.instance_of?(ActiveSupport::Duration)
|
@@ -45,7 +42,7 @@ module Datory
|
|
45
42
|
value
|
46
43
|
end
|
47
44
|
|
48
|
-
[attribute.name, value]
|
45
|
+
[attribute.from.name, value]
|
49
46
|
end
|
50
47
|
end
|
51
48
|
end
|
@@ -21,28 +21,12 @@ module Datory
|
|
21
21
|
@model_class.const_set(ServiceBuilder::SERVICE_CLASS_NAME, class_sample)
|
22
22
|
end
|
23
23
|
|
24
|
-
def create_service_class
|
24
|
+
def create_service_class
|
25
25
|
collection_of_attributes = @collection_of_attributes
|
26
26
|
|
27
27
|
Class.new(Datory::Service::Builder) do
|
28
28
|
collection_of_attributes.each do |attribute|
|
29
|
-
|
30
|
-
|
31
|
-
input input_internal_name, **attribute.input_serialization_options
|
32
|
-
|
33
|
-
output attribute.name, **attribute.output_serialization_options
|
34
|
-
|
35
|
-
make :"assign_#{attribute.name}_output"
|
36
|
-
|
37
|
-
define_method(:"assign_#{attribute.name}_output") do
|
38
|
-
value = inputs.public_send(input_internal_name)
|
39
|
-
|
40
|
-
from_type = attribute.options.fetch(:from)
|
41
|
-
|
42
|
-
value = Datory::Utils.transform_value_with(:s, value, from_type)
|
43
|
-
|
44
|
-
outputs.public_send(:"#{attribute.name}=", value)
|
45
|
-
end
|
29
|
+
prepare_serialization_data_for(attribute)
|
46
30
|
end
|
47
31
|
end
|
48
32
|
end
|
data/lib/datory/base.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Datory
|
4
4
|
module Context
|
5
5
|
module Callable
|
6
|
-
def serialize(model)
|
6
|
+
def serialize(model) # rubocop:disable Metrics/MethodLength
|
7
7
|
if [Set, Array].include?(model.class)
|
8
8
|
model.map do |model_item|
|
9
9
|
serialize(model_item)
|
@@ -19,7 +19,7 @@ module Datory
|
|
19
19
|
raise Datory::Exceptions::SerializationError.new(message: e.message)
|
20
20
|
end
|
21
21
|
|
22
|
-
def deserialize(json)
|
22
|
+
def deserialize(json) # rubocop:disable Metrics/MethodLength
|
23
23
|
if [Set, Array].include?(json.class)
|
24
24
|
json.map do |json_item|
|
25
25
|
deserialize(json_item)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datory
|
4
|
+
module Info
|
5
|
+
module DSL
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def info # rubocop:disable Metrics/MethodLength
|
12
|
+
Datory::Info::Result.new(
|
13
|
+
attributes: collection_of_attributes.to_h do |attribute|
|
14
|
+
[
|
15
|
+
attribute.from.name,
|
16
|
+
{
|
17
|
+
from: attribute.from.info,
|
18
|
+
to: attribute.to.info
|
19
|
+
}
|
20
|
+
]
|
21
|
+
end
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/datory/service/base.rb
CHANGED
@@ -15,11 +15,15 @@ module Datory
|
|
15
15
|
result_class Datory::Result
|
16
16
|
|
17
17
|
input_option_helpers [
|
18
|
-
Servactory::ToolKit::DynamicOptions::Format.use
|
18
|
+
Servactory::ToolKit::DynamicOptions::Format.use,
|
19
|
+
Servactory::ToolKit::DynamicOptions::Min.use,
|
20
|
+
Servactory::ToolKit::DynamicOptions::Max.use
|
19
21
|
]
|
20
22
|
|
21
23
|
output_option_helpers [
|
22
|
-
Servactory::ToolKit::DynamicOptions::Format.use
|
24
|
+
Servactory::ToolKit::DynamicOptions::Format.use,
|
25
|
+
Servactory::ToolKit::DynamicOptions::Min.use,
|
26
|
+
Servactory::ToolKit::DynamicOptions::Max.use
|
23
27
|
]
|
24
28
|
|
25
29
|
predicate_methods_enabled false
|
@@ -3,6 +3,70 @@
|
|
3
3
|
module Datory
|
4
4
|
module Service
|
5
5
|
class Builder < Base
|
6
|
+
TRANSFORMATIONS = {
|
7
|
+
SERIALIZATION: {
|
8
|
+
Symbol => ->(value) { value.to_sym },
|
9
|
+
String => ->(value) { value.to_s },
|
10
|
+
Integer => ->(value) { value.to_i },
|
11
|
+
Float => ->(value) { value.to_f },
|
12
|
+
Date => ->(value) { value.to_s },
|
13
|
+
Time => ->(value) { value.to_s },
|
14
|
+
DateTime => ->(value) { value.to_s },
|
15
|
+
ActiveSupport::Duration => ->(value) { value.iso8601 }
|
16
|
+
},
|
17
|
+
DESERIALIZATION: {
|
18
|
+
Symbol => ->(value) { value.to_sym },
|
19
|
+
String => ->(value) { value.to_s },
|
20
|
+
Integer => ->(value) { value.to_i },
|
21
|
+
Float => ->(value) { value.to_f },
|
22
|
+
Date => ->(value) { Date.parse(value) },
|
23
|
+
Time => ->(value) { Time.parse(value) },
|
24
|
+
DateTime => ->(value) { DateTime.parse(value) },
|
25
|
+
ActiveSupport::Duration => ->(value) { ActiveSupport::Duration.parse(value) }
|
26
|
+
}
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
private_constant :TRANSFORMATIONS
|
30
|
+
|
31
|
+
def self.prepare_serialization_data_for(attribute) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
32
|
+
serialized_name = attribute.from.name
|
33
|
+
deserialized_name = attribute.to.name
|
34
|
+
method_name = :"assign_#{serialized_name}_output"
|
35
|
+
|
36
|
+
input deserialized_name, **attribute.input_serialization_options
|
37
|
+
|
38
|
+
output serialized_name, **attribute.output_serialization_options
|
39
|
+
|
40
|
+
make method_name
|
41
|
+
|
42
|
+
define_method(method_name) do
|
43
|
+
value = inputs.public_send(deserialized_name)
|
44
|
+
|
45
|
+
value = TRANSFORMATIONS.fetch(:SERIALIZATION).fetch(value.class, ->(v) { v }).call(value)
|
46
|
+
|
47
|
+
outputs.public_send(:"#{serialized_name}=", value)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.prepare_deserialization_data_for(attribute) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
52
|
+
serialized_name = attribute.from.name
|
53
|
+
deserialized_name = attribute.to.name
|
54
|
+
method_name = :"assign_#{deserialized_name}_output"
|
55
|
+
|
56
|
+
input serialized_name, **attribute.input_deserialization_options
|
57
|
+
|
58
|
+
output deserialized_name, **attribute.output_deserialization_options
|
59
|
+
|
60
|
+
make method_name
|
61
|
+
|
62
|
+
define_method(method_name) do
|
63
|
+
value = inputs.public_send(deserialized_name)
|
64
|
+
|
65
|
+
value = TRANSFORMATIONS.fetch(:DESERIALIZATION).fetch(attribute.to.type, ->(v) { v }).call(value)
|
66
|
+
|
67
|
+
outputs.public_send(:"#{deserialized_name}=", value)
|
68
|
+
end
|
69
|
+
end
|
6
70
|
end
|
7
71
|
end
|
8
72
|
end
|
data/lib/datory/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.rc13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton Sokolov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - '='
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 2.5.0.
|
53
|
+
version: 2.5.0.rc7
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - '='
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 2.5.0.
|
60
|
+
version: 2.5.0.rc7
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: terminal-table
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -216,6 +216,9 @@ files:
|
|
216
216
|
- lib/datory/attributes/deserialization/service_builder.rb
|
217
217
|
- lib/datory/attributes/deserialization/service_factory.rb
|
218
218
|
- lib/datory/attributes/dsl.rb
|
219
|
+
- lib/datory/attributes/options/base.rb
|
220
|
+
- lib/datory/attributes/options/from.rb
|
221
|
+
- lib/datory/attributes/options/to.rb
|
219
222
|
- lib/datory/attributes/serialization/model.rb
|
220
223
|
- lib/datory/attributes/serialization/serializator.rb
|
221
224
|
- lib/datory/attributes/serialization/service_builder.rb
|
@@ -228,11 +231,12 @@ files:
|
|
228
231
|
- lib/datory/context/workspace.rb
|
229
232
|
- lib/datory/engine.rb
|
230
233
|
- lib/datory/exceptions.rb
|
234
|
+
- lib/datory/info/dsl.rb
|
235
|
+
- lib/datory/info/result.rb
|
231
236
|
- lib/datory/result.rb
|
232
237
|
- lib/datory/service/base.rb
|
233
238
|
- lib/datory/service/builder.rb
|
234
239
|
- lib/datory/service/exceptions.rb
|
235
|
-
- lib/datory/utils.rb
|
236
240
|
- lib/datory/version.rb
|
237
241
|
homepage: https://github.com/servactory/datory
|
238
242
|
licenses:
|
@@ -259,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
259
263
|
- !ruby/object:Gem::Version
|
260
264
|
version: '0'
|
261
265
|
requirements: []
|
262
|
-
rubygems_version: 3.5.
|
266
|
+
rubygems_version: 3.5.9
|
263
267
|
signing_key:
|
264
268
|
specification_version: 4
|
265
269
|
summary: A set of tools for building reliable services of any complexity
|
data/lib/datory/utils.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Datory
|
4
|
-
module Utils
|
5
|
-
module_function
|
6
|
-
|
7
|
-
D_TRANSFORMATIONS = {
|
8
|
-
Symbol => ->(value) { value.to_sym },
|
9
|
-
String => ->(value) { value.to_s },
|
10
|
-
Integer => ->(value) { value.to_i },
|
11
|
-
Float => ->(value) { value.to_f },
|
12
|
-
Date => ->(value) { Date.parse(value) },
|
13
|
-
Time => ->(value) { Time.parse(value) },
|
14
|
-
DateTime => ->(value) { DateTime.parse(value) },
|
15
|
-
ActiveSupport::Duration => ->(value) { ActiveSupport::Duration.parse(value) }
|
16
|
-
}.freeze
|
17
|
-
|
18
|
-
private_constant :D_TRANSFORMATIONS
|
19
|
-
|
20
|
-
S_TRANSFORMATIONS = {
|
21
|
-
Symbol => ->(value, _type) { value.to_sym },
|
22
|
-
String => ->(value, _type) { value.to_s },
|
23
|
-
Integer => ->(value, _type) { value.to_i },
|
24
|
-
Float => ->(value, _type) { value.to_f },
|
25
|
-
Date => ->(value, _type) { value.to_s },
|
26
|
-
Time => ->(value, _type) { value.to_s },
|
27
|
-
DateTime => ->(value, _type) { value.to_s },
|
28
|
-
ActiveSupport::Duration => ->(value, _type) { value.iso8601 }
|
29
|
-
}.freeze
|
30
|
-
|
31
|
-
private_constant :S_TRANSFORMATIONS
|
32
|
-
|
33
|
-
def transform_value_with(format, value, type)
|
34
|
-
if format == :d
|
35
|
-
D_TRANSFORMATIONS.fetch(type, ->(v) { v }).call(value)
|
36
|
-
else
|
37
|
-
S_TRANSFORMATIONS.fetch(value.class, ->(v, _type) { v }).call(value, type)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|