datory 1.0.0.rc11 → 1.0.0.rc13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ef2274984450ba2915867f37000b443ffd18a51eeb497adecaaaeae7d0821ae
4
- data.tar.gz: ddab73410ef68b0a65f02ed24f9e7177ea43f6779015aa9f5208d4583f8f2882
3
+ metadata.gz: ad1cc00d4916767ce4e99d5cd52cde2f9640c4ea536f602e0ade8e5008b61820
4
+ data.tar.gz: 012e57a2c905b6de960fb1cd32e1719f1f876c630cc77b37ea7e8ee31427dae8
5
5
  SHA512:
6
- metadata.gz: 0c794e11db75f222df975ddf31d0e0c9ff2c37ed7dc33e9c6707a5addfd53c12265f45b8808a3c5d7eebbf426674ccf8442bc3f74ec367ee4f67467ed8e0ea51
7
- data.tar.gz: 235ed83fe57e9db74fb93803e83820ecba0aea31a673ede0ae6b485a8d4c219394cf1cd0ceb04efd06048e554039105a05538fda8eb520404f9eaf7bb904c1fd
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
- string :birthDate, to: :birth_date, as: Date
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
- string :registered_at, as: DateTime
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](./website/docs/CONTRIBUTING.md) as well.
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 :name, :options
6
+ attr_reader :from, :to
7
7
 
8
- def initialize(name, **options)
9
- @name = name
10
- @options = options
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
- def input_serialization_options
31
+ ##########################################################################
32
+
33
+ def input_serialization_options # rubocop:disable Metrics/AbcSize
14
34
  hash = {
15
- as: options.fetch(:to, name),
16
- type: options.fetch(:as, options.fetch(:from)),
17
- required: options.fetch(:required, true),
18
- consists_of: options.fetch(:consists_of, false)
35
+ as: to.name,
36
+ type: to.type,
37
+ required: to.required,
38
+ consists_of: to.consists_of
19
39
  }
20
40
 
21
- if (format = options.fetch(:format, nil)).present?
22
- hash[:format] = format
23
- end
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 input_deserialization_options # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
50
+ def output_serialization_options # rubocop:disable Metrics/AbcSize
29
51
  hash = {
30
- as: options.fetch(:to, name),
31
- type: options.fetch(:from),
32
- required: options.fetch(:required, true),
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
- from_type = options.fetch(:from, nil)
56
+ hash[:min] = from.min if from.min.present?
39
57
 
40
- if [Set, Array].include?(from_type)
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
- if (format = options.fetch(:format, nil)).present?
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
- def output_serialization_options # rubocop:disable Metrics/MethodLength
65
+ ##########################################################################
66
+
67
+ def input_deserialization_options # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
56
68
  hash = {
57
- consists_of: if (consists_of_type = options.fetch(:consists_of, false)) == Hash
58
- Datory::Result
59
- else
60
- consists_of_type
61
- end,
62
- type: if (as_type = options.fetch(:as, options.fetch(:from))) == Datory::Result
63
- Hash
64
- elsif (from_type = options.fetch(:from)).present?
65
- from_type
66
- else
67
- as_type
68
- end
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
- if (format = options.fetch(:format, nil)).present?
72
- hash[:format] = format
73
- end
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/MethodLength
93
+ def output_deserialization_options # rubocop:disable Metrics/AbcSize
79
94
  hash = {
80
- consists_of: if (consists_of_type = options.fetch(:consists_of, false)) == Hash
81
- Datory::Result
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
- if (format = options.fetch(:format, nil)).present?
95
- hash[:format] = format
96
- end
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.options.fetch(:to, attribute.name) }
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
- row << attribute.name
23
+ include_class = attribute.to.include_class.presence || attribute.from.type
23
24
 
24
- from_type = attribute.options.fetch(:from)
25
-
26
- row << from_type
27
- row << attribute.options.fetch(:to, attribute.name)
28
- row << attribute.options.fetch(:as, attribute.options.fetch(:include, from_type))
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 # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
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
- input_internal_name = attribute.options.fetch(:to, attribute.name)
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.options.fetch(:to, attribute.name)
24
- include_class = attribute.options.fetch(:include, nil)
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
- from_type = attribute.options.fetch(:from)
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
- output_formatter.call(value: value)
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 # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
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
- input_internal_name = attribute.options.fetch(:to, attribute.name)
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
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Datory
4
4
  class Base
5
+ include Info::DSL
5
6
  include Context::DSL
6
7
  include Attributes::DSL
7
8
  end
@@ -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
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datory
4
+ module Info
5
+ class Result
6
+ attr_reader :attributes
7
+
8
+ def initialize(attributes:)
9
+ @attributes = attributes
10
+ end
11
+ end
12
+ end
13
+ end
@@ -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
@@ -5,7 +5,7 @@ module Datory
5
5
  MAJOR = 1
6
6
  MINOR = 0
7
7
  PATCH = 0
8
- PRE = "rc11"
8
+ PRE = "rc13"
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
11
11
  end
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.rc11
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-26 00:00:00.000000000 Z
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.rc6
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.rc6
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.6
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