bcdd-process 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b912c6dd7bbc76a3a091da0e5d722fea38b97ff0ac93f61a4477e20e8ba7d26
4
- data.tar.gz: c0161a5ccc0f6275b28187b822dd20dc9d35640b7461827bef8fcbe5beb9b491
3
+ metadata.gz: 60c6b5184edd4076e88382736efff9e0981be518c064ae290a75ad4d052d3196
4
+ data.tar.gz: ca15261b4991198f5277cddf5f2c2133458e7163f8388e39d5a0c18dad688bce
5
5
  SHA512:
6
- metadata.gz: cf2fd171d9beae0ba6d90f768fbd4c8966f4a2e2d54d7c7ec9d220b35f0f0ab420cfeb3d786f6749165480eb888dacae9ae1a2a521c0e7d284b859addf618e4e
7
- data.tar.gz: 65848285149f38f9d88114e8a1277e2b4f943237a056e7a519fb2fcaab4a7d17a47edaa0fdb351f4252d898ba56313ed27ad79401cb704be1f338589c53d863a
6
+ metadata.gz: 4dd1a4bf3e06a13060233215ea6ad8ee1f0a0a6a4be94d202a6126833fe62a68504a4af677f2f4a8b34abb39a3124a6b8d25009569dfa2d3050debaad45dbd9b
7
+ data.tar.gz: '08daaa2746fd38c0db77c1d131080923693c697d19577d2b33dded81f1a9675c4a841650bba799c46b24a2e8ba6de06c4370ba143ab7b65578ab0fb90eddac84'
data/.rubocop.yml CHANGED
@@ -49,6 +49,9 @@ Style/ParallelAssignment:
49
49
  Style/SingleLineMethods:
50
50
  Enabled: false
51
51
 
52
+ Style/FormatStringToken:
53
+ Enabled: false
54
+
52
55
  Style/MapToSet:
53
56
  Enabled: false
54
57
 
@@ -64,6 +67,10 @@ Naming/VariableName:
64
67
  Naming/MemoizedInstanceVariableName:
65
68
  Enabled: false
66
69
 
70
+ Metrics/AbcSize:
71
+ Exclude:
72
+ - lib/bcdd/ext/value.rb
73
+
67
74
  Metrics/BlockLength:
68
75
  Exclude:
69
76
  - test/**/*.rb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2024-02-04
4
+
5
+ ### Added
6
+
7
+ - Add `:value` input property to use a registered `BCDD::Value` to handle the input.
8
+ ```ruby
9
+ attribute :name, value: :name
10
+ ```
11
+
12
+ - Add `:respond_to` input property to check if the value responds to a given method.
13
+ ```ruby
14
+ attribute :name, respond_to: :strip
15
+ ```
16
+
17
+ ### Changed
18
+
19
+ - Use `:type` property to check if the normalize should be applied.
20
+ ```ruby
21
+ attribute :name, type: String, normalize: -> { _1.strip }
22
+ ```
23
+
3
24
  ## [0.3.1] - 2024-02-03
4
25
 
5
26
  ### Fixed
@@ -5,7 +5,7 @@ class Account
5
5
  include BCDD::Result::RollbackOnFailure
6
6
 
7
7
  input do
8
- attribute :uuid, contract: :is_uuid, normalize: -> { _1.strip.downcase }, default: -> { ::SecureRandom.uuid }
8
+ attribute :uuid, value: :uuid
9
9
  attribute :owner, type: ::Hash, contract: :is_present
10
10
  end
11
11
 
@@ -5,7 +5,7 @@ class User
5
5
  include BCDD::Result::RollbackOnFailure
6
6
 
7
7
  input do
8
- attribute :uuid, contract: :is_uuid, normalize: -> { _1.strip.downcase }, default: -> { ::SecureRandom.uuid }
8
+ attribute :uuid, value: :uuid
9
9
  attribute :name, contract: :is_str, normalize: -> { _1.strip.gsub(/\s+/, ' ') }
10
10
  attribute :email, contract: :is_email, normalize: -> { _1.strip.downcase }
11
11
  attribute :password, contract: :is_password
@@ -12,6 +12,7 @@ require 'db/setup'
12
12
  require 'lib/bcdd/result/rollback_on_failure'
13
13
  require 'lib/bcdd/result/transitions_record'
14
14
  require 'lib/bcdd/contracts'
15
+ require 'lib/bcdd/values/uuid'
15
16
  require 'lib/runtime_breaker'
16
17
 
17
18
  module TransitionsListener
@@ -4,14 +4,12 @@ module BCDD::Contracts
4
4
  HasSize = ->(min, max) { ->(val) { val.size.between?(min, max) or "must be >= #{min} and <= #{max} chars" } }
5
5
 
6
6
  is_str = contract[::String]
7
- is_uuid = ->(val) { val.match?(/\A[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}\z/) or '%p must be an UUID' }
8
7
  is_email = ->(val) { val.match?(::URI::MailTo::EMAIL_REGEXP) or '%p must be an email' }
9
8
  is_present = ->(val) { val.present? or '%p must be present' }
10
9
  is_persisted = ->(val) { val.persisted? or '%p must be persisted' }
11
10
 
12
11
  register(
13
12
  is_str: is_str,
14
- is_uuid: is_str & is_present & is_uuid,
15
13
  is_email: is_str & is_present& is_email,
16
14
  is_present: is_present,
17
15
  is_password: is_str & is_present & HasSize[8, 72],
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../contracts'
4
+
5
+ module BCDD
6
+ module Contracts
7
+ is_uuid = ->(val) { val.match?(/\A[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}\z/) or '%p must be an UUID' }
8
+
9
+ register(is_uuid: contract[::String] & :is_present & is_uuid)
10
+ end
11
+
12
+ module Values
13
+ register(
14
+ name: :uuid,
15
+ type: ::String,
16
+ contract: :is_uuid,
17
+ normalize: -> { _1.strip.downcase },
18
+ default: -> { ::SecureRandom.uuid }
19
+ )
20
+ end
21
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDD::Contract
4
+ # TODO: Move to bcdd-contract
5
+ module RespondTo
6
+ class Checking
7
+ include Core::Checking
8
+
9
+ def initialize(method_names, value)
10
+ @value = value
11
+ @errors = []
12
+
13
+ validate(method_names, @errors)
14
+ end
15
+
16
+ def errors_message
17
+ valid? ? '' : errors[0]
18
+ end
19
+
20
+ private
21
+
22
+ def validate(method_names, errors)
23
+ return if method_names.all? { |method_name| value.respond_to?(method_name) }
24
+
25
+ errors << format('%p must respond to %p', value, method_names)
26
+ end
27
+ end
28
+
29
+ module Checker
30
+ include Core::Checker
31
+ end
32
+
33
+ def self.new(args)
34
+ args.is_a?(Array) or raise ::ArgumentError, format('%p must be an array', args)
35
+
36
+ raise ::ArgumentError, "Must provide at least one symbol #{args.inspect}" if args.empty? || !args.all?(::Symbol)
37
+
38
+ Core::Factory.new(Checker, Checking, args)
39
+ end
40
+ end
41
+
42
+ # TODO: Move to bcdd-contract
43
+ def self.respond_to(args)
44
+ RespondTo.new(args)
45
+ end
46
+
47
+ private_constant :RespondTo
48
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bcdd/contract'
4
+
5
+ require_relative 'contracts'
6
+ require_relative 'contract/null'
7
+ require_relative 'contract/respond_to'
8
+
9
+ module BCDD::Contract
10
+ # TODO: Move to bcdd-contract
11
+ def self.type(arg)
12
+ arg.is_a?(::Module) or raise ::ArgumentError, format('%p must be a class OR module', arg)
13
+
14
+ unit(arg)
15
+ end
16
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'value'
4
+
5
+ module BCDD
6
+ class Data
7
+ class Object
8
+ attr_reader :attributes, :errors
9
+
10
+ def initialize(**kargs)
11
+ properties = self.class::Properties
12
+ attributes = properties.map(kargs)
13
+
14
+ @errors = {}
15
+ @attributes =
16
+ if properties.contract?
17
+ attributes.each_with_object({}) do |(key, value), output|
18
+ output[key] = value.valid? ? value.value : (errors[key] = value.errors)
19
+ end
20
+ else
21
+ attributes.transform_values!(&:value)
22
+ end
23
+ end
24
+ end
25
+
26
+ class Properties
27
+ attr_reader :spec, :contract
28
+
29
+ def initialize
30
+ @spec = {}
31
+ @contract = false
32
+ end
33
+
34
+ def attribute(name, **options)
35
+ name.is_a?(Symbol) or raise ArgumentError, "#{name.inspect} must be a Symbol"
36
+
37
+ value_option = options[:value]
38
+
39
+ spec[name] =
40
+ if value_option
41
+ (value_option.is_a?(Value::Object) ? value_option : Value[value_option])::Properties
42
+ else
43
+ Value::Properties.new(options).freeze
44
+ end
45
+ end
46
+
47
+ def freeze
48
+ @contract = spec.any? { |_, properties| properties.contract? }
49
+
50
+ spec.freeze
51
+
52
+ super
53
+ end
54
+
55
+ def contract?
56
+ contract
57
+ end
58
+
59
+ def map(input)
60
+ spec.each_with_object({}) do |(name, properties), output|
61
+ output[name] = properties.map(input[name])
62
+ end
63
+ end
64
+ end
65
+
66
+ class Evaluator
67
+ # :nodoc:
68
+ attr_reader :properties
69
+
70
+ def initialize
71
+ @properties = Data::Properties.new
72
+ end
73
+
74
+ def attribute(name, **options)
75
+ properties.attribute(name, **options)
76
+ end
77
+
78
+ private
79
+
80
+ def contract
81
+ BCDD::Contract
82
+ end
83
+ end
84
+
85
+ def self.new(&block)
86
+ evaluator = Evaluator.new
87
+ evaluator.instance_eval(&block)
88
+
89
+ klass = ::Class.new(Object)
90
+ klass.const_set(:Properties, evaluator.properties.freeze)
91
+ klass
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+
5
+ module BCDD
6
+ class Value
7
+ class Object
8
+ attr_reader :value, :errors
9
+
10
+ def initialize(value = nil)
11
+ properties = self.class::Properties
12
+ contract = properties.map(value)
13
+
14
+ @errors = contract.errors
15
+ @value = contract.value
16
+ end
17
+ end
18
+
19
+ class Properties
20
+ module Contract
21
+ def self.[](options)
22
+ contract = compose(options)
23
+ required = options.fetch(:required, true)
24
+
25
+ if contract
26
+ required ? contract : (contract | nil)
27
+ elsif required
28
+ Contracts::NotNil
29
+ end
30
+ end
31
+
32
+ def self.compose(options)
33
+ type = ::BCDD::Contract.type(options[:type]) if options.key?(:type)
34
+ contract = ::BCDD::Contract[options[:contract]] if options.key?(:contract)
35
+ respond_to = ::BCDD::Contract.respond_to(Array(options[:respond_to])) if options.key?(:respond_to)
36
+
37
+ [type, contract, respond_to].compact!&.reduce(:&)
38
+ end
39
+ end
40
+
41
+ Default = ->(options) do
42
+ value = options[:default]
43
+
44
+ return value unless value.is_a?(Proc)
45
+ return value if value.lambda? && value.arity.zero?
46
+
47
+ raise ArgumentError, 'Default value must be a lambda with zero arity'
48
+ end
49
+
50
+ Normalize = ->(options) do
51
+ value = options[:normalize]
52
+
53
+ return value if value.is_a?(Proc)
54
+
55
+ raise ArgumentError, 'normalize value must be a lambda'
56
+ end
57
+
58
+ Type = ->(options) do
59
+ type = options[:type]
60
+
61
+ return type if type.is_a?(::Module)
62
+
63
+ raise ArgumentError, 'type must be a Module or a Class'
64
+ end
65
+
66
+ attr_reader :spec, :contract
67
+
68
+ def initialize(options)
69
+ @contract = false
70
+
71
+ contract = Contract[options]
72
+
73
+ @spec = {}
74
+ @spec[:type] = Type[options] if options.key?(:type)
75
+ @spec[:default] = Default[options] if options.key?(:default)
76
+ @spec[:contract] = contract if contract
77
+ @spec[:normalize] = Normalize[options] if options.key?(:normalize)
78
+ end
79
+
80
+ def freeze
81
+ @contract = spec.key?(:contract)
82
+
83
+ spec.freeze
84
+
85
+ super
86
+ end
87
+
88
+ def contract?
89
+ contract
90
+ end
91
+
92
+ def map(value)
93
+ if !value && spec.key?(:default)
94
+ default = spec[:default]
95
+
96
+ value = default.is_a?(::Proc) ? default.call : default
97
+ end
98
+
99
+ type = spec[:type]
100
+
101
+ value = spec[:normalize].call(value) if spec.key?(:normalize) && (!type || type === value)
102
+
103
+ spec.key?(:contract) ? spec[:contract][value] : Contract.null(value)
104
+ end
105
+ end
106
+
107
+ class Registry
108
+ include ::Singleton
109
+
110
+ attr_reader :registry
111
+
112
+ def initialize
113
+ @registry = {}
114
+ end
115
+
116
+ def self.write(options)
117
+ name = options.delete(:name)
118
+
119
+ name.is_a?(Symbol) or raise ArgumentError, "#{name.inspect} must be a Symbol"
120
+
121
+ instance.registry[name] = Value.new(**options)
122
+ end
123
+
124
+ def self.read(name)
125
+ value_object = instance.registry[name]
126
+
127
+ value_object or raise ArgumentError, "#{name.inspect} is not registered"
128
+ end
129
+ end
130
+
131
+ def self.new(**options)
132
+ klass = ::Class.new(Object)
133
+ klass.const_set(:Properties, Properties.new(options).freeze)
134
+ klass
135
+ end
136
+
137
+ def self.[](name)
138
+ Registry.read(name)
139
+ end
140
+ end
141
+
142
+ module Values
143
+ class << self
144
+ private
145
+
146
+ def register(**options)
147
+ Value::Registry.write(options)
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDD
4
+ class Process
5
+ module Output
6
+ # :nodoc:
7
+ class Properties
8
+ attr_reader :success
9
+
10
+ def initialize
11
+ @success = {}
12
+ @failure = {}
13
+ end
14
+
15
+ def success=(spec)
16
+ @success = spec.transform_values(&BCDD::Contract)
17
+ end
18
+
19
+ def failure=(spec)
20
+ @failure = spec.transform_values(&BCDD::Contract)
21
+ end
22
+
23
+ INVALID_INPUT = { invalid_input: ::Hash }.freeze
24
+
25
+ def failure
26
+ INVALID_INPUT.merge(@failure)
27
+ end
28
+ end
29
+
30
+ class Evaluator
31
+ # :nodoc:
32
+ attr_reader :__properties__
33
+
34
+ def initialize
35
+ @__properties__ = Properties.new
36
+ end
37
+
38
+ private
39
+
40
+ def Success(**spec)
41
+ __properties__.success = spec
42
+ end
43
+
44
+ def Failure(**spec)
45
+ __properties__.failure = spec
46
+ end
47
+
48
+ def contract
49
+ ::BCDD::Contract
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module BCDD
4
4
  class Process
5
- VERSION = '0.3.1'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
data/lib/bcdd/process.rb CHANGED
@@ -1,60 +1,59 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bcdd/result'
4
- require 'bcdd/contract'
5
4
 
6
- require_relative 'contracts'
7
- require_relative 'contract/null'
5
+ require_relative 'ext/contract'
6
+ require_relative 'ext/data'
8
7
 
9
8
  require_relative 'process/version'
10
- require_relative 'process/caller'
11
- require_relative 'process/input_spec'
12
- require_relative 'process/output_spec'
9
+ require_relative 'process/output'
13
10
 
14
11
  module BCDD
15
12
  class Process
16
- class << self
17
- attr_reader :__input__, :__input_contract__, :__output__
13
+ module Caller
14
+ def call(**kargs)
15
+ input = self.class::Input.new(**kargs)
18
16
 
19
- def input(&block)
20
- return @__input__ if defined?(@__input__)
17
+ Result.transitions(name: self.class.name) do
18
+ return Failure(:invalid_input, **input.errors) if input.errors.any?
21
19
 
22
- spec = InputSpec.new
23
- spec.instance_eval(&block)
24
- spec.__result__.transform_values!(&:freeze).freeze
25
-
26
- @__input_contract__ = spec.__result__.any? { |_key, value| value.key?(:contract) }
27
- @__input__ = spec.__result__
20
+ super(**input.attributes)
21
+ end
28
22
  end
23
+ end
29
24
 
30
- def output(expectations: true, &block)
31
- @__output__ and raise ArgumentError, 'outputs already defined'
25
+ def self.input(&block)
26
+ return if const_defined?(:Input)
32
27
 
33
- config = { addon: { given: true, continue: true } }
28
+ const_set(:Input, ::BCDD::Data.new(&block))
29
+ end
34
30
 
35
- if expectations
36
- spec = OutputSpec.new
37
- spec.instance_eval(&block)
31
+ RESULT_CONFIG = { addon: { given: true, continue: true }.freeze }.freeze
38
32
 
39
- output = spec.__result__
40
- success = output[:success]
41
- failure = output.fetch(:failure, {}).merge(invalid_input: ::Hash)
33
+ def self.output(expectations: true, &block)
34
+ return if const_defined?(:Result, false)
42
35
 
43
- include(Result::Context::Expectations.mixin(config: config, success: success, failure: failure))
44
- else
45
- include(Result::Context.mixin(config: config))
46
- end
36
+ if expectations
37
+ evaluator = Output::Evaluator.new
38
+ evaluator.instance_eval(&block)
47
39
 
48
- @__output__ = { expectations: expectations }.freeze
49
- end
40
+ success = evaluator.__properties__.success
41
+ failure = evaluator.__properties__.failure
50
42
 
51
- def inherited(subclass)
52
- subclass.prepend(Caller)
43
+ include(Result::Context::Expectations.mixin(config: RESULT_CONFIG, success: success, failure: failure))
44
+ else
45
+ include(Result::Context.mixin(config: RESULT_CONFIG))
53
46
  end
47
+ end
54
48
 
55
- def call(**input)
56
- new.call(**input)
57
- end
49
+ def self.inherited(subclass)
50
+ subclass.prepend(Caller)
58
51
  end
52
+
53
+ def self.call(**input)
54
+ new.call(**input)
55
+ end
56
+
57
+ private_constant :Caller, :RESULT_CONFIG
59
58
  end
60
59
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bcdd-process
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.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: 2024-02-02 00:00:00.000000000 Z
11
+ date: 2024-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcdd-contract
@@ -68,15 +68,18 @@ files:
68
68
  - examples/business_processes/lib/bcdd/contracts.rb
69
69
  - examples/business_processes/lib/bcdd/result/rollback_on_failure.rb
70
70
  - examples/business_processes/lib/bcdd/result/transitions_record.rb
71
+ - examples/business_processes/lib/bcdd/values/uuid.rb
71
72
  - examples/business_processes/lib/runtime_breaker.rb
72
73
  - examples/business_processes/lib/transitions_listener/stdout.rb
73
74
  - lib/bcdd-process.rb
74
- - lib/bcdd/contract/null.rb
75
- - lib/bcdd/contracts.rb
75
+ - lib/bcdd/ext/contract.rb
76
+ - lib/bcdd/ext/contract/null.rb
77
+ - lib/bcdd/ext/contract/respond_to.rb
78
+ - lib/bcdd/ext/contracts.rb
79
+ - lib/bcdd/ext/data.rb
80
+ - lib/bcdd/ext/value.rb
76
81
  - lib/bcdd/process.rb
77
- - lib/bcdd/process/caller.rb
78
- - lib/bcdd/process/input_spec.rb
79
- - lib/bcdd/process/output_spec.rb
82
+ - lib/bcdd/process/output.rb
80
83
  - lib/bcdd/process/version.rb
81
84
  - sig/bcdd/process.rbs
82
85
  homepage: https://github.com/b-cdd/process
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BCDD
4
- class Process
5
- module Caller
6
- PrepareInputs = ->(spec, input) do
7
- spec.each_with_object({}) do |(name, options), result|
8
- value = input.fetch(name) do
9
- if options.key?(:default)
10
- default = options[:default]
11
-
12
- default.is_a?(::Proc) ? default.call : default
13
- end
14
- end
15
-
16
- value = options[:normalize].call(value) if options.key?(:normalize)
17
-
18
- result[name] = options.key?(:contract) ? options[:contract][value] : Contract.null(value)
19
- end
20
- end
21
-
22
- def call(**inputs)
23
- prepared_input = PrepareInputs[self.class.__input__, inputs]
24
-
25
- Result.transitions(name: self.class.name) do
26
- if self.class.__input_contract__
27
- invalid_input = prepared_input.select { |_key, value| value.invalid? }
28
-
29
- return Failure(:invalid_input, **invalid_input.transform_values(&:errors)) unless invalid_input.empty?
30
- end
31
-
32
- super(**prepared_input.transform_values!(&:value))
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BCDD
4
- class Process
5
- class InputSpec
6
- module MapContract
7
- def self.[](options)
8
- required = options.fetch(:required, true)
9
-
10
- if options.key?(:contract) || options.key?(:type) || options.key?(:validate)
11
- resolve(options).then { required ? _1 : (_1 | nil) }
12
- elsif required
13
- Contracts::NotNil
14
- end
15
- end
16
-
17
- def self.resolve(options)
18
- type = ::BCDD::Contract.unit(options[:type]) if options.key?(:type)
19
- contract = ::BCDD::Contract[options[:contract]] if options.key?(:contract)
20
-
21
- type && contract ? (type & contract) : type || contract
22
- end
23
- end
24
-
25
- MapDefault = ->(options) do
26
- value = options[:default]
27
-
28
- return value unless value.is_a?(Proc)
29
- return value if value.lambda? && value.arity.zero?
30
-
31
- raise ArgumentError, 'Default value must be a lambda with zero arity'
32
- end
33
-
34
- MapNormalize = ->(options) do
35
- value = options[:normalize]
36
-
37
- return value if value.is_a?(Proc)
38
-
39
- raise ArgumentError, 'normalize value must be a lambda'
40
- end
41
-
42
- # :nodoc:
43
- attr_reader :__result__
44
-
45
- def initialize
46
- @__result__ = {}
47
- end
48
-
49
- def attribute(name, **options)
50
- name.is_a?(Symbol) or raise ArgumentError, "#{name.inspect} must be a Symbol"
51
-
52
- spec = {}
53
- spec[:default] = MapDefault[options] if options.key?(:default)
54
- spec[:normalize] = MapNormalize[options] if options.key?(:normalize)
55
-
56
- MapContract[options].then { spec[:contract] = _1 if _1 }
57
-
58
- __result__[name] = spec
59
- end
60
-
61
- def contract
62
- BCDD::Contract
63
- end
64
- end
65
- end
66
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BCDD
4
- class Process
5
- class OutputSpec
6
- def initialize
7
- @success = {}
8
- @failure = {}
9
- end
10
-
11
- def Success(**spec)
12
- @success = spec.transform_values(&BCDD::Contract)
13
- end
14
-
15
- def Failure(**spec)
16
- @failure = spec.transform_values(&BCDD::Contract)
17
- end
18
-
19
- # :nodoc:
20
- def __result__
21
- { success: @success, failure: @failure }
22
- end
23
-
24
- private
25
-
26
- def contract
27
- ::BCDD::Contract
28
- end
29
- end
30
- end
31
- end
File without changes
File without changes