typed_operation 0.4.2 → 1.0.0.beta2

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.
@@ -2,34 +2,87 @@
2
2
 
3
3
  module TypedOperation
4
4
  class PartiallyApplied
5
- def initialize(operation, **applied_args)
6
- @operation = operation
7
- @applied_args = applied_args
5
+ def initialize(operation_class, *positional_args, **keyword_args)
6
+ @operation_class = operation_class
7
+ @positional_args = positional_args
8
+ @keyword_args = keyword_args
8
9
  end
9
10
 
10
- def curry(**params)
11
- all_args = @applied_args.merge(params)
12
- # check if required attrs are in @applied_args
13
- required_keys = @operation.attribute_names.select do |name|
14
- meta = @operation.attribute_metadata(name)
15
- meta[:required] != false && !meta[:typed_attribute_options].key?(:default)
16
- end
17
- missing_keys = required_keys - all_args.keys
11
+ def with(*positional, **keyword)
12
+ all_positional = positional_args + positional
13
+ all_kw_args = keyword_args.merge(keyword)
14
+
15
+ validate_positional_arg_count!(all_positional.size)
18
16
 
19
- if missing_keys.size > 0
20
- # Partially apply the arguments
21
- PartiallyApplied.new(@operation, **all_args)
17
+ if partially_applied?(all_positional, all_kw_args)
18
+ PartiallyApplied.new(operation_class, *all_positional, **all_kw_args)
22
19
  else
23
- Prepared.new(@operation, **all_args)
20
+ Prepared.new(operation_class, *all_positional, **all_kw_args)
24
21
  end
25
22
  end
26
- alias_method :[], :curry
27
- alias_method :with, :curry
23
+ alias_method :[], :with
24
+
25
+ def curry
26
+ Curried.new(operation_class, self)
27
+ end
28
28
 
29
29
  def call(...)
30
- prepared = curry(...)
30
+ prepared = with(...)
31
31
  return prepared.operation.call if prepared.is_a?(Prepared)
32
- raise TypedOperation::MissingParameterError, "Cannot call PartiallyApplied operation #{@operation.name} (key: #{@operation.operation_key}), are you expecting it to be Prepared?"
32
+ raise MissingParameterError, "Cannot call PartiallyApplied operation #{operation_class.name} (key: #{operation_class.name}), are you expecting it to be Prepared?"
33
+ end
34
+
35
+ def operation
36
+ raise MissingParameterError, "Cannot instantiate Operation #{operation_class.name} (key: #{operation_class.name}), as it is only partially applied."
37
+ end
38
+
39
+ def prepared?
40
+ false
41
+ end
42
+
43
+ def to_proc
44
+ method(:call).to_proc
45
+ end
46
+
47
+ def deconstruct
48
+ positional_args + keyword_args.values
49
+ end
50
+
51
+ def deconstruct_keys(keys)
52
+ h = keyword_args.dup
53
+ positional_args.each_with_index { |v, i| h[positional_parameters[i]] = v }
54
+ keys ? h.slice(*keys) : h
55
+ end
56
+
57
+ attr_reader :positional_args, :keyword_args
58
+
59
+ private
60
+
61
+ attr_reader :operation_class
62
+
63
+ def required_positional_parameters
64
+ @required_positional_parameters ||= operation_class.required_positional_parameters
65
+ end
66
+
67
+ def required_keyword_parameters
68
+ @required_keyword_parameters ||= operation_class.required_keyword_parameters
69
+ end
70
+
71
+ def positional_parameters
72
+ @positional_parameters ||= operation_class.positional_parameters
73
+ end
74
+
75
+ def validate_positional_arg_count!(count)
76
+ if count > positional_parameters.size
77
+ raise ArgumentError, "Too many positional arguments provided for #{operation_class.name} (key: #{operation_class.name})"
78
+ end
79
+ end
80
+
81
+ def partially_applied?(all_positional, all_kw_args)
82
+ missing_positional = required_positional_parameters.size - all_positional.size
83
+ missing_keys = required_keyword_parameters - all_kw_args.keys
84
+
85
+ missing_positional > 0 || missing_keys.size > 0
33
86
  end
34
87
  end
35
88
  end
@@ -3,7 +3,11 @@
3
3
  module TypedOperation
4
4
  class Prepared < PartiallyApplied
5
5
  def operation
6
- @operation.new(**@applied_args)
6
+ operation_class.new(*@positional_args, **@keyword_args)
7
+ end
8
+
9
+ def prepared?
10
+ true
7
11
  end
8
12
  end
9
13
  end
@@ -1,3 +1,3 @@
1
1
  module TypedOperation
2
- VERSION = "0.4.2"
2
+ VERSION = "1.0.0.beta2"
3
3
  end
@@ -1,11 +1,28 @@
1
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2.0")
2
+ require "polyfill-data"
3
+ end
4
+
5
+ require "literal"
6
+
1
7
  require "typed_operation/version"
2
- require "typed_operation/railtie"
8
+ require "typed_operation/railtie" if defined?(Rails::Railtie)
9
+ require "typed_operation/operations/introspection"
10
+ require "typed_operation/operations/parameters"
11
+ require "typed_operation/operations/partial_application"
12
+ require "typed_operation/operations/callable"
13
+ require "typed_operation/operations/lifecycle"
14
+ require "typed_operation/operations/property_builder"
15
+ require "typed_operation/operations/executable"
16
+ require "typed_operation/curried"
17
+ require "typed_operation/immutable_base"
3
18
  require "typed_operation/base"
4
19
  require "typed_operation/partially_applied"
5
20
  require "typed_operation/prepared"
6
21
 
7
22
  module TypedOperation
8
23
  class InvalidOperationError < StandardError; end
24
+
9
25
  class MissingParameterError < ArgumentError; end
26
+
10
27
  class ParameterError < TypeError; end
11
28
  end
metadata CHANGED
@@ -1,65 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typed_operation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 1.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Ierodiaconou
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-27 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rails
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '6.0'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '8.0'
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: '6.0'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '8.0'
33
- - !ruby/object:Gem::Dependency
34
- name: vident-typed
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: 0.1.0
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: 0.1.0
47
- - !ruby/object:Gem::Dependency
48
- name: dry-initializer
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '3.0'
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '3.0'
61
- description: TypedOperation is a command pattern implementation where inputs can be
62
- defined with runtime type checks. Operations can be partially applied.
11
+ date: 2024-06-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Command pattern, which is callable, and can be partially applied, curried
14
+ and has typed parameters. Authorization to execute via action_policy if desired.
63
15
  email:
64
16
  - stevegeek@gmail.com
65
17
  executables: []
@@ -68,7 +20,6 @@ extra_rdoc_files: []
68
20
  files:
69
21
  - MIT-LICENSE
70
22
  - README.md
71
- - Rakefile
72
23
  - lib/generators/USAGE
73
24
  - lib/generators/templates/operation.rb
74
25
  - lib/generators/templates/operation_test.rb
@@ -76,9 +27,18 @@ files:
76
27
  - lib/generators/typed_operation/install/install_generator.rb
77
28
  - lib/generators/typed_operation/install/templates/application_operation.rb
78
29
  - lib/generators/typed_operation_generator.rb
79
- - lib/tasks/typed_operation_tasks.rake
80
30
  - lib/typed_operation.rb
31
+ - lib/typed_operation/action_policy_auth.rb
81
32
  - lib/typed_operation/base.rb
33
+ - lib/typed_operation/curried.rb
34
+ - lib/typed_operation/immutable_base.rb
35
+ - lib/typed_operation/operations/callable.rb
36
+ - lib/typed_operation/operations/executable.rb
37
+ - lib/typed_operation/operations/introspection.rb
38
+ - lib/typed_operation/operations/lifecycle.rb
39
+ - lib/typed_operation/operations/parameters.rb
40
+ - lib/typed_operation/operations/partial_application.rb
41
+ - lib/typed_operation/operations/property_builder.rb
82
42
  - lib/typed_operation/partially_applied.rb
83
43
  - lib/typed_operation/prepared.rb
84
44
  - lib/typed_operation/railtie.rb
@@ -97,15 +57,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
57
  requirements:
98
58
  - - ">="
99
59
  - !ruby/object:Gem::Version
100
- version: '0'
60
+ version: '3.2'
101
61
  required_rubygems_version: !ruby/object:Gem::Requirement
102
62
  requirements:
103
63
  - - ">="
104
64
  - !ruby/object:Gem::Version
105
65
  version: '0'
106
66
  requirements: []
107
- rubygems_version: 3.4.10
67
+ rubygems_version: 3.5.3
108
68
  signing_key:
109
69
  specification_version: 4
110
- summary: TypedOperation is a command pattern implementation
70
+ summary: TypedOperation is a command pattern with typed parameters, which is callable,
71
+ and can be partially applied.
111
72
  test_files: []
data/Rakefile DELETED
@@ -1,3 +0,0 @@
1
- require "bundler/setup"
2
-
3
- require "bundler/gem_tasks"
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :typed_operation do
3
- # # Task goes here
4
- # end