datory 1.0.0.rc2 → 1.0.0.rc4

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: dad592cd7b60ed42e5e729fc785dfcb148abff2e4966194563d943f9e3f66f60
4
- data.tar.gz: 9bffee76ef163ac26529c4a163afa2e1a9cea42da6619381b85d7cd2b5187290
3
+ metadata.gz: 5ca68aea305e426d629f97a3d8940e016a933e4298e56b7ab7d3f9e495fb515d
4
+ data.tar.gz: 3589f41e040965dacdbaa9f22d197c837afd96f6a5d34e6b32b93e2043ce2391
5
5
  SHA512:
6
- metadata.gz: fe6407e48e97f7e2f462e52cc7aba7a1726171f02e9fcd1d774bb36c9b04047abdf7218a3eede1b99023fe38f16d80b7bbec224313ffc229e3695b8bdc6126e3
7
- data.tar.gz: ae3835273961a84951d232afccf50851cade4f9efb5f89c44d8d7cdf55b3804ff6ba983580d4025aa4f6fd28fd4f695d1941fb74833015d3a88852712d4332fa
6
+ metadata.gz: 4b08dcadef0150c3183c5ae1458fdd4de9ddf9a1dd6303c5b7dfa1e104f7c4581826c4876660628879a432263ac4cc87de728d2948a3167dc1dd20c83b6bf176
7
+ data.tar.gz: a19f50f5e2bfe11d3092292ea2e641f546ba78bd2b2eb8efb50769f42d47753c9a6edd46460a6391b4e389c6dcd662cbaf5510f80aa7fd66ab9cf0f3233bb5f0
data/README.md CHANGED
@@ -36,10 +36,10 @@ UserDto.deserialize(json)
36
36
  ```ruby
37
37
  class UserDto < Datory::Base
38
38
  string :id
39
- string :firstname, as: :first_name
40
- string :lastname, as: :last_name
39
+ string :firstname, to: :first_name
40
+ string :lastname, to: :last_name
41
41
  string :email
42
- string :birthDate, as: :birth_date, output: ->(value:) { value.to_s }
42
+ string :birthDate, to: :birth_date, output: ->(value:) { value.to_s }
43
43
 
44
44
  one :login, include: UserLoginDto
45
45
 
@@ -29,42 +29,47 @@ module Datory
29
29
  collection_of_attributes << Attribute.new(name, **options)
30
30
  end
31
31
 
32
+ def symbol(name, **options)
33
+ options = options.merge(from: Symbol)
34
+ attribute(name, **options)
35
+ end
36
+
32
37
  def string(name, **options)
33
- options = options.merge(type: String)
38
+ options = options.merge(from: String)
34
39
  attribute(name, **options)
35
40
  end
36
41
 
37
42
  def integer(name, **options)
38
- options = options.merge(type: Integer)
43
+ options = options.merge(from: Integer)
39
44
  attribute(name, **options)
40
45
  end
41
46
 
42
47
  def float(name, **options)
43
- options = options.merge(type: Float)
48
+ options = options.merge(from: Float)
44
49
  attribute(name, **options)
45
50
  end
46
51
 
47
52
  def date(name, **options)
48
- options = options.merge(type: Date)
53
+ options = options.merge(from: Date)
49
54
  attribute(name, **options)
50
55
  end
51
56
 
52
57
  def time(name, **options)
53
- options = options.merge(type: Time)
58
+ options = options.merge(from: Time)
54
59
  attribute(name, **options)
55
60
  end
56
61
 
57
62
  def datetime(name, **options)
58
- options = options.merge(type: DateTime)
63
+ options = options.merge(from: DateTime)
59
64
  attribute(name, **options)
60
65
  end
61
66
 
62
- def one(name, include:, as: nil)
63
- attribute(name, as: as.presence || name, type: Hash, include: include)
67
+ def one(name, include:, to: nil)
68
+ attribute(name, to: to.presence || name, from: Hash, include: include)
64
69
  end
65
70
 
66
- def many(name, include:, as: nil)
67
- attribute(name, as: as.presence || name, type: Array, consists_of: Hash, include: include)
71
+ def many(name, include:, to: nil)
72
+ attribute(name, to: to.presence || name, from: Array, consists_of: Hash, include: include)
68
73
  end
69
74
 
70
75
  def collection_of_attributes
@@ -0,0 +1,52 @@
1
+ module Datory
2
+ module Attributes
3
+ module Serialization
4
+ class Serializator
5
+ def self.serialize(model:, collection_of_attributes:)
6
+ new(collection_of_attributes: collection_of_attributes).serialize(model: model)
7
+ end
8
+
9
+ def initialize(collection_of_attributes:)
10
+ @collection_of_attributes = collection_of_attributes
11
+ end
12
+
13
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
14
+ def serialize(model:)
15
+ if [Set, Array].include?(model.class)
16
+ model.map do |nested_model|
17
+ serialize(model: nested_model)
18
+ end
19
+ else
20
+ @collection_of_attributes.to_h do |attribute|
21
+ internal_name = attribute.options.fetch(:to, attribute.name)
22
+ include_class = attribute.options.fetch(:include, nil)
23
+ output_formatter = attribute.options.fetch(:output, nil)
24
+
25
+ value = model.public_send(internal_name)
26
+
27
+ value =
28
+ if include_class.present?
29
+ type = attribute.options.fetch(:type, nil)
30
+
31
+ if [Set, Array].include?(type)
32
+ value.map { |item| include_class.serialize(item) }
33
+ else
34
+ include_class.serialize(value)
35
+ end
36
+ elsif output_formatter.is_a?(Proc)
37
+ output_formatter.call(value: value)
38
+ elsif [Date, Time, DateTime].include?(value.class)
39
+ value.to_s
40
+ else
41
+ value
42
+ end
43
+
44
+ [attribute.name, value]
45
+ end
46
+ end
47
+ end
48
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datory
4
+ module Attributes
5
+ module Tools
6
+ class ServiceBuilder
7
+ SERVICE_CLASS_NAME = "Builder"
8
+
9
+ def self.build!(...)
10
+ new(...).build!
11
+ end
12
+
13
+ def initialize(context, incoming_attributes, collection_of_attributes)
14
+ @context = context
15
+ @incoming_attributes = incoming_attributes
16
+ @collection_of_attributes = collection_of_attributes
17
+ end
18
+
19
+ def build!
20
+ ServiceFactory.create(@context.class, @collection_of_attributes)
21
+
22
+ builder_class.call!(**@incoming_attributes)
23
+ end
24
+
25
+ private
26
+
27
+ def builder_class
28
+ "#{@context.class.name}::#{SERVICE_CLASS_NAME}".constantize
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datory
4
+ module Attributes
5
+ module Tools
6
+ class ServiceFactory
7
+ def self.create(...)
8
+ new(...).create
9
+ end
10
+
11
+ def initialize(model_class, collection_of_attributes)
12
+ @model_class = model_class
13
+ @collection_of_attributes = collection_of_attributes
14
+ end
15
+
16
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
17
+ def create
18
+ return if @model_class.const_defined?(ServiceBuilder::SERVICE_CLASS_NAME)
19
+
20
+ collection_of_attributes = @collection_of_attributes
21
+
22
+ class_sample = Class.new(Datory::Service::Builder) do
23
+ collection_of_attributes.each do |attribute| # rubocop:disable Metrics/BlockLength
24
+ input_internal_name = attribute.options.fetch(:to, attribute.name)
25
+
26
+ input attribute.name,
27
+ as: input_internal_name,
28
+ type: attribute.options.fetch(:from),
29
+ required: attribute.options.fetch(:required, true),
30
+ consists_of: attribute.options.fetch(:consists_of, false),
31
+ prepare: (lambda do |value:|
32
+ include_class = attribute.options.fetch(:include, nil)
33
+ return value unless include_class.present?
34
+
35
+ from_type = attribute.options.fetch(:from, nil)
36
+
37
+ if [Set, Array].include?(from_type)
38
+ value.map { |item| include_class.build(**item) }
39
+ else
40
+ include_class.build(**value)
41
+ end
42
+ end)
43
+
44
+ output input_internal_name,
45
+ consists_of: if (consists_of_type = attribute.options.fetch(:consists_of, false)) == Hash
46
+ Datory::Result
47
+ else
48
+ consists_of_type
49
+ end,
50
+ type: if (from_type = attribute.options.fetch(:from)) == Hash
51
+ Datory::Result
52
+ elsif (option_as = attribute.options.fetch(:as, nil)).present?
53
+ option_as
54
+ else
55
+ from_type
56
+ end
57
+
58
+ make :"assign_#{input_internal_name}_output"
59
+
60
+ define_method(:"assign_#{input_internal_name}_output") do
61
+ value = inputs.public_send(input_internal_name)
62
+
63
+ option_as = attribute.options.fetch(:as, nil)
64
+
65
+ if [Date, Time, DateTime].include?(option_as)
66
+ value = option_as.parse(value)
67
+ elsif option_as == String
68
+ value = value.to_s
69
+ elsif option_as == Integer
70
+ value = value.to_i
71
+ elsif option_as == Float
72
+ value = value.to_f
73
+ end
74
+
75
+ outputs.public_send(:"#{input_internal_name}=", value)
76
+ end
77
+ end
78
+
79
+ # output :model, type: Class
80
+
81
+ # make :assign_model_name
82
+
83
+ # def assign_model_name
84
+ # model_class_name_array = self.class.name.split("::")
85
+ # model_class_name_array.pop
86
+ # model_class_name = model_class_name_array.join("::")
87
+ # model_class = model_class_name.constantize
88
+ #
89
+ # outputs.model = model_class
90
+ # end
91
+ end
92
+
93
+ @model_class.const_set(ServiceBuilder::SERVICE_CLASS_NAME, class_sample)
94
+ end
95
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
96
+ end
97
+ end
98
+ end
99
+ end
@@ -3,76 +3,12 @@
3
3
  module Datory
4
4
  module Attributes
5
5
  module Workspace
6
- class ServiceFactory
7
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
8
- def self.create(model_class, class_name, collection_of_attributes)
9
- return if model_class.const_defined?(class_name)
10
-
11
- class_sample = Class.new(Datory::Service::Builder) do
12
- collection_of_attributes.each do |attribute| # rubocop:disable Metrics/BlockLength
13
- input_internal_name = attribute.options.fetch(:as, attribute.name)
14
-
15
- input attribute.name,
16
- as: input_internal_name,
17
- type: attribute.options.fetch(:type),
18
- required: attribute.options.fetch(:required, true),
19
- consists_of: attribute.options.fetch(:consists_of, false),
20
- prepare: (lambda do |value:|
21
- include_class = attribute.options.fetch(:include, nil)
22
- return value unless include_class.present?
23
-
24
- type = attribute.options.fetch(:type, nil)
25
-
26
- if [Set, Array].include?(type)
27
- value.map { |item| include_class.build(**item) }
28
- else
29
- include_class.build(**value)
30
- end
31
- end)
32
-
33
- output input_internal_name,
34
- consists_of: (
35
- if (type = attribute.options.fetch(:consists_of, false)) == Hash
36
- Datory::Result
37
- else
38
- type
39
- end
40
- ),
41
- type: if (type = attribute.options.fetch(:type)) == Hash
42
- Datory::Result
43
- else
44
- type
45
- end
46
-
47
- make :"assign_#{input_internal_name}_output"
48
-
49
- define_method(:"assign_#{input_internal_name}_output") do
50
- outputs.public_send(:"#{input_internal_name}=", inputs.public_send(input_internal_name))
51
- end
52
- end
53
- end
54
-
55
- model_class.const_set(class_name, class_sample)
56
- end
57
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
58
- end
59
-
60
6
  private
61
7
 
62
8
  def build!(incoming_attributes:, collection_of_attributes:, **)
63
9
  super
64
10
 
65
- builder_class_name = "GBuilder"
66
-
67
- ServiceFactory.create(self.class, builder_class_name, collection_of_attributes)
68
-
69
- builder_class = "#{self.class.name}::#{builder_class_name}".constantize
70
-
71
- builder_class.call!(**incoming_attributes)
72
-
73
- # Tools::Unnecessary.find!(self, attributes, collection_of_attributes)
74
- # Tools::Rules.check!(self, collection_of_attributes)
75
- # Tools::Validation.validate!(self, attributes, collection_of_attributes)
11
+ Tools::ServiceBuilder.build!(self, incoming_attributes, collection_of_attributes)
76
12
  end
77
13
  end
78
14
  end
@@ -3,42 +3,12 @@
3
3
  module Datory
4
4
  module Context
5
5
  module Callable
6
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
7
6
  def serialize(model)
8
- if [Set, Array].include?(model.class)
9
- model.map do |model_item|
10
- serialize(model_item)
11
- end
12
- else
13
- collection_of_attributes.to_h do |attribute|
14
- internal_name = attribute.options.fetch(:as, attribute.name)
15
- include_class = attribute.options.fetch(:include, nil)
16
- output_formatter = attribute.options.fetch(:output, nil)
17
-
18
- value = model.public_send(internal_name)
19
-
20
- value =
21
- if include_class.present?
22
- type = attribute.options.fetch(:type, nil)
23
-
24
- if [Set, Array].include?(type)
25
- value.map { |item| include_class.serialize(item) }
26
- else
27
- include_class.serialize(value)
28
- end
29
- elsif output_formatter.is_a?(Proc)
30
- output_formatter.call(value: value)
31
- elsif [Date, Time, DateTime].include?(value.class)
32
- value.to_s
33
- else
34
- value
35
- end
36
-
37
- [attribute.name, value]
38
- end
39
- end
7
+ Datory::Attributes::Serialization::Serializator.serialize(
8
+ model: model,
9
+ collection_of_attributes: collection_of_attributes
10
+ )
40
11
  end
41
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
42
12
 
43
13
  def deserialize(json)
44
14
  if [Set, Array].include?(json.class)
@@ -5,7 +5,7 @@ module Datory
5
5
  MAJOR = 1
6
6
  MINOR = 0
7
7
  PATCH = 0
8
- PRE = "rc2"
8
+ PRE = "rc4"
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
11
11
  end
data/lib/datory.rb CHANGED
@@ -4,7 +4,7 @@ require "zeitwerk"
4
4
 
5
5
  require "active_support/all"
6
6
 
7
- require "uri"
7
+ require "servactory"
8
8
 
9
9
  loader = Zeitwerk::Loader.for_gem
10
10
  loader.inflector.inflect(
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.rc2
4
+ version: 1.0.0.rc4
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-21 00:00:00.000000000 Z
11
+ date: 2024-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -48,16 +48,16 @@ dependencies:
48
48
  name: servactory
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ">="
51
+ - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: '2.4'
53
+ version: 2.5.0.rc2
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.4'
60
+ version: 2.5.0.rc2
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: zeitwerk
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -199,6 +199,9 @@ files:
199
199
  - lib/datory/attributes/attribute.rb
200
200
  - lib/datory/attributes/collection.rb
201
201
  - lib/datory/attributes/dsl.rb
202
+ - lib/datory/attributes/serialization/serializator.rb
203
+ - lib/datory/attributes/tools/service_builder.rb
204
+ - lib/datory/attributes/tools/service_factory.rb
202
205
  - lib/datory/attributes/workspace.rb
203
206
  - lib/datory/base.rb
204
207
  - lib/datory/context/callable.rb