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 +4 -4
- data/README.md +58 -10
- data/lib/micro/attributes.rb +7 -3
- data/lib/micro/attributes/diff.rb +26 -14
- data/lib/micro/attributes/features.rb +72 -77
- data/lib/micro/attributes/features/keys_as_symbol.rb +31 -0
- data/lib/micro/attributes/macros.rb +18 -2
- data/lib/micro/attributes/utils.rb +12 -8
- data/lib/micro/attributes/version.rb +1 -1
- data/lib/micro/attributes/with.rb +107 -25
- data/u-attributes.gemspec +1 -1
- metadata +3 -3
- data/assets/u-attributes_logo_v1.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62c6ad9683f0824be6a32648028f25a97ba88a10c7fbdd0b9a2ccfbfe275961b
|
4
|
+
data.tar.gz: d110a1b4220af76a7f14753cb1ca5067428f06db026466e095d54a22ee46f86f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
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 :
|
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.
|
data/lib/micro/attributes.rb
CHANGED
@@ -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(
|
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
|
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 =
|
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
|
-
|
7
|
-
|
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
|
-
|
14
|
-
|
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
|
38
|
+
differences.has_key?(key_access(name))
|
33
39
|
else
|
34
|
-
result = @differences[name
|
35
|
-
result ? result[
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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 :
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
60
|
+
def self.fetch_keys(args)
|
61
|
+
keys = Array(args).dup.map { |name| fetch_key(name) }
|
63
62
|
|
64
|
-
|
65
|
-
return name unless name.is_a?(Hash)
|
63
|
+
raise ArgumentError, INVALID_NAME if keys.empty? || !(keys - KEYS).empty?
|
66
64
|
|
67
|
-
|
65
|
+
yield(keys)
|
68
66
|
end
|
69
67
|
|
70
|
-
def
|
71
|
-
|
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
|
81
|
-
|
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
|
85
|
-
|
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
|
-
|
90
|
-
end
|
81
|
+
option = keys.sort.join('_')
|
91
82
|
|
92
|
-
|
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
|
-
|
97
|
-
|
87
|
+
def all
|
88
|
+
@all ||= self.with(Options::KEYS)
|
89
|
+
end
|
98
90
|
|
99
|
-
|
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
|
-
|
103
|
-
|
104
|
-
|
97
|
+
def without(names)
|
98
|
+
Options.fetch_keys(names) do |keys|
|
99
|
+
keys = Options.without_keys(keys)
|
105
100
|
|
106
|
-
|
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
|
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
|
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 =
|
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 =
|
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
|
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, '
|
34
|
+
raise ArgumentError, 'argument must be one of these values: :symbol, :string, Symbol, String'.freeze
|
31
35
|
end
|
32
36
|
|
33
|
-
def self.
|
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.
|
48
|
+
Hashes.assoc(object, key) if object.respond_to?(:[])
|
45
49
|
end
|
46
50
|
|
47
51
|
def self.from(object, keys:)
|
@@ -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
|
30
|
+
module StrictInitialize
|
29
31
|
def self.included(base)
|
30
32
|
base.send(:include, Initialize)
|
31
|
-
base.send(:include, ::Micro::Attributes::Features::
|
33
|
+
base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
module
|
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::
|
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
|
54
|
+
module AMValidations_Diff
|
46
55
|
def self.included(base)
|
47
|
-
base.send(:include,
|
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
|
61
|
+
module AMValidations_Diff_Init
|
54
62
|
def self.included(base)
|
55
|
-
base.send(:include,
|
56
|
-
base.send(:include, ::Micro::Attributes::Features::
|
63
|
+
base.send(:include, ActiveModelValidations)
|
64
|
+
base.send(:include, ::Micro::Attributes::Features::Diff)
|
57
65
|
end
|
58
66
|
end
|
59
67
|
|
60
|
-
module
|
68
|
+
module AMValidations_Diff_Init_KeysAsSymbol
|
61
69
|
def self.included(base)
|
62
|
-
base.send(:include,
|
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
|
76
|
+
module AMValidations_Diff_InitStrict
|
69
77
|
def self.included(base)
|
70
|
-
base.send(:include,
|
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
|
83
|
+
module AMValidations_Diff_InitStrict_KeysAsSymbol
|
77
84
|
def self.included(base)
|
78
|
-
base.send(:include,
|
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
|
91
|
+
module AMValidations_Diff_KeysAsSymbol
|
84
92
|
def self.included(base)
|
85
|
-
base.send(:include,
|
86
|
-
base.send(:include, ::Micro::Attributes::Features::
|
87
|
-
|
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
|
139
|
+
module Diff_Init_KeysAsSymbol
|
93
140
|
def self.included(base)
|
94
|
-
base.send(:include,
|
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
|
data/u-attributes.gemspec
CHANGED
@@ -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.
|
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-
|
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
|
Binary file
|