class_composer 1.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,129 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "class_composer/default_object"
4
+ require "class_composer/generate_config"
5
+ require "class_composer/generator/instance_methods"
6
+ require "class_composer/generator/class_methods"
4
7
 
5
8
  module ClassComposer
9
+ FROZEN_TYPES = [
10
+ DEFAULT_FROZEN_TYPE = FROZEN_RAISE = :raise,
11
+ FROZEN_LOG_AND_ALLOW = :log_and_allow,
12
+ FROZEN_LOG_AND_SKIP = :log_and_skip,
13
+ ]
6
14
  module Generator
7
15
  def self.included(base)
8
16
  base.extend(ClassMethods)
9
- end
10
-
11
- module ClassMethods
12
- COMPOSER_VALIDATE_METHOD_NAME = ->(name) { :"__composer_#{name}_is_valid__?" }
13
- COMPOSER_ASSIGNED_ATTR_NAME = ->(name) { :"@__composer_#{name}_value_assigned__" }
14
- COMPOSER_ASSIGNED_ARRAY_METHODS = ->(name) { :"@__composer_#{name}_array_methods_set__" }
15
-
16
- def add_composer(name, allowed:, accessor: true, validator: ->(_) { true }, validation_error_klass: ::ClassComposer::ValidatorError, error_klass: ::ClassComposer::Error, **params)
17
- default =
18
- if params.has_key?(:default)
19
- params[:default]
20
- else
21
- if allowed.is_a?(Array)
22
- allowed << ClassComposer::DefaultObject
23
- else
24
- allowed = [allowed, ClassComposer::DefaultObject]
25
- end
26
- ClassComposer::DefaultObject
27
- end
28
-
29
- allowed.include?(ClassComposer::DefaultObject)
30
- validate_proc = __composer_validator_proc__(validator: validator, allowed: allowed, name: name, error_klass: error_klass)
31
- __composer_validate_options__!(name: name, validate_proc: validate_proc, default: default, validation_error_klass: validation_error_klass, error_klass: error_klass)
32
-
33
- array_proc = __composer_array_proc__(name: name, validator: validator, allowed: allowed, params: params)
34
- __composer_assignment__(name: name, allowed: allowed, params: params, validator: validate_proc, array_proc: array_proc, validation_error_klass: validation_error_klass, error_klass: error_klass)
35
- __composer_retrieval__(name: name, default: default, array_proc: array_proc)
36
- end
37
-
38
- def __composer_validate_options__!(name:, validate_proc:, default:, params: {}, validation_error_klass:, error_klass:)
39
- unless validate_proc.(default)
40
- raise validation_error_klass, "Default value [#{default}] for #{self.class}.#{name} is not valid"
41
- end
42
-
43
- if instance_methods.include?(name.to_sym)
44
- raise error_klass, "[#{name}] is already defined. Ensure composer names are all uniq and do not class with class instance methods"
45
- end
46
- end
47
-
48
- def __composer_array_proc__(name:, validator:, allowed:, params:)
49
- Proc.new do |value, _itself|
50
- _itself.send(:"#{name}=", value)
51
- end
52
- end
53
-
54
- # create assignment method for the incoming name
55
- def __composer_assignment__(name:, params:, allowed:, validator:, array_proc:, validation_error_klass:, error_klass:)
56
- define_method(:"#{name}=") do |value|
57
- is_valid = validator.(value)
58
-
59
- if is_valid
60
- instance_variable_set(COMPOSER_ASSIGNED_ATTR_NAME.(name), true)
61
- instance_variable_set(:"@#{name}", value)
62
- else
63
- message = ["#{self.class}.#{name} failed validation. #{name} is expected to be #{allowed}."]
64
-
65
- message << (params[:invalid_message].is_a?(Proc) ? params[:invalid_message].(value) : params[:invalid_message].to_s)
66
- if value.is_a?(Array)
67
- # we assigned the array value...pop it from the array
68
- # must be done after the message is created so that failing value can get passed appropriately
69
- value.pop
70
- end
71
- raise validation_error_klass, message.compact.join(" ")
72
- end
73
-
74
- if value.is_a?(Array) && !value.instance_variable_get(COMPOSER_ASSIGNED_ARRAY_METHODS.(name))
75
- _itself = itself
76
- value.define_singleton_method(:<<) do |val|
77
- array_proc.(super(val), _itself)
78
- end
79
- value.instance_variable_set(COMPOSER_ASSIGNED_ARRAY_METHODS.(name), true)
80
- end
81
-
82
- value
83
- end
84
- end
85
-
86
- # retrieve the value for the name -- Or return the default value
87
- def __composer_retrieval__(name:, default:, array_proc:)
88
- define_method(:"#{name}") do
89
- value = instance_variable_get(:"@#{name}")
90
- return value if instance_variable_get(COMPOSER_ASSIGNED_ATTR_NAME.(name))
91
-
92
- if default.is_a?(Array) && !default.instance_variable_get(COMPOSER_ASSIGNED_ARRAY_METHODS.(name))
93
- _itself = itself
94
- default.define_singleton_method(:<<) do |value|
95
- array_proc.(super(value), _itself)
96
- end
97
- default.instance_variable_set(COMPOSER_ASSIGNED_ARRAY_METHODS.(name), true)
98
- end
99
-
100
- default == ClassComposer::DefaultObject ? ClassComposer::DefaultObject.value : default
101
- end
102
- end
103
-
104
- # create validator method for incoming name
105
- def __composer_validator_proc__(validator:, allowed:, name:, error_klass:)
106
- if validator && !validator.is_a?(Proc)
107
- raise error_klass, "Expected validator to be a Proc. Received [#{validator.class}]"
108
- end
109
-
110
- # Proc will validate the entire attribute -- Full assignment must occur before validate is called
111
- Proc.new do |value|
112
- begin
113
- allow =
114
- if allowed.is_a?(Array)
115
- allowed.include?(value.class)
116
- else
117
- allowed == value.class
118
- end
119
- # order is important -- Do not run validator if it is the default object
120
- # Default object will likely raise an error if there is a custom validator
121
- (allowed.include?(ClassComposer::DefaultObject) && value == ClassComposer::DefaultObject) || (allow && validator.(value))
122
- rescue StandardError => e
123
- raise error_klass, "#{e} occured during validation for value [#{value}]. Check custom validator for #{name}"
124
- end
125
- end
126
- end
17
+ base.include(InstanceMethods)
127
18
  end
128
19
  end
129
20
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClassComposer
4
- VERSION = "1.0.2"
4
+ VERSION = "2.1.0"
5
5
  end
@@ -6,5 +6,4 @@ require "class_composer/generator"
6
6
  module ClassComposer
7
7
  class Error < StandardError; end
8
8
  class ValidatorError < Error; end
9
- # Your code goes here...
10
9
  end
metadata CHANGED
@@ -1,71 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class_composer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Taylor
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-04 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: pry-byebug
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '12.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '12.0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: simplecov
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 0.17.0
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 0.17.0
11
+ date: 2024-12-18 00:00:00.000000000 Z
12
+ dependencies: []
69
13
  description: Compose configurations for any class.
70
14
  email:
71
15
  - mattius.taylor@gmail.com
@@ -89,9 +33,18 @@ files:
89
33
  - bin/setup
90
34
  - class_composer.gemspec
91
35
  - docker-compose.yml
36
+ - docs/array_usage.md
37
+ - docs/basic_composer.md
38
+ - docs/basic_composer_example.md
39
+ - docs/composer_blocking.md
40
+ - docs/freezing.md
41
+ - docs/generating_initializer.md
92
42
  - lib/class_composer.rb
93
43
  - lib/class_composer/default_object.rb
44
+ - lib/class_composer/generate_config.rb
94
45
  - lib/class_composer/generator.rb
46
+ - lib/class_composer/generator/class_methods.rb
47
+ - lib/class_composer/generator/instance_methods.rb
95
48
  - lib/class_composer/version.rb
96
49
  homepage: https://github.com/matt-taylor/class_composer
97
50
  licenses:
@@ -107,14 +60,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
60
  requirements:
108
61
  - - ">="
109
62
  - !ruby/object:Gem::Version
110
- version: '2.7'
63
+ version: '3.1'
111
64
  required_rubygems_version: !ruby/object:Gem::Requirement
112
65
  requirements:
113
66
  - - ">="
114
67
  - !ruby/object:Gem::Version
115
68
  version: '0'
116
69
  requirements: []
117
- rubygems_version: 3.3.11
70
+ rubygems_version: 3.5.9
118
71
  signing_key:
119
72
  specification_version: 4
120
73
  summary: Easily compose a class via inline code or passed in YAML config. Add instance