typed_operation 1.0.0.pre3 → 1.0.0
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.
- checksums.yaml +4 -4
- data/README.md +76 -624
- data/lib/generators/typed_operation/install/USAGE +1 -0
- data/lib/generators/typed_operation/install/install_generator.rb +8 -0
- data/lib/generators/typed_operation/install/templates/application_operation.rb +24 -2
- data/lib/generators/typed_operation_generator.rb +8 -4
- data/lib/typed_operation/action_policy_auth.rb +161 -0
- data/lib/typed_operation/base.rb +4 -13
- data/lib/typed_operation/callable_resolver.rb +30 -0
- data/lib/typed_operation/chains/chained_operation.rb +27 -0
- data/lib/typed_operation/chains/fallback_chain.rb +32 -0
- data/lib/typed_operation/chains/map_chain.rb +37 -0
- data/lib/typed_operation/chains/sequence_chain.rb +54 -0
- data/lib/typed_operation/chains/smart_chain.rb +161 -0
- data/lib/typed_operation/chains/splat_chain.rb +53 -0
- data/lib/typed_operation/configuration.rb +52 -0
- data/lib/typed_operation/context.rb +193 -0
- data/lib/typed_operation/curried.rb +14 -1
- data/lib/typed_operation/explainable.rb +14 -0
- data/lib/typed_operation/immutable_base.rb +4 -2
- data/lib/typed_operation/instrumentation/trace.rb +71 -0
- data/lib/typed_operation/instrumentation/tree_formatter.rb +141 -0
- data/lib/typed_operation/instrumentation.rb +214 -0
- data/lib/typed_operation/operations/composition.rb +41 -0
- data/lib/typed_operation/operations/executable.rb +27 -1
- data/lib/typed_operation/operations/introspection.rb +14 -8
- data/lib/typed_operation/operations/lifecycle.rb +5 -2
- data/lib/typed_operation/operations/parameters.rb +21 -6
- data/lib/typed_operation/operations/partial_application.rb +4 -0
- data/lib/typed_operation/operations/property_builder.rb +105 -0
- data/lib/typed_operation/partially_applied.rb +33 -10
- data/lib/typed_operation/pipeline/builder.rb +88 -0
- data/lib/typed_operation/pipeline/chainable_wrapper.rb +23 -0
- data/lib/typed_operation/pipeline/empty_pipeline_chain.rb +25 -0
- data/lib/typed_operation/pipeline/step_wrapper.rb +94 -0
- data/lib/typed_operation/pipeline.rb +176 -0
- data/lib/typed_operation/prepared.rb +13 -0
- data/lib/typed_operation/railtie.rb +4 -0
- data/lib/typed_operation/result/adapters/built_in.rb +28 -0
- data/lib/typed_operation/result/adapters/dry_monads.rb +36 -0
- data/lib/typed_operation/result/failure.rb +78 -0
- data/lib/typed_operation/result/mixin.rb +24 -0
- data/lib/typed_operation/result/success.rb +75 -0
- data/lib/typed_operation/result.rb +39 -0
- data/lib/typed_operation/version.rb +5 -1
- data/lib/typed_operation.rb +18 -6
- metadata +58 -18
- data/Rakefile +0 -17
- data/lib/tasks/typed_operation_tasks.rake +0 -4
- data/lib/typed_operation/operations/attribute_builder.rb +0 -81
- data/lib/typed_operation/operations/callable.rb +0 -23
- data/lib/typed_operation/operations/deconstruct.rb +0 -16
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative "result/success"
|
|
5
|
+
require_relative "result/failure"
|
|
6
|
+
require_relative "result/adapters/built_in"
|
|
7
|
+
require_relative "result/adapters/dry_monads"
|
|
8
|
+
require_relative "result/mixin"
|
|
9
|
+
|
|
10
|
+
module TypedOperation
|
|
11
|
+
# Result types for representing success and failure outcomes.
|
|
12
|
+
#
|
|
13
|
+
# TypedOperation provides built-in Success and Failure types that work
|
|
14
|
+
# out of the box. You can also configure it to use Dry::Monads or a
|
|
15
|
+
# custom adapter.
|
|
16
|
+
#
|
|
17
|
+
# @example Default usage (built-in types)
|
|
18
|
+
# result = MyPipeline.call(input)
|
|
19
|
+
# result.success? # => true or false
|
|
20
|
+
# result.value! # => the value (raises on failure)
|
|
21
|
+
#
|
|
22
|
+
# @example Configure to use Dry::Monads
|
|
23
|
+
# TypedOperation.configure do |config|
|
|
24
|
+
# config.result_adapter = :dry_monads
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# @example Pattern matching
|
|
28
|
+
# case result
|
|
29
|
+
# in Success[value]
|
|
30
|
+
# handle_success(value)
|
|
31
|
+
# in Failure[error]
|
|
32
|
+
# handle_failure(error)
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
module Result
|
|
36
|
+
# Alias for easy access to UnwrapError from Result module
|
|
37
|
+
UnwrapError = TypedOperation::UnwrapError
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/typed_operation.rb
CHANGED
|
@@ -1,25 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
require "polyfill-data"
|
|
3
|
-
end
|
|
1
|
+
# rbs_inline: enabled
|
|
4
2
|
|
|
5
3
|
require "literal"
|
|
6
4
|
|
|
7
5
|
require "typed_operation/version"
|
|
8
6
|
require "typed_operation/railtie" if defined?(Rails::Railtie)
|
|
7
|
+
require "typed_operation/result"
|
|
8
|
+
require "typed_operation/configuration"
|
|
9
9
|
require "typed_operation/operations/introspection"
|
|
10
10
|
require "typed_operation/operations/parameters"
|
|
11
11
|
require "typed_operation/operations/partial_application"
|
|
12
|
-
require "typed_operation/operations/callable"
|
|
13
12
|
require "typed_operation/operations/lifecycle"
|
|
14
|
-
require "typed_operation/operations/
|
|
15
|
-
require "typed_operation/operations/attribute_builder"
|
|
13
|
+
require "typed_operation/operations/property_builder"
|
|
16
14
|
require "typed_operation/operations/executable"
|
|
15
|
+
require "typed_operation/operations/composition"
|
|
17
16
|
require "typed_operation/curried"
|
|
17
|
+
require "typed_operation/instrumentation"
|
|
18
|
+
require "typed_operation/explainable"
|
|
18
19
|
require "typed_operation/immutable_base"
|
|
19
20
|
require "typed_operation/base"
|
|
20
21
|
require "typed_operation/partially_applied"
|
|
21
22
|
require "typed_operation/prepared"
|
|
23
|
+
require "typed_operation/callable_resolver"
|
|
24
|
+
require "typed_operation/chains/chained_operation"
|
|
25
|
+
require "typed_operation/chains/sequence_chain"
|
|
26
|
+
require "typed_operation/chains/splat_chain"
|
|
27
|
+
require "typed_operation/chains/smart_chain"
|
|
28
|
+
require "typed_operation/chains/map_chain"
|
|
29
|
+
require "typed_operation/chains/fallback_chain"
|
|
30
|
+
require "typed_operation/context"
|
|
31
|
+
require "typed_operation/pipeline"
|
|
22
32
|
|
|
33
|
+
# TypedOperation provides a framework for defining type-safe, composable operations
|
|
34
|
+
# with support for partial application, currying, and parameter validation.
|
|
23
35
|
module TypedOperation
|
|
24
36
|
class InvalidOperationError < StandardError; end
|
|
25
37
|
|
metadata
CHANGED
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: typed_operation
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.0
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stephen Ierodiaconou
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
-
dependencies:
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: literal
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 1.9.0
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 2.0.0
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: 1.9.0
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: 2.0.0
|
|
32
|
+
description: Command pattern, which is callable, and can be partially applied, curried
|
|
33
|
+
and has typed parameters. Authorization to execute via action_policy if desired.
|
|
15
34
|
email:
|
|
16
35
|
- stevegeek@gmail.com
|
|
17
36
|
executables: []
|
|
@@ -20,7 +39,6 @@ extra_rdoc_files: []
|
|
|
20
39
|
files:
|
|
21
40
|
- MIT-LICENSE
|
|
22
41
|
- README.md
|
|
23
|
-
- Rakefile
|
|
24
42
|
- lib/generators/USAGE
|
|
25
43
|
- lib/generators/templates/operation.rb
|
|
26
44
|
- lib/generators/templates/operation_test.rb
|
|
@@ -28,22 +46,45 @@ files:
|
|
|
28
46
|
- lib/generators/typed_operation/install/install_generator.rb
|
|
29
47
|
- lib/generators/typed_operation/install/templates/application_operation.rb
|
|
30
48
|
- lib/generators/typed_operation_generator.rb
|
|
31
|
-
- lib/tasks/typed_operation_tasks.rake
|
|
32
49
|
- lib/typed_operation.rb
|
|
50
|
+
- lib/typed_operation/action_policy_auth.rb
|
|
33
51
|
- lib/typed_operation/base.rb
|
|
52
|
+
- lib/typed_operation/callable_resolver.rb
|
|
53
|
+
- lib/typed_operation/chains/chained_operation.rb
|
|
54
|
+
- lib/typed_operation/chains/fallback_chain.rb
|
|
55
|
+
- lib/typed_operation/chains/map_chain.rb
|
|
56
|
+
- lib/typed_operation/chains/sequence_chain.rb
|
|
57
|
+
- lib/typed_operation/chains/smart_chain.rb
|
|
58
|
+
- lib/typed_operation/chains/splat_chain.rb
|
|
59
|
+
- lib/typed_operation/configuration.rb
|
|
60
|
+
- lib/typed_operation/context.rb
|
|
34
61
|
- lib/typed_operation/curried.rb
|
|
62
|
+
- lib/typed_operation/explainable.rb
|
|
35
63
|
- lib/typed_operation/immutable_base.rb
|
|
36
|
-
- lib/typed_operation/
|
|
37
|
-
- lib/typed_operation/
|
|
38
|
-
- lib/typed_operation/
|
|
64
|
+
- lib/typed_operation/instrumentation.rb
|
|
65
|
+
- lib/typed_operation/instrumentation/trace.rb
|
|
66
|
+
- lib/typed_operation/instrumentation/tree_formatter.rb
|
|
67
|
+
- lib/typed_operation/operations/composition.rb
|
|
39
68
|
- lib/typed_operation/operations/executable.rb
|
|
40
69
|
- lib/typed_operation/operations/introspection.rb
|
|
41
70
|
- lib/typed_operation/operations/lifecycle.rb
|
|
42
71
|
- lib/typed_operation/operations/parameters.rb
|
|
43
72
|
- lib/typed_operation/operations/partial_application.rb
|
|
73
|
+
- lib/typed_operation/operations/property_builder.rb
|
|
44
74
|
- lib/typed_operation/partially_applied.rb
|
|
75
|
+
- lib/typed_operation/pipeline.rb
|
|
76
|
+
- lib/typed_operation/pipeline/builder.rb
|
|
77
|
+
- lib/typed_operation/pipeline/chainable_wrapper.rb
|
|
78
|
+
- lib/typed_operation/pipeline/empty_pipeline_chain.rb
|
|
79
|
+
- lib/typed_operation/pipeline/step_wrapper.rb
|
|
45
80
|
- lib/typed_operation/prepared.rb
|
|
46
81
|
- lib/typed_operation/railtie.rb
|
|
82
|
+
- lib/typed_operation/result.rb
|
|
83
|
+
- lib/typed_operation/result/adapters/built_in.rb
|
|
84
|
+
- lib/typed_operation/result/adapters/dry_monads.rb
|
|
85
|
+
- lib/typed_operation/result/failure.rb
|
|
86
|
+
- lib/typed_operation/result/mixin.rb
|
|
87
|
+
- lib/typed_operation/result/success.rb
|
|
47
88
|
- lib/typed_operation/version.rb
|
|
48
89
|
homepage: https://github.com/stevegeek/typed_operation
|
|
49
90
|
licenses:
|
|
@@ -51,7 +92,6 @@ licenses:
|
|
|
51
92
|
metadata:
|
|
52
93
|
homepage_uri: https://github.com/stevegeek/typed_operation
|
|
53
94
|
source_code_uri: https://github.com/stevegeek/typed_operation
|
|
54
|
-
post_install_message:
|
|
55
95
|
rdoc_options: []
|
|
56
96
|
require_paths:
|
|
57
97
|
- lib
|
|
@@ -59,15 +99,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
59
99
|
requirements:
|
|
60
100
|
- - ">="
|
|
61
101
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: '3.
|
|
102
|
+
version: '3.2'
|
|
63
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
104
|
requirements:
|
|
65
|
-
- - "
|
|
105
|
+
- - ">="
|
|
66
106
|
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
107
|
+
version: '0'
|
|
68
108
|
requirements: []
|
|
69
|
-
rubygems_version:
|
|
70
|
-
signing_key:
|
|
109
|
+
rubygems_version: 4.0.3
|
|
71
110
|
specification_version: 4
|
|
72
|
-
summary: TypedOperation is a command pattern
|
|
111
|
+
summary: TypedOperation is a command pattern with typed parameters, which is callable,
|
|
112
|
+
and can be partially applied.
|
|
73
113
|
test_files: []
|
data/Rakefile
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/gem_tasks"
|
|
4
|
-
require "bundler/setup"
|
|
5
|
-
require "rake/testtask"
|
|
6
|
-
|
|
7
|
-
ENV["NO_RAILS"] = "true"
|
|
8
|
-
|
|
9
|
-
Rake::TestTask.new(:test) do |t|
|
|
10
|
-
t.libs << "test"
|
|
11
|
-
t.libs << "lib"
|
|
12
|
-
t.test_files = FileList["test/typed_operation/**/*_test.rb"]
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
require "standard/rake"
|
|
16
|
-
|
|
17
|
-
task default: %i[test standard]
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module TypedOperation
|
|
4
|
-
module Operations
|
|
5
|
-
class AttributeBuilder
|
|
6
|
-
def initialize(typed_operation, parameter_name, type_signature, options)
|
|
7
|
-
@typed_operation = typed_operation
|
|
8
|
-
@name = parameter_name
|
|
9
|
-
@signature = type_signature
|
|
10
|
-
@optional = options[:optional]
|
|
11
|
-
@positional = options[:positional]
|
|
12
|
-
@reader = options[:reader] || :public
|
|
13
|
-
@default_key = options.key?(:default)
|
|
14
|
-
@default = options[:default]
|
|
15
|
-
|
|
16
|
-
prepare_type_signature_for_literal
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def define(&converter)
|
|
20
|
-
# If nilable, then converter should not attempt to call the type converter block if the value is nil
|
|
21
|
-
coerce_by = if type_nilable? && converter
|
|
22
|
-
->(v) { (v == Literal::Null || v.nil?) ? v : converter.call(v) }
|
|
23
|
-
else
|
|
24
|
-
converter
|
|
25
|
-
end
|
|
26
|
-
@typed_operation.attribute(
|
|
27
|
-
@name,
|
|
28
|
-
@signature,
|
|
29
|
-
default: default_value_for_literal,
|
|
30
|
-
positional: @positional,
|
|
31
|
-
reader: @reader,
|
|
32
|
-
&coerce_by
|
|
33
|
-
)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
def prepare_type_signature_for_literal
|
|
39
|
-
@signature = Literal::Types::NilableType.new(@signature) if needs_to_be_nilable?
|
|
40
|
-
union_with_nil_to_support_nil_default
|
|
41
|
-
validate_positional_order_params! if @positional
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# If already wrapped in a Nilable then don't wrap again
|
|
45
|
-
def needs_to_be_nilable?
|
|
46
|
-
@optional && !type_nilable?
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def type_nilable?
|
|
50
|
-
@signature.is_a?(Literal::Types::NilableType)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def union_with_nil_to_support_nil_default
|
|
54
|
-
@signature = Literal::Union.new(@signature, NilClass) if has_default_value_nil?
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def has_default_value_nil?
|
|
58
|
-
default_provided? && @default.nil?
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def validate_positional_order_params!
|
|
62
|
-
# Optional ones can always be added after required ones, or before any others, but required ones must be first
|
|
63
|
-
unless type_nilable? || @typed_operation.optional_positional_parameters.empty?
|
|
64
|
-
raise ParameterError, "Cannot define required positional parameter '#{@name}' after optional positional parameters"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def default_provided?
|
|
69
|
-
@default_key
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def default_value_for_literal
|
|
73
|
-
if has_default_value_nil? || type_nilable?
|
|
74
|
-
-> {}
|
|
75
|
-
else
|
|
76
|
-
@default
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module TypedOperation
|
|
4
|
-
module Operations
|
|
5
|
-
module Callable
|
|
6
|
-
def self.included(base)
|
|
7
|
-
base.extend(CallableMethods)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
module CallableMethods
|
|
11
|
-
def call(...)
|
|
12
|
-
new(...).call
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def to_proc
|
|
16
|
-
method(:call).to_proc
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
include CallableMethods
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module TypedOperation
|
|
4
|
-
module Operations
|
|
5
|
-
module Deconstruct
|
|
6
|
-
def deconstruct
|
|
7
|
-
attributes.values
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def deconstruct_keys(keys)
|
|
11
|
-
h = attributes.to_h
|
|
12
|
-
keys ? h.slice(*keys) : h
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|