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 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