u-attributes 1.1.1 → 2.1.1

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.
@@ -7,6 +7,7 @@ module Micro::Attributes
7
7
  base.class_eval(<<-RUBY)
8
8
  def initialize(arg)
9
9
  self.attributes = arg
10
+ __call_after_micro_attribute
10
11
  end
11
12
  RUBY
12
13
  end
@@ -18,6 +19,10 @@ module Micro::Attributes
18
19
  def with_attributes(arg)
19
20
  self.class.new(attributes.merge(arg))
20
21
  end
22
+
23
+ private
24
+
25
+ def __call_after_micro_attribute; end
21
26
  end
22
27
  end
23
28
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro::Attributes
4
+ module Features
5
+ module Initialize
6
+ module Strict
7
+ module ClassMethods
8
+ def attributes_are_all_required?
9
+ true
10
+ end
11
+ end
12
+
13
+ def self.included(base)
14
+ base.send(:extend, ClassMethods)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,8 +3,31 @@
3
3
  module Micro
4
4
  module Attributes
5
5
  module Macros
6
- def __attributes_data
7
- @__attributes_data ||= {}
6
+ def attributes_are_all_required?
7
+ false
8
+ end
9
+
10
+ # NOTE: can't be renamed! It is used by u-case v4.
11
+ def __attributes_data__
12
+ @__attributes_data__ ||= {}
13
+ end
14
+
15
+ def __attributes_required__
16
+ @__attributes_required__ ||= Set.new
17
+ end
18
+
19
+ def __attributes_required_add(name, is_required, hasnt_default)
20
+ if is_required || (attributes_are_all_required? && hasnt_default)
21
+ __attributes_required__.add(name)
22
+ end
23
+
24
+ nil
25
+ end
26
+
27
+ def __attributes_data_to_assign(name, options)
28
+ hasnt_default = !options.key?(:default)
29
+
30
+ hasnt_default ? __attributes_required_add(name, options[:required], hasnt_default) : options[:default]
8
31
  end
9
32
 
10
33
  def __attributes
@@ -13,58 +36,65 @@ module Micro
13
36
 
14
37
  def __attribute_reader(name)
15
38
  __attributes.add(name)
39
+
16
40
  attr_reader(name)
17
41
  end
18
42
 
19
- def __attribute_set(key, value, can_overwrite)
43
+ def __attribute_assign(key, can_overwrite, options)
20
44
  name = key.to_s
21
45
  has_attribute = attribute?(name)
46
+
22
47
  __attribute_reader(name) unless has_attribute
23
- __attributes_data[name] = value if can_overwrite || !has_attribute
24
- end
25
48
 
26
- def __attributes_def(arg, can_overwrite)
27
- return __attribute_set(arg, nil, can_overwrite) unless arg.is_a?(::Hash)
28
- arg.each { |key, val| __attribute_set(key, val, can_overwrite) }
49
+ __attributes_data__[name] = __attributes_data_to_assign(name, options) if can_overwrite || !has_attribute
50
+
51
+ __call_after_attribute_assign__(name, options)
29
52
  end
30
53
 
31
- def __attributes_set(args, can_overwrite)
32
- args.flatten.each { |arg| __attributes_def(arg, can_overwrite) }
54
+ def __call_after_attribute_assign__(attr_name, options); end
55
+
56
+ # NOTE: can't be renamed! It is used by u-case v4.
57
+ def __attributes_set_after_inherit__(arg)
58
+ arg.each do |key, val|
59
+ __attribute_assign(key, true, val ? { default: val } : {})
60
+ end
33
61
  end
34
62
 
35
63
  def attribute?(name)
36
64
  __attributes.member?(name.to_s)
37
65
  end
38
66
 
39
- def attribute(name, value=nil)
40
- __attribute_set(name, value, false)
67
+ def attribute(name, options = Kind::Empty::HASH)
68
+ __attribute_assign(name, false, options)
41
69
  end
42
70
 
43
71
  def attributes(*args)
44
72
  return __attributes.to_a if args.empty?
45
- __attributes_set(args, can_overwrite: false)
46
- end
47
73
 
48
- def attributes_data(arg)
49
- __attributes_data.merge(AttributesUtils.stringify_hash_keys!(arg))
74
+ args.flatten!
75
+ args.each do |arg|
76
+ if arg.is_a?(String) || arg.is_a?(Symbol)
77
+ __attribute_assign(arg, false, Kind::Empty::HASH)
78
+ else
79
+ raise Kind::Error.new('String/Symbol'.freeze, arg)
80
+ end
81
+ end
50
82
  end
51
83
 
84
+ # NOTE: can't be renamed! It is used by u-case v4.
52
85
  module ForSubclasses
53
86
  WRONG_NUMBER_OF_ARGS = 'wrong number of arguments (given 0, expected 1 or more)'.freeze
54
87
 
55
- def attribute!(name, value=nil)
56
- __attribute_set(name, value, true)
57
- end
58
-
59
- def attributes!(*args)
60
- return __attributes_set(args, can_overwrite: true) unless args.empty?
61
- raise ArgumentError, WRONG_NUMBER_OF_ARGS
88
+ def attribute!(name, options = Kind::Empty::HASH)
89
+ __attribute_assign(name, true, options)
62
90
  end
63
91
 
64
92
  private_constant :WRONG_NUMBER_OF_ARGS
65
93
  end
94
+
66
95
  private_constant :ForSubclasses
67
96
  end
97
+
68
98
  private_constant :Macros
69
99
  end
70
100
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Attributes
5
+ module Utils
6
+ def self.stringify_hash_keys(arg)
7
+ hash = Kind::Of.(::Hash, arg)
8
+
9
+ return hash if hash.empty?
10
+
11
+ if hash.respond_to?(:transform_keys)
12
+ hash.transform_keys { |key| key.to_s }
13
+ else
14
+ hash.each_with_object({}) { |(key, val), memo| memo[key.to_s] = val }
15
+ end
16
+ end
17
+
18
+ HashAccess = -> (hash, key) {
19
+ return hash[key.to_s] unless hash[key.to_s].nil?
20
+
21
+ hash[key.to_sym]
22
+ }
23
+ end
24
+ end
25
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  module Attributes
5
- VERSION = '1.1.1'.freeze
5
+ VERSION = '2.1.1'.freeze
6
6
  end
7
7
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'micro/attributes/features/diff'
4
4
  require 'micro/attributes/features/initialize'
5
+ require 'micro/attributes/features/initialize/strict'
5
6
  require 'micro/attributes/features/activemodel_validations'
6
- require 'micro/attributes/features/strict_initialize'
7
7
 
8
8
  module Micro
9
9
  module Attributes
@@ -27,7 +27,7 @@ module Micro
27
27
 
28
28
  module ActiveModelValidations
29
29
  def self.included(base)
30
- base.send(:include, ::Micro::Attributes)
30
+ base.send(:include, Initialize)
31
31
  base.send(:include, ::Micro::Attributes::Features::ActiveModelValidations)
32
32
  end
33
33
  end
@@ -35,7 +35,7 @@ module Micro
35
35
  module StrictInitialize
36
36
  def self.included(base)
37
37
  base.send(:include, Initialize)
38
- base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
38
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
39
39
  end
40
40
  end
41
41
 
@@ -53,7 +53,7 @@ module Micro
53
53
  module DiffAndStrictInitialize
54
54
  def self.included(base)
55
55
  base.send(:include, DiffAndInitialize)
56
- base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
56
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
57
57
  end
58
58
  end
59
59
 
@@ -76,7 +76,7 @@ module Micro
76
76
  module ActiveModelValidationsAndStrictInitialize
77
77
  def self.included(base)
78
78
  base.send(:include, ActiveModelValidationsAndInitialize)
79
- base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
79
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
80
80
  end
81
81
  end
82
82
 
@@ -92,7 +92,7 @@ module Micro
92
92
  module ActiveModelValidationsAndDiffAndStrictInitialize
93
93
  def self.included(base)
94
94
  base.send(:include, ActiveModelValidationsAndDiffAndInitialize)
95
- base.send(:include, ::Micro::Attributes::Features::StrictInitialize)
95
+ base.send(:include, ::Micro::Attributes::Features::Initialize::Strict)
96
96
  end
97
97
  end
98
98
  end
@@ -1,28 +1,35 @@
1
1
 
2
- lib = File.expand_path("../lib", __FILE__)
2
+ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "micro/attributes/version"
4
+ require 'micro/attributes/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "u-attributes"
7
+ spec.name = 'u-attributes'
8
8
  spec.version = Micro::Attributes::VERSION
9
- spec.authors = ["Rodrigo Serradura"]
10
- spec.email = ["rodrigo.serradura@gmail.com"]
9
+ spec.authors = ['Rodrigo Serradura']
10
+ spec.email = ['rodrigo.serradura@gmail.com']
11
11
 
12
- spec.summary = %q{Define read-only attributes}
13
- spec.description = %q{This gem allows defining read-only attributes, that is, your objects will have only getters to access their attributes data.}
14
- spec.homepage = "https://github.com/serradura/u-attributes"
15
- spec.license = "MIT"
12
+ spec.summary = %q{Create "immutable" objects. No setters, just getters!}
13
+ spec.description =
14
+ "This gem allows you to define \"immutable\" objects, and your objects will have only getters and no setters. "\
15
+ "So, if you change some object attribute, you will have a new object instance. " \
16
+ "That is, you transform the object instead of modifying it."
17
+ spec.homepage = 'https://github.com/serradura/u-attributes'
18
+ spec.license = 'MIT'
16
19
 
17
20
  # Specify which files should be added to the gem when it is released.
18
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
22
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
23
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
24
  end
22
- spec.bindir = "exe"
25
+ spec.bindir = 'exe'
23
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
- spec.require_paths = ["lib"]
27
+ spec.require_paths = ['lib']
25
28
 
26
29
  spec.required_ruby_version = '>= 2.2.0'
27
- spec.add_development_dependency "rake", "~> 10.0"
30
+
31
+ spec.add_runtime_dependency 'kind', '>= 3.0', '< 5.0'
32
+
33
+ spec.add_development_dependency 'bundler'
34
+ spec.add_development_dependency 'rake', '~> 13.0'
28
35
  end
metadata CHANGED
@@ -1,31 +1,67 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-05 00:00:00.000000000 Z
11
+ date: 2020-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kind
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
13
47
  - !ruby/object:Gem::Dependency
14
48
  name: rake
15
49
  requirement: !ruby/object:Gem::Requirement
16
50
  requirements:
17
51
  - - "~>"
18
52
  - !ruby/object:Gem::Version
19
- version: '10.0'
53
+ version: '13.0'
20
54
  type: :development
21
55
  prerelease: false
22
56
  version_requirements: !ruby/object:Gem::Requirement
23
57
  requirements:
24
58
  - - "~>"
25
59
  - !ruby/object:Gem::Version
26
- version: '10.0'
27
- description: This gem allows defining read-only attributes, that is, your objects
28
- will have only getters to access their attributes data.
60
+ version: '13.0'
61
+ description: This gem allows you to define "immutable" objects, and your objects will
62
+ have only getters and no setters. So, if you change some object attribute, you will
63
+ have a new object instance. That is, you transform the object instead of modifying
64
+ it.
29
65
  email:
30
66
  - rodrigo.serradura@gmail.com
31
67
  executables: []
@@ -37,20 +73,21 @@ files:
37
73
  - ".travis.yml"
38
74
  - CODE_OF_CONDUCT.md
39
75
  - Gemfile
40
- - Gemfile.lock
41
76
  - LICENSE.txt
42
77
  - README.md
43
78
  - Rakefile
79
+ - assets/u-attributes_logo_v1.png
44
80
  - bin/console
45
81
  - bin/setup
46
82
  - lib/micro/attributes.rb
47
- - lib/micro/attributes/attributes_utils.rb
83
+ - lib/micro/attributes/diff.rb
48
84
  - lib/micro/attributes/features.rb
49
85
  - lib/micro/attributes/features/activemodel_validations.rb
50
86
  - lib/micro/attributes/features/diff.rb
51
87
  - lib/micro/attributes/features/initialize.rb
52
- - lib/micro/attributes/features/strict_initialize.rb
88
+ - lib/micro/attributes/features/initialize/strict.rb
53
89
  - lib/micro/attributes/macros.rb
90
+ - lib/micro/attributes/utils.rb
54
91
  - lib/micro/attributes/version.rb
55
92
  - lib/micro/attributes/with.rb
56
93
  - lib/u-attributes.rb
@@ -75,8 +112,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
112
  - !ruby/object:Gem::Version
76
113
  version: '0'
77
114
  requirements: []
78
- rubygems_version: 3.0.1
115
+ rubygems_version: 3.0.6
79
116
  signing_key:
80
117
  specification_version: 4
81
- summary: Define read-only attributes
118
+ summary: Create "immutable" objects. No setters, just getters!
82
119
  test_files: []
@@ -1,29 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- u-attributes (1.1.1)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- docile (1.3.2)
10
- json (2.2.0)
11
- minitest (5.11.3)
12
- rake (10.5.0)
13
- simplecov (0.17.0)
14
- docile (~> 1.1)
15
- json (>= 1.8, < 3)
16
- simplecov-html (~> 0.10.0)
17
- simplecov-html (0.10.2)
18
-
19
- PLATFORMS
20
- ruby
21
-
22
- DEPENDENCIES
23
- minitest (~> 5.0)
24
- rake (~> 10.0)
25
- simplecov
26
- u-attributes!
27
-
28
- BUNDLED WITH
29
- 1.17.3
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Micro
4
- module Attributes
5
- module AttributesUtils
6
- ARGUMENT_ERROR_MSG = 'argument must be a Hash'.freeze
7
-
8
- def self.hash_argument!(arg)
9
- return arg if arg.is_a?(Hash)
10
-
11
- raise ArgumentError, ARGUMENT_ERROR_MSG
12
- end
13
-
14
- def self.stringify_hash_keys!(arg)
15
- hash_argument!(arg).each_with_object({}) do |(key, val), memo|
16
- memo[key.to_s] = val
17
- end
18
- end
19
- end
20
- end
21
- end