u-attributes 2.3.0 → 2.4.0

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: 2f90839cb67a0501e1ef44a5f06a324103063c87e929549377f885504bda5d8a
4
- data.tar.gz: fd77058f7e514644a8363d460ad33ad76885648e32b5d9b02e22e592ffbf3ffe
3
+ metadata.gz: 62c6ad9683f0824be6a32648028f25a97ba88a10c7fbdd0b9a2ccfbfe275961b
4
+ data.tar.gz: d110a1b4220af76a7f14753cb1ca5067428f06db026466e095d54a22ee46f86f
5
5
  SHA512:
6
- metadata.gz: 27401e952c4f5611ec5443df546d4c2c67f0af7aa40606a8e0f128ae37dc167747d0ba4c94008d993d65c886d4e1d66c6ef3472556ecfa353903779f51b4fe23
7
- data.tar.gz: d05025bd7442681e14fa8f970fb166898ec9af4a344b8912e10c57f559830833bebe05ccacea85332ef9c88437adabc60152967f8b0b38d01f38f1cc6a7c1257
6
+ metadata.gz: 24703dcd81aa785fe00b77a741434ad84600243f4bb132d2bbbce2b5a310d4f2b931c2b6ea41e311a2bcf07876296bd03d8e6c39a92905bc9a4f745fdb30a094
7
+ data.tar.gz: 8172811ddaf44a3099e66f63cea5aed99d5c1a63a77944dc1e98c16fa0378603498fbdfe0c77f7220244c8d7b977801a75bd01facc875fb05f0bd1aed0171cc5
data/README.md CHANGED
@@ -54,7 +54,7 @@ So, if you change [[1](#with_attribute)] [[2](#with_attributes)] some object att
54
54
  - [`#attributes(keys_as:)`](#attributeskeys_as)
55
55
  - [`#attributes(*names)`](#attributesnames)
56
56
  - [`#attributes([names])`](#attributesnames-1)
57
- - [`#attributes(with:, without)`](#attributeswith-without)
57
+ - [`#attributes(with:, without:)`](#attributeswith-without)
58
58
  - [`#defined_attributes`](#defined_attributes)
59
59
  - [Built-in extensions](#built-in-extensions)
60
60
  - [Picking specific features](#picking-specific-features)
@@ -67,6 +67,7 @@ So, if you change [[1](#with_attribute)] [[2](#with_attributes)] some object att
67
67
  - [Diff extension](#diff-extension)
68
68
  - [Initialize extension](#initialize-extension)
69
69
  - [Strict mode](#strict-mode)
70
+ - [Keys as symbol extension](#keys-as-symbol-extension)
70
71
  - [Development](#development)
71
72
  - [Contributing](#contributing)
72
73
  - [License](#license)
@@ -84,7 +85,7 @@ gem 'u-attributes'
84
85
 
85
86
  | u-attributes | branch | ruby | activemodel |
86
87
  | -------------- | ------- | -------- | ------------- |
87
- | 2.3.0 | main | >= 2.2.0 | >= 3.2, < 6.1 |
88
+ | 2.4.0 | main | >= 2.2.0 | >= 3.2, < 6.1 |
88
89
  | 1.2.0 | v1.x | >= 2.2.0 | >= 3.2, < 6.1 |
89
90
 
90
91
  > **Note**: The activemodel is an optional dependency, this module [can be enabled](#activemodelvalidation-extension) to validate the attributes.
@@ -498,14 +499,17 @@ person2.attributes # {"age"=>nil, "first_name"=>"Rodrigo", "last_name"=>"Rodrigu
498
499
 
499
500
  #### `#attributes(keys_as:)`
500
501
 
501
- Use the `keys_as:` option with `Symbol` or `String` to transform the attributes hash keys.
502
+ Use the `keys_as:` option with `Symbol`/`:symbol` or `String`/`:string` to transform the attributes hash keys.
502
503
 
503
504
  ```ruby
504
505
  person1 = Person.new(age: 20)
505
- person1.attributes(keys_as: Symbol) # {:age=>20, :first_name=>"John", :last_name=>"Doe"}
506
-
507
506
  person2 = Person.new(first_name: 'Rodrigo', last_name: 'Rodrigues')
507
+
508
+ person1.attributes(keys_as: Symbol) # {:age=>20, :first_name=>"John", :last_name=>"Doe"}
508
509
  person2.attributes(keys_as: String) # {"age"=>nil, "first_name"=>"Rodrigo", "last_name"=>"Rodrigues"}
510
+
511
+ person1.attributes(keys_as: :symbol) # {:age=>20, :first_name=>"John", :last_name=>"Doe"}
512
+ person2.attributes(keys_as: :string) # {"age"=>nil, "first_name"=>"Rodrigo", "last_name"=>"Rodrigues"}
509
513
  ```
510
514
 
511
515
  #### `#attributes(*names)`
@@ -544,7 +548,7 @@ person.attributes([:age, 'last_name']) # {:age => 20, "last_name" => "Doe"}
544
548
  person.attributes([:age, 'last_name'], keys_as: Symbol) # {:age=>20, :last_name=>"Doe"}
545
549
  ```
546
550
 
547
- #### `#attributes(with:, without)`
551
+ #### `#attributes(with:, without:)`
548
552
 
549
553
  Use the `with:` option to include any method value of the instance inside of the hash, and,
550
554
  you can use the `without:` option to exclude one or more attribute keys from the final hash.
@@ -591,24 +595,30 @@ But, if you desire except one or more features, use the `Micro::Attributes.witho
591
595
  ```ruby
592
596
  Micro::Attributes.with(:initialize)
593
597
 
594
- Micro::Attributes.with(initialize: :strict)
598
+ Micro::Attributes.with(:initialize, :keys_as_symbol)
599
+
600
+ Micro::Attributes.with(:keys_as_symbol, initialize: :strict)
595
601
 
596
602
  Micro::Attributes.with(:diff, :initialize)
597
603
 
598
604
  Micro::Attributes.with(:diff, initialize: :strict)
599
605
 
606
+ Micro::Attributes.with(:diff, :keys_as_symbol, initialize: :strict)
607
+
600
608
  Micro::Attributes.with(:activemodel_validations)
601
609
 
602
610
  Micro::Attributes.with(:activemodel_validations, :diff)
603
611
 
604
612
  Micro::Attributes.with(:activemodel_validations, :diff, initialize: :strict)
613
+
614
+ Micro::Attributes.with(:activemodel_validations, :diff, :keys_as_symbol, initialize: :strict)
605
615
  ```
606
616
 
607
617
  The method `Micro::Attributes.with()` will raise an exception if no arguments/features were declared.
608
618
 
609
619
  ```ruby
610
620
  class Job
611
- include Micro::Attributes.with() # ArgumentError (Invalid feature name! Available options: :activemodel_validations, :diff, :initialize)
621
+ include Micro::Attributes.with() # ArgumentError (Invalid feature name! Available options: :activemodel_validations, :diff, :initialize, :keys_as_symbol)
612
622
  end
613
623
  ```
614
624
 
@@ -617,15 +627,19 @@ end
617
627
  Picking *except* one or more features
618
628
 
619
629
  ```ruby
620
- Micro::Attributes.without(:diff) # will load :activemodel_validations and initialize: :strict
630
+ Micro::Attributes.without(:diff) # will load :activemodel_validations, :keys_as_symbol and initialize: :strict
621
631
 
622
- Micro::Attributes.without(initialize: :strict) # will load :activemodel_validations and :diff
632
+ Micro::Attributes.without(initialize: :strict) # will load :activemodel_validations, :diff and :keys_as_symbol
623
633
  ```
624
634
 
625
635
  ## Picking all the features
626
636
 
627
637
  ```ruby
628
638
  Micro::Attributes.with_all_features
639
+
640
+ # This method returns the same of:
641
+
642
+ Micro::Attributes.with(:activemodel_validations, :diff, :keys_as_symbol, initialize: :strict)
629
643
  ```
630
644
 
631
645
  [⬆️ Back to Top](#table-of-contents-)
@@ -817,6 +831,40 @@ job.state # 'sleeping'
817
831
 
818
832
  [⬆️ Back to Top](#table-of-contents-)
819
833
 
834
+ ### Keys as symbol extension
835
+
836
+ Disables the indifferent access requiring the declaration/usage of the attributes as symbols.
837
+
838
+ The advantage of this extension over the default behavior is because it avoids an unnecessary allocation in memory of strings. All the keys are transformed into strings in the indifferent access mode, but, with this extension, this typecasting will be avoided. So, it has a better performance and reduces the usage of memory/Garbage collector, but gives for you the responsibility to always use symbols to set/access the attributes.
839
+
840
+ ```ruby
841
+ class Job
842
+ include Micro::Attributes.with(:initialize, :keys_as_symbol)
843
+
844
+ attribute :id
845
+ attribute :state, default: 'sleeping'
846
+ end
847
+
848
+ job = Job.new(id: 1)
849
+
850
+ job.attributes # {:id => 1, :state => "sleeping"}
851
+
852
+ job.attribute?(:id) # true
853
+ job.attribute?('id') # false
854
+
855
+ job.attribute(:id) # 1
856
+ job.attribute('id') # nil
857
+
858
+ job.attribute!(:id) # 1
859
+ job.attribute!('id') # NameError (undefined attribute `id)
860
+ ```
861
+
862
+ As you could see in the previous example only symbols will work to do something with the attributes.
863
+
864
+ This extension also changes the `diff extension` making everything (arguments, outputs) working only with symbols.
865
+
866
+ [⬆️ Back to Top](#table-of-contents-)
867
+
820
868
  # Development
821
869
 
822
870
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -68,14 +68,14 @@ module Micro
68
68
 
69
69
  without_option = Array(options.fetch(:without, Kind::Empty::ARRAY))
70
70
 
71
- keys = names.empty? ? defined_attributes - without_option.map(&:to_s) : names - without_option
71
+ keys = names.empty? ? defined_attributes - without_option.map { |value| __attribute_key(value) } : names - without_option
72
72
 
73
73
  data = keys.each_with_object({}) { |key, memo| memo[key] = attribute(key) if attribute?(key) }
74
74
 
75
75
  with_option = Array(options.fetch(:with, Kind::Empty::ARRAY))
76
76
 
77
77
  unless with_option.empty?
78
- extra = with_option.each_with_object({}) { |key, memo| memo[key.to_s] = public_send(key) }
78
+ extra = with_option.each_with_object({}) { |key, memo| memo[__attribute_key(key)] = public_send(key) }
79
79
 
80
80
  data.merge!(extra)
81
81
  end
@@ -86,7 +86,7 @@ module Micro
86
86
  protected
87
87
 
88
88
  def attributes=(arg)
89
- hash = Utils::Hashes.stringify_keys(arg)
89
+ hash = self.class.__attributes_keys__(arg)
90
90
 
91
91
  __attributes_missing!(hash)
92
92
 
@@ -99,6 +99,10 @@ module Micro
99
99
  Utils::ExtractAttribute.from(other, keys: defined_attributes)
100
100
  end
101
101
 
102
+ def __attribute_key(value)
103
+ self.class.__attribute_key__(value)
104
+ end
105
+
102
106
  def __attributes
103
107
  @__attributes ||= {}
104
108
  end
@@ -3,15 +3,20 @@
3
3
  module Micro::Attributes
4
4
  module Diff
5
5
  class Changes
6
- TO = 'to'.freeze
7
- FROM = 'from'.freeze
6
+ FROM_TO_SYM = [:from, :to].freeze
7
+ FROM_TO_STR = ['from'.freeze, 'to'.freeze].freeze
8
8
  FROM_TO_ERROR = 'pass the attribute name with the :from and :to values'.freeze
9
9
 
10
10
  attr_reader :from, :to, :differences
11
11
 
12
12
  def initialize(from:, to:)
13
- raise ArgumentError, "expected an instance of #{from.class}" unless to.is_a?(from.class)
14
- @from, @to = from, to
13
+ @from_class = from.class
14
+
15
+ @from, @to = from, Kind::Of.(@from_class, to)
16
+
17
+ @from_key, @to_key =
18
+ @from_class.attributes_access == :symbol ? FROM_TO_SYM : FROM_TO_STR
19
+
15
20
  @differences = diff(from.attributes, to.attributes).freeze
16
21
  end
17
22
 
@@ -27,26 +32,33 @@ module Micro::Attributes
27
32
  def changed?(name = nil, from: nil, to: nil)
28
33
  if name.nil?
29
34
  return present? if from.nil? && to.nil?
35
+
30
36
  raise ArgumentError, FROM_TO_ERROR
31
37
  elsif from.nil? && to.nil?
32
- differences.has_key?(name.to_s)
38
+ differences.has_key?(key_access(name))
33
39
  else
34
- result = @differences[name.to_s]
35
- result ? result[FROM] == from && result[TO] == to : false
40
+ result = @differences[key_access(name)]
41
+ result ? result[@from_key] == from && result[@to_key] == to : false
36
42
  end
37
43
  end
38
44
 
39
45
  private
40
46
 
41
- def diff(from_attributes, to_attributes)
42
- @from_attributes, @to_attributes = from_attributes, to_attributes
43
- @from_attributes.each_with_object({}) do |(from_key, from_val), acc|
44
- to_value = @to_attributes[from_key]
45
- acc[from_key] = {FROM => from_val, TO => to_value}.freeze if from_val != to_value
47
+ def key_access(key)
48
+ @from_class.__attribute_key__(key)
49
+ end
50
+
51
+ def diff(from_attributes, to_attributes)
52
+ @from_attributes, @to_attributes = from_attributes, to_attributes
53
+
54
+ @from_attributes.each_with_object({}) do |(from_key, from_val), acc|
55
+ to_value = @to_attributes[from_key]
56
+
57
+ acc[from_key] = {@from_key => from_val, @to_key => to_value}.freeze if from_val != to_value
58
+ end
46
59
  end
47
- end
48
60
 
49
- private_constant :TO, :FROM, :FROM_TO_ERROR
61
+ private_constant :FROM_TO_SYM, :FROM_TO_STR, :FROM_TO_ERROR
50
62
  end
51
63
  end
52
64
  end
@@ -7,105 +7,100 @@ module Micro
7
7
  module Features
8
8
  extend self
9
9
 
10
- STRICT_INITIALIZE = 'strict_initialize'.freeze
11
-
12
- ALL_VISIBLE = [
13
- DIFF = 'diff'.freeze,
14
- INITIALIZE = 'initialize'.freeze,
15
- ACTIVEMODEL_VALIDATIONS = 'activemodel_validations'.freeze
16
- ].sort.freeze
17
-
18
- ALL = (ALL_VISIBLE + [STRICT_INITIALIZE]).sort.freeze
19
-
20
- INVALID_NAME = [
21
- 'Invalid feature name! Available options: ',
22
- ALL_VISIBLE.map { |feature_name| ":#{feature_name}" }.join(', ')
23
- ].join
24
-
25
- OPTIONS = {
26
- # Features
27
- DIFF => With::Diff,
28
- INITIALIZE => With::Initialize,
29
- STRICT_INITIALIZE => With::StrictInitialize,
30
- ACTIVEMODEL_VALIDATIONS => With::ActiveModelValidations,
31
- # Combinations
32
- 'diff:initialize' => With::DiffAndInitialize,
33
- 'diff:strict_initialize' => With::DiffAndStrictInitialize,
34
- 'activemodel_validations:diff' => With::ActiveModelValidationsAndDiff,
35
- 'activemodel_validations:initialize' => With::ActiveModelValidationsAndInitialize,
36
- 'activemodel_validations:strict_initialize' => With::ActiveModelValidationsAndStrictInitialize,
37
- 'activemodel_validations:diff:initialize' => With::ActiveModelValidationsAndDiffAndInitialize,
38
- 'activemodel_validations:diff:strict_initialize' => With::ActiveModelValidationsAndDiffAndStrictInitialize
39
- }.freeze
40
-
41
- private_constant :OPTIONS, :INVALID_NAME
42
-
43
- def all
44
- @all ||= self.with(ALL)
10
+ module Name
11
+ ALL = [
12
+ DIFF = 'diff'.freeze,
13
+ INITIALIZE = 'initialize'.freeze,
14
+ KEYS_AS_SYMBOL = 'keys_as_symbol'.freeze,
15
+ ACTIVEMODEL_VALIDATIONS = 'activemodel_validations'.freeze
16
+ ].sort.freeze
45
17
  end
46
18
 
47
- def with(args)
48
- valid_names!(args) do |names|
49
- delete_initialize_if_has_strict_initialize(names)
50
-
51
- OPTIONS.fetch(names.sort.join(':'))
19
+ module Options
20
+ KEYS = [
21
+ DIFF = 'Diff'.freeze,
22
+ INIT = 'Init'.freeze,
23
+ INIT_STRICT = 'InitStrict'.freeze,
24
+ KEYS_AS_SYMBOL = 'KeysAsSymbol'.freeze,
25
+ AM_VALIDATIONS = 'AMValidations'.freeze
26
+ ].sort.freeze
27
+
28
+ NAMES_TO_KEYS = {
29
+ Name::DIFF => DIFF,
30
+ Name::INITIALIZE => INIT,
31
+ Name::KEYS_AS_SYMBOL => KEYS_AS_SYMBOL,
32
+ Name::ACTIVEMODEL_VALIDATIONS => AM_VALIDATIONS
33
+ }.freeze
34
+
35
+ KEYS_TO_MODULES = {
36
+ DIFF => With::Diff,
37
+ INIT => With::Initialize,
38
+ INIT_STRICT => With::StrictInitialize,
39
+ KEYS_AS_SYMBOL => With::KeysAsSymbol,
40
+ AM_VALIDATIONS => With::ActiveModelValidations
41
+ }.freeze
42
+
43
+ def self.fetch_key(arg)
44
+ if arg.is_a?(Hash)
45
+ INIT_STRICT if arg[:initialize] == :strict
46
+ else
47
+ name = String(arg)
48
+
49
+ return name if KEYS_TO_MODULES.key?(name)
50
+
51
+ NAMES_TO_KEYS[name]
52
+ end
52
53
  end
53
- end
54
54
 
55
- def without(args)
56
- valid_names!(args) do |names_to_exclude|
57
- names = except_options(names_to_exclude)
58
- names.empty? ? ::Micro::Attributes : self.with(names)
59
- end
60
- end
55
+ INVALID_NAME = [
56
+ 'Invalid feature name! Available options: ',
57
+ Name::ALL.map { |feature_name| ":#{feature_name}" }.join(', ')
58
+ ].join
61
59
 
62
- private
60
+ def self.fetch_keys(args)
61
+ keys = Array(args).dup.map { |name| fetch_key(name) }
63
62
 
64
- def fetch_feature_name(name)
65
- return name unless name.is_a?(Hash)
63
+ raise ArgumentError, INVALID_NAME if keys.empty? || !(keys - KEYS).empty?
66
64
 
67
- STRICT_INITIALIZE if name[:initialize] == :strict
65
+ yield(keys)
68
66
  end
69
67
 
70
- def normalize_names(args)
71
- names = Array(args).dup
72
-
73
- last_feature = fetch_feature_name(names.pop)
74
-
75
- features = names.empty? ? [last_feature] : names + [last_feature]
76
- features.map! { |name| name.to_s.downcase }
77
- features.uniq
68
+ def self.remove_init_keys(keys, if_has_init_in:)
69
+ keys.delete_if { |key| key == INIT || key == INIT_STRICT } if if_has_init_in.include?(INIT)
78
70
  end
79
71
 
80
- def valid_names?(names)
81
- names.all? { |name| ALL.include?(name) }
72
+ def self.without_keys(keys_to_exclude)
73
+ (KEYS - keys_to_exclude).tap do |keys|
74
+ remove_init_keys(keys, if_has_init_in: keys_to_exclude)
75
+ end
82
76
  end
83
77
 
84
- def valid_names!(args)
85
- names = normalize_names(args)
86
-
87
- raise ArgumentError, INVALID_NAME if names.empty? || !valid_names?(names)
78
+ def self.fetch_module_by_keys(keys)
79
+ keys.delete_if { |key| key == INIT } if keys.include?(INIT_STRICT)
88
80
 
89
- yield(names)
90
- end
81
+ option = keys.sort.join('_')
91
82
 
92
- def an_initialize?(name)
93
- name == INITIALIZE || name == STRICT_INITIALIZE
83
+ KEYS_TO_MODULES.fetch(option) { With.const_get(option, false) }
94
84
  end
85
+ end
95
86
 
96
- def delete_initialize_if_has_strict_initialize(names)
97
- return unless names.include?(STRICT_INITIALIZE)
87
+ def all
88
+ @all ||= self.with(Options::KEYS)
89
+ end
98
90
 
99
- names.delete_if { |name| name == INITIALIZE }
91
+ def with(names)
92
+ Options.fetch_keys(names) do |keys|
93
+ Options.fetch_module_by_keys(keys)
100
94
  end
95
+ end
101
96
 
102
- def except_options(names_to_exclude)
103
- (ALL - names_to_exclude).tap do |names|
104
- names.delete_if { |name| an_initialize?(name) } if names_to_exclude.include?(INITIALIZE)
97
+ def without(names)
98
+ Options.fetch_keys(names) do |keys|
99
+ keys = Options.without_keys(keys)
105
100
 
106
- delete_initialize_if_has_strict_initialize(names)
107
- end
101
+ keys.empty? ? ::Micro::Attributes : Options.fetch_module_by_keys(keys)
108
102
  end
103
+ end
109
104
  end
110
105
  end
111
106
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro::Attributes
4
+ module Features
5
+ module KeysAsSymbol
6
+
7
+ module ClassMethods
8
+ def attributes_access
9
+ :symbol
10
+ end
11
+
12
+ def __attribute_access__(value)
13
+ Kind::Of.(::Symbol, value)
14
+ end
15
+
16
+ def __attribute_key__(value)
17
+ value
18
+ end
19
+
20
+ def __attributes_keys__(hash)
21
+ Utils::Hashes.kind(hash)
22
+ end
23
+ end
24
+
25
+ def self.included(base)
26
+ base.send(:extend, ClassMethods)
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -7,6 +7,22 @@ module Micro
7
7
  false
8
8
  end
9
9
 
10
+ def attributes_access
11
+ :indifferent
12
+ end
13
+
14
+ def __attribute_access__(value)
15
+ value
16
+ end
17
+
18
+ def __attribute_key__(value)
19
+ value.to_s
20
+ end
21
+
22
+ def __attributes_keys__(hash)
23
+ Utils::Hashes.stringify_keys(hash)
24
+ end
25
+
10
26
  # NOTE: can't be renamed! It is used by u-case v4.
11
27
  def __attributes_data__
12
28
  @__attributes_data__ ||= {}
@@ -41,7 +57,7 @@ module Micro
41
57
  end
42
58
 
43
59
  def __attribute_assign(key, can_overwrite, options)
44
- name = key.to_s
60
+ name = __attribute_access__(__attribute_key__(key))
45
61
  has_attribute = attribute?(name)
46
62
 
47
63
  __attribute_reader(name) unless has_attribute
@@ -61,7 +77,7 @@ module Micro
61
77
  end
62
78
 
63
79
  def attribute?(name)
64
- __attributes.member?(name.to_s)
80
+ __attributes.member?(__attribute_key__(name))
65
81
  end
66
82
 
67
83
  def attribute(name, options = Kind::Empty::HASH)
@@ -3,8 +3,12 @@
3
3
  module Micro::Attributes
4
4
  module Utils
5
5
  module Hashes
6
+ def self.kind(hash)
7
+ Kind::Of.(::Hash, hash)
8
+ end
9
+
6
10
  def self.stringify_keys(arg)
7
- hash = Kind::Of.(::Hash, arg)
11
+ hash = kind(arg)
8
12
 
9
13
  return hash if hash.empty?
10
14
  return hash.transform_keys(&:to_s) if hash.respond_to?(:transform_keys)
@@ -13,7 +17,7 @@ module Micro::Attributes
13
17
  end
14
18
 
15
19
  def self.symbolize_keys(arg)
16
- hash = Kind::Of.(::Hash, arg)
20
+ hash = kind(arg)
17
21
 
18
22
  return hash if hash.empty?
19
23
  return hash.transform_keys(&:to_sym) if hash.respond_to?(:transform_keys)
@@ -22,15 +26,15 @@ module Micro::Attributes
22
26
  end
23
27
 
24
28
  def self.keys_as(type, hash)
25
- return Kind::Of.(::Hash, hash) unless type
29
+ return kind(hash) unless type
26
30
 
27
- return symbolize_keys(hash) if type == Symbol
28
- return stringify_keys(hash) if type == String
31
+ return symbolize_keys(hash) if type == Symbol || type == :symbol
32
+ return stringify_keys(hash) if type == String || type == :string
29
33
 
30
- raise ArgumentError, 'first argument must be the class String or Symbol'.freeze
34
+ raise ArgumentError, 'argument must be one of these values: :symbol, :string, Symbol, String'.freeze
31
35
  end
32
36
 
33
- def self.get(hash, key)
37
+ def self.assoc(hash, key)
34
38
  value = hash[key.to_s]
35
39
 
36
40
  value.nil? ? hash[key.to_sym] : value
@@ -41,7 +45,7 @@ module Micro::Attributes
41
45
  def self.call(object, key:)
42
46
  return object.public_send(key) if object.respond_to?(key)
43
47
 
44
- Hashes.get(object, key) if object.respond_to?(:[])
48
+ Hashes.assoc(object, key) if object.respond_to?(:[])
45
49
  end
46
50
 
47
51
  def self.from(object, keys:)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  module Attributes
5
- VERSION = '2.3.0'.freeze
5
+ VERSION = '2.4.0'.freeze
6
6
  end
7
7
  end
@@ -3,8 +3,10 @@
3
3
  require 'micro/attributes/features/diff'
4
4
  require 'micro/attributes/features/initialize'
5
5
  require 'micro/attributes/features/initialize/strict'
6
+ require 'micro/attributes/features/keys_as_symbol'
6
7
  require 'micro/attributes/features/activemodel_validations'
7
8
 
9
+
8
10
  module Micro
9
11
  module Attributes
10
12
  module With
@@ -25,76 +27,156 @@ module Micro
25
27
  end
26
28
  end
27
29
 
28
- module ActiveModelValidations
30
+ module StrictInitialize
29
31
  def self.included(base)
30
32
  base.send(:include, Initialize)
31
- base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
33
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
32
34
  end
33
35
  end
34
36
 
35
- module StrictInitialize
37
+ module KeysAsSymbol
38
+ def self.included(base)
39
+ base.send(:include, ::Micro::Attributes)
40
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
41
+ end
42
+ end
43
+
44
+ module ActiveModelValidations
36
45
  def self.included(base)
37
46
  base.send(:include, Initialize)
38
- base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
47
+ base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
39
48
  end
40
49
  end
41
50
 
42
51
  #
43
52
  # Combinations
44
53
  #
45
- module DiffAndInitialize
54
+ module AMValidations_Diff
46
55
  def self.included(base)
47
- base.send(:include, ::Micro::Attributes)
48
- base.send(:include, ::Micro::Attributes::Features::Initialize)
56
+ base.send(:include, ActiveModelValidations)
49
57
  base.send(:include, ::Micro::Attributes::Features::Diff)
50
58
  end
51
59
  end
52
60
 
53
- module DiffAndStrictInitialize
61
+ module AMValidations_Diff_Init
54
62
  def self.included(base)
55
- base.send(:include, DiffAndInitialize)
56
- base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
63
+ base.send(:include, ActiveModelValidations)
64
+ base.send(:include, ::Micro::Attributes::Features::Diff)
57
65
  end
58
66
  end
59
67
 
60
- module ActiveModelValidationsAndDiff
68
+ module AMValidations_Diff_Init_KeysAsSymbol
61
69
  def self.included(base)
62
- base.send(:include, ::Micro::Attributes)
63
- base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
70
+ base.send(:include, ActiveModelValidations)
64
71
  base.send(:include, ::Micro::Attributes::Features::Diff)
72
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
65
73
  end
66
74
  end
67
75
 
68
- module ActiveModelValidationsAndInitialize
76
+ module AMValidations_Diff_InitStrict
69
77
  def self.included(base)
70
- base.send(:include, ::Micro::Attributes)
71
- base.send(:include, ::Micro::Attributes::Features::Initialize)
72
- base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
78
+ base.send(:include, AMValidations_Diff_Init)
79
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
73
80
  end
74
81
  end
75
82
 
76
- module ActiveModelValidationsAndStrictInitialize
83
+ module AMValidations_Diff_InitStrict_KeysAsSymbol
77
84
  def self.included(base)
78
- base.send(:include, ActiveModelValidationsAndInitialize)
85
+ base.send(:include, AMValidations_Diff_Init)
79
86
  base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
87
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
80
88
  end
81
89
  end
82
90
 
83
- module ActiveModelValidationsAndDiffAndInitialize
91
+ module AMValidations_Diff_KeysAsSymbol
84
92
  def self.included(base)
85
- base.send(:include, ::Micro::Attributes)
86
- base.send(:include, ::Micro::Attributes::Features::Initialize)
87
- base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
93
+ base.send(:include, AMValidations_Diff)
94
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
95
+ end
96
+ end
97
+
98
+ module AMValidations_Init
99
+ def self.included(base)
100
+ base.send(:include, ActiveModelValidations)
101
+ end
102
+ end
103
+
104
+ module AMValidations_Init_KeysAsSymbol
105
+ def self.included(base)
106
+ base.send(:include, AMValidations_Init)
107
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
108
+ end
109
+ end
110
+
111
+ module AMValidations_InitStrict
112
+ def self.included(base)
113
+ base.send(:include, ActiveModelValidations)
114
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
115
+ end
116
+ end
117
+
118
+ module AMValidations_InitStrict_KeysAsSymbol
119
+ def self.included(base)
120
+ base.send(:include, AMValidations_InitStrict)
121
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
122
+ end
123
+ end
124
+
125
+ module AMValidations_KeysAsSymbol
126
+ def self.included(base)
127
+ base.send(:include, ActiveModelValidations)
128
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
129
+ end
130
+ end
131
+
132
+ module Diff_Init
133
+ def self.included(base)
134
+ base.send(:include, Initialize)
88
135
  base.send(:include, ::Micro::Attributes::Features::Diff)
89
136
  end
90
137
  end
91
138
 
92
- module ActiveModelValidationsAndDiffAndStrictInitialize
139
+ module Diff_Init_KeysAsSymbol
93
140
  def self.included(base)
94
- base.send(:include, ActiveModelValidationsAndDiffAndInitialize)
141
+ base.send(:include, Diff_Init)
142
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
143
+ end
144
+ end
145
+
146
+ module Diff_InitStrict
147
+ def self.included(base)
148
+ base.send(:include, Diff_Init)
95
149
  base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
96
150
  end
97
151
  end
152
+
153
+ module Diff_InitStrict_KeysAsSymbol
154
+ def self.included(base)
155
+ base.send(:include, Diff_InitStrict)
156
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
157
+ end
158
+ end
159
+
160
+ module Diff_KeysAsSymbol
161
+ def self.included(base)
162
+ base.send(:include, Diff)
163
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
164
+ end
165
+ end
166
+
167
+ module Init_KeysAsSymbol
168
+ def self.included(base)
169
+ base.send(:include, Initialize)
170
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
171
+ end
172
+ end
173
+
174
+ module InitStrict_KeysAsSymbol
175
+ def self.included(base)
176
+ base.send(:include, StrictInitialize)
177
+ base.send(:include, ::Micro::Attributes::Features::KeysAsSymbol)
178
+ end
179
+ end
98
180
  end
99
181
  end
100
182
  end
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
22
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|assets)/}) }
24
24
  end
25
25
  spec.bindir = 'exe'
26
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-07 00:00:00.000000000 Z
11
+ date: 2020-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kind
@@ -76,7 +76,6 @@ files:
76
76
  - LICENSE.txt
77
77
  - README.md
78
78
  - Rakefile
79
- - assets/u-attributes_logo_v1.png
80
79
  - bin/console
81
80
  - bin/setup
82
81
  - lib/micro/attributes.rb
@@ -86,6 +85,7 @@ files:
86
85
  - lib/micro/attributes/features/diff.rb
87
86
  - lib/micro/attributes/features/initialize.rb
88
87
  - lib/micro/attributes/features/initialize/strict.rb
88
+ - lib/micro/attributes/features/keys_as_symbol.rb
89
89
  - lib/micro/attributes/macros.rb
90
90
  - lib/micro/attributes/utils.rb
91
91
  - lib/micro/attributes/version.rb