u-case 1.1.0 → 2.0.0.pre
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/Gemfile +1 -0
- data/README.md +16 -16
- data/lib/micro/case/error.rb +3 -3
- data/lib/micro/case/flow/reducer.rb +9 -33
- data/lib/micro/case/flow.rb +5 -12
- data/lib/micro/case/result.rb +4 -4
- data/lib/micro/case/safe/flow.rb +48 -0
- data/lib/micro/case/safe.rb +3 -2
- data/lib/micro/case/strict.rb +3 -3
- data/lib/micro/case/version.rb +2 -2
- data/lib/micro/case/with_validation.rb +5 -7
- data/lib/micro/case.rb +89 -8
- data/u-case.gemspec +2 -2
- metadata +7 -7
- data/lib/micro/case/base.rb +0 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 806dbd5686331f1a76c1dd8d972172cd3754a7cb4aa53fb74f3a9eb8497d0afd
|
4
|
+
data.tar.gz: 5ea6769e14d5f5fdb32bc0a43895ab2a4635bcdd2ad25bbe5f1240fff90abe71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad2316a9def217796b9aa9f8f6f49a95aa7a49fec96153ff90cec72247c8e7900ce790a6af3c7d4d6a14e39af05a864d6d9d2c967f2ebb3f9fb6f6b6dd0dd326
|
7
|
+
data.tar.gz: a63bf37a2d60d8f177a7105224a1e1d1d77120447c2c31ae1da70e960429e9f8ff30d41f6c803c07c74205b311c90824de8360735f8721e5bc19f3b77fbfa5e3
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -6,13 +6,13 @@
|
|
6
6
|
μ-case (Micro::Case)
|
7
7
|
==========================
|
8
8
|
|
9
|
-
Create simple and powerful use cases as objects
|
9
|
+
Create simple and powerful use cases as objects.
|
10
10
|
|
11
11
|
The main goals of this project are:
|
12
12
|
1. Be simple to use and easy to learn (input **>>** process/transform **>>** output).
|
13
|
-
2.
|
13
|
+
2. Promove referential transparency (transforming instead of modifying) and data integrity.
|
14
14
|
3. No callbacks (before, after, around...).
|
15
|
-
4.
|
15
|
+
4. Solve complex business logic using a composition of use cases.
|
16
16
|
|
17
17
|
## Table of Contents <!-- omit in toc -->
|
18
18
|
- [μ-case (Micro::Case)](#%ce%bc-case-microcase)
|
@@ -64,7 +64,7 @@ Or install it yourself as:
|
|
64
64
|
### How to define a use case?
|
65
65
|
|
66
66
|
```ruby
|
67
|
-
class Multiply < Micro::Case
|
67
|
+
class Multiply < Micro::Case
|
68
68
|
# 1. Define its input as attributes
|
69
69
|
attributes :a, :b
|
70
70
|
|
@@ -108,7 +108,7 @@ result.value # 6
|
|
108
108
|
|
109
109
|
# Note:
|
110
110
|
# ----
|
111
|
-
# The result of a Micro::Case
|
111
|
+
# The result of a Micro::Case.call
|
112
112
|
# is an instance of Micro::Case::Result
|
113
113
|
```
|
114
114
|
|
@@ -133,7 +133,7 @@ Every result has a type and these are the defaults:
|
|
133
133
|
- `:error`/`:exception` when failures
|
134
134
|
|
135
135
|
```ruby
|
136
|
-
class Divide < Micro::Case
|
136
|
+
class Divide < Micro::Case
|
137
137
|
attributes :a, :b
|
138
138
|
|
139
139
|
def call!
|
@@ -187,7 +187,7 @@ err_result.use_case # #<Divide:0x0000 @__attributes={"a"=>2, "b"=>0}, @a=2, @b=0
|
|
187
187
|
Answer: Use a symbol as the argument of `Success()`, `Failure()` methods and declare a block to set their values.
|
188
188
|
|
189
189
|
```ruby
|
190
|
-
class Multiply < Micro::Case
|
190
|
+
class Multiply < Micro::Case
|
191
191
|
attributes :a, :b
|
192
192
|
|
193
193
|
def call!
|
@@ -223,7 +223,7 @@ bad_result.failure? # true
|
|
223
223
|
Answer: Yes, it is. But only for failure results!
|
224
224
|
|
225
225
|
```ruby
|
226
|
-
class Multiply < Micro::Case
|
226
|
+
class Multiply < Micro::Case
|
227
227
|
attributes :a, :b
|
228
228
|
|
229
229
|
def call!
|
@@ -255,7 +255,7 @@ As mentioned earlier, the `Micro::Case::Result` has two methods to improve the f
|
|
255
255
|
The examples below show how to use them:
|
256
256
|
|
257
257
|
```ruby
|
258
|
-
class Double < Micro::Case
|
258
|
+
class Double < Micro::Case
|
259
259
|
attributes :number
|
260
260
|
|
261
261
|
def call!
|
@@ -307,7 +307,7 @@ Double
|
|
307
307
|
Answer: The hook will be triggered if it matches the result type.
|
308
308
|
|
309
309
|
```ruby
|
310
|
-
class Double < Micro::Case
|
310
|
+
class Double < Micro::Case
|
311
311
|
attributes :number
|
312
312
|
|
313
313
|
def call!
|
@@ -341,7 +341,7 @@ In this case, this will be is a **flow**, because the idea is to use/reuse use c
|
|
341
341
|
|
342
342
|
```ruby
|
343
343
|
module Steps
|
344
|
-
class ConvertToNumbers < Micro::Case
|
344
|
+
class ConvertToNumbers < Micro::Case
|
345
345
|
attribute :numbers
|
346
346
|
|
347
347
|
def call!
|
@@ -440,7 +440,7 @@ Answer: Yes, it is.
|
|
440
440
|
|
441
441
|
```ruby
|
442
442
|
module Steps
|
443
|
-
class ConvertToNumbers < Micro::Case
|
443
|
+
class ConvertToNumbers < Micro::Case
|
444
444
|
attribute :numbers
|
445
445
|
|
446
446
|
def call!
|
@@ -585,7 +585,7 @@ end
|
|
585
585
|
|
586
586
|
module Users
|
587
587
|
class Create
|
588
|
-
include Micro::Case::Flow
|
588
|
+
include Micro::Case::Safe::Flow
|
589
589
|
|
590
590
|
flow ProcessParams, ValidateParams, Persist, SendToCRM
|
591
591
|
end
|
@@ -594,7 +594,7 @@ end
|
|
594
594
|
# or
|
595
595
|
|
596
596
|
module Users
|
597
|
-
Create = Micro::Case::Flow
|
597
|
+
Create = Micro::Case::Safe::Flow[
|
598
598
|
ProcessParams,
|
599
599
|
ValidateParams,
|
600
600
|
Persist,
|
@@ -616,7 +616,7 @@ To do this your application must have the [activemodel >= 3.2](https://rubygems.
|
|
616
616
|
# By default, if your application has the activemodel as a dependency,
|
617
617
|
# any kind of use case can use it to validate their attributes.
|
618
618
|
#
|
619
|
-
class Multiply < Micro::Case
|
619
|
+
class Multiply < Micro::Case
|
620
620
|
attributes :a, :b
|
621
621
|
|
622
622
|
validates :a, :b, presence: true, numericality: true
|
@@ -640,7 +640,7 @@ gem 'u-case', require: 'u-case/with_validation'
|
|
640
640
|
|
641
641
|
# Using this approach, you can rewrite the previous example with less code. e.g:
|
642
642
|
|
643
|
-
class Multiply < Micro::Case
|
643
|
+
class Multiply < Micro::Case
|
644
644
|
attributes :a, :b
|
645
645
|
|
646
646
|
validates :a, :b, presence: true, numericality: true
|
data/lib/micro/case/error.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Micro
|
4
|
-
|
4
|
+
class Case
|
5
5
|
module Error
|
6
6
|
class UnexpectedResult < TypeError
|
7
7
|
MESSAGE = '#call! must return an instance of Micro::Case::Result'.freeze
|
@@ -14,8 +14,8 @@ module Micro
|
|
14
14
|
InvalidResultType = TypeError.new('type must be a Symbol'.freeze)
|
15
15
|
InvalidResultInstance = ArgumentError.new('argument must be an instance of Micro::Case::Result'.freeze)
|
16
16
|
|
17
|
-
InvalidUseCase = TypeError.new('use case must be a kind or an instance of Micro::Case
|
18
|
-
InvalidUseCases = ArgumentError.new('argument must be a collection of `Micro::Case
|
17
|
+
InvalidUseCase = TypeError.new('use case must be a kind or an instance of Micro::Case'.freeze)
|
18
|
+
InvalidUseCases = ArgumentError.new('argument must be a collection of `Micro::Case` classes'.freeze)
|
19
19
|
|
20
20
|
UndefinedFlow = ArgumentError.new("This class hasn't declared its flow. Please, use the `flow()` macro to define one.".freeze)
|
21
21
|
|
@@ -1,21 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Micro
|
4
|
-
|
4
|
+
class Case
|
5
5
|
module Flow
|
6
6
|
class Reducer
|
7
7
|
attr_reader :use_cases
|
8
8
|
|
9
9
|
def self.map_use_cases(arg)
|
10
10
|
return arg.use_cases if arg.is_a?(Reducer)
|
11
|
-
return arg.__flow__.use_cases if arg.is_a?(Class) && arg < Micro::Case::Flow
|
11
|
+
return arg.__flow__.use_cases if arg.is_a?(Class) && arg < ::Micro::Case::Flow
|
12
|
+
|
12
13
|
Array(arg)
|
13
14
|
end
|
14
15
|
|
15
16
|
def self.build(args)
|
16
17
|
use_cases = Array(args).flat_map { |arg| map_use_cases(arg) }
|
17
18
|
|
18
|
-
raise Error::InvalidUseCases if use_cases.any? { |klass| !(klass < ::Micro::Case
|
19
|
+
raise Error::InvalidUseCases if use_cases.any? { |klass| !(klass < ::Micro::Case) }
|
19
20
|
|
20
21
|
new(use_cases)
|
21
22
|
end
|
@@ -27,6 +28,7 @@ module Micro
|
|
27
28
|
def call(arg = {})
|
28
29
|
@use_cases.reduce(initial_result(arg)) do |result, use_case|
|
29
30
|
break result if result.failure?
|
31
|
+
|
30
32
|
use_case.__new__(result, result.value).call
|
31
33
|
end
|
32
34
|
end
|
@@ -48,43 +50,17 @@ module Micro
|
|
48
50
|
def initial_result(arg)
|
49
51
|
return arg.call if arg_to_call?(arg)
|
50
52
|
return arg if arg.is_a?(Micro::Case::Result)
|
51
|
-
|
53
|
+
|
54
|
+
result = ::Micro::Case::Result.new
|
52
55
|
result.__set__(true, arg, :ok, nil)
|
53
56
|
end
|
54
57
|
|
55
58
|
def arg_to_call?(arg)
|
56
|
-
return true if arg.is_a?(Micro::Case
|
57
|
-
return true if arg.is_a?(Class) && (arg < Micro::Case
|
59
|
+
return true if arg.is_a?(::Micro::Case) || arg.is_a?(Reducer)
|
60
|
+
return true if arg.is_a?(Class) && (arg < ::Micro::Case || arg < ::Micro::Case::Flow)
|
58
61
|
return false
|
59
62
|
end
|
60
63
|
end
|
61
|
-
|
62
|
-
class SafeReducer < Reducer
|
63
|
-
def call(arg = {})
|
64
|
-
@use_cases.reduce(initial_result(arg)) do |result, use_case|
|
65
|
-
break result if result.failure?
|
66
|
-
use_case_result(use_case, result)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
alias_method :&, :>>
|
71
|
-
|
72
|
-
def >>(arg)
|
73
|
-
raise NoMethodError, "undefined method `>>' for #{self.inspect}. Please, use the method `&' to avoid this error."
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def use_case_result(use_case, result)
|
79
|
-
begin
|
80
|
-
instance = use_case.__new__(result, result.value)
|
81
|
-
instance.call
|
82
|
-
rescue => exception
|
83
|
-
raise exception if Error::ByWrongUsage.check(exception)
|
84
|
-
result.__set__(false, exception, :exception, instance)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
64
|
end
|
89
65
|
end
|
90
66
|
end
|
data/lib/micro/case/flow.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Micro
|
4
|
-
|
4
|
+
class Case
|
5
5
|
module Flow
|
6
6
|
module ClassMethods
|
7
7
|
def __flow__
|
@@ -20,7 +20,9 @@ module Micro
|
|
20
20
|
CONSTRUCTOR = <<-RUBY
|
21
21
|
def initialize(options)
|
22
22
|
@options = options
|
23
|
+
|
23
24
|
flow = self.class.__flow__
|
25
|
+
|
24
26
|
raise Error::UndefinedFlow unless flow
|
25
27
|
end
|
26
28
|
RUBY
|
@@ -29,7 +31,9 @@ module Micro
|
|
29
31
|
|
30
32
|
def self.included(base)
|
31
33
|
def base.flow_reducer; Reducer; end
|
34
|
+
|
32
35
|
base.extend(ClassMethods)
|
36
|
+
|
33
37
|
base.class_eval(CONSTRUCTOR)
|
34
38
|
end
|
35
39
|
|
@@ -40,17 +44,6 @@ module Micro
|
|
40
44
|
def call
|
41
45
|
self.class.__flow__.call(@options)
|
42
46
|
end
|
43
|
-
|
44
|
-
module Safe
|
45
|
-
def self.included(base)
|
46
|
-
base.send(:include, Micro::Case::Flow)
|
47
|
-
def base.flow_reducer; SafeReducer; end
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.[](*args)
|
51
|
-
SafeReducer.build(args)
|
52
|
-
end
|
53
|
-
end
|
54
47
|
end
|
55
48
|
end
|
56
49
|
end
|
data/lib/micro/case/result.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Micro
|
4
|
-
|
4
|
+
class Case
|
5
5
|
class Result
|
6
6
|
attr_reader :value, :type
|
7
7
|
|
8
8
|
def __set__(is_success, value, type, use_case)
|
9
9
|
raise Error::InvalidResultType unless type.is_a?(Symbol)
|
10
|
-
raise Error::InvalidUseCase if !is_success && !
|
10
|
+
raise Error::InvalidUseCase if !is_success && !is_a_use_case?(use_case)
|
11
11
|
|
12
12
|
@success, @value, @type, @use_case = is_success, value, type, use_case
|
13
13
|
|
@@ -46,8 +46,8 @@ module Micro
|
|
46
46
|
failure? && (arg.nil? || arg == type)
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
50
|
-
(arg.is_a?(Class) && arg < Case
|
49
|
+
def is_a_use_case?(arg)
|
50
|
+
(arg.is_a?(Class) && arg < ::Micro::Case) || arg.is_a?(::Micro::Case)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Micro
|
4
|
+
class Case
|
5
|
+
class Safe
|
6
|
+
module Flow
|
7
|
+
def self.included(base)
|
8
|
+
base.send(:include, ::Micro::Case::Flow)
|
9
|
+
|
10
|
+
def base.flow_reducer; Reducer; end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.[](*args)
|
14
|
+
Reducer.build(args)
|
15
|
+
end
|
16
|
+
|
17
|
+
class Reducer < ::Micro::Case::Flow::Reducer
|
18
|
+
def call(arg = {})
|
19
|
+
@use_cases.reduce(initial_result(arg)) do |result, use_case|
|
20
|
+
break result if result.failure?
|
21
|
+
|
22
|
+
use_case_result(use_case, result)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :&, :>>
|
27
|
+
|
28
|
+
def >>(arg)
|
29
|
+
raise NoMethodError, "undefined method `>>' for #{self.inspect}. Please, use the method `&' to avoid this error."
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def use_case_result(use_case, result)
|
35
|
+
begin
|
36
|
+
instance = use_case.__new__(result, result.value)
|
37
|
+
instance.call
|
38
|
+
rescue => exception
|
39
|
+
raise exception if Error::ByWrongUsage.check(exception)
|
40
|
+
|
41
|
+
result.__set__(false, exception, :exception, instance)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/micro/case/safe.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Micro
|
4
|
-
|
5
|
-
class Safe < Case
|
4
|
+
class Case
|
5
|
+
class Safe < ::Micro::Case
|
6
6
|
def call
|
7
7
|
super
|
8
8
|
rescue => exception
|
9
9
|
raise exception if Error::ByWrongUsage.check(exception)
|
10
|
+
|
10
11
|
Failure(exception)
|
11
12
|
end
|
12
13
|
end
|
data/lib/micro/case/strict.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Micro
|
4
|
-
|
5
|
-
class Strict < Case
|
4
|
+
class Case
|
5
|
+
class Strict < ::Micro::Case
|
6
6
|
include Micro::Attributes::Features::StrictInitialize
|
7
7
|
|
8
|
-
class Safe < Case::Safe
|
8
|
+
class Safe < ::Micro::Case::Safe
|
9
9
|
include Micro::Attributes::Features::StrictInitialize
|
10
10
|
end
|
11
11
|
end
|
data/lib/micro/case/version.rb
CHANGED
@@ -3,15 +3,13 @@
|
|
3
3
|
require 'micro/case'
|
4
4
|
|
5
5
|
module Micro
|
6
|
-
|
7
|
-
|
8
|
-
include Micro::Attributes::Features::ActiveModelValidations
|
6
|
+
class Case
|
7
|
+
include Micro::Attributes::Features::ActiveModelValidations
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
def call
|
10
|
+
return Failure(:validation_error) { { errors: self.errors } } unless valid?
|
12
11
|
|
13
|
-
|
14
|
-
end
|
12
|
+
__call
|
15
13
|
end
|
16
14
|
end
|
17
15
|
end
|
data/lib/micro/case.rb
CHANGED
@@ -1,12 +1,93 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'micro/attributes'
|
4
|
+
# frozen_string_literal: true
|
5
|
+
|
6
|
+
module Micro
|
7
|
+
class Case
|
8
|
+
require 'micro/case/version'
|
9
|
+
require 'micro/case/result'
|
10
|
+
require 'micro/case/error'
|
11
|
+
require 'micro/case/safe'
|
12
|
+
require 'micro/case/strict'
|
13
|
+
require 'micro/case/flow/reducer'
|
14
|
+
require 'micro/case/flow'
|
15
|
+
require 'micro/case/safe/flow'
|
16
|
+
|
17
|
+
include Micro::Attributes.without(:strict_initialize)
|
18
|
+
|
19
|
+
def self.to_proc
|
20
|
+
Proc.new { |arg| call(arg) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.>>(use_case)
|
24
|
+
Flow[self, use_case]
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.&(use_case)
|
28
|
+
Safe::Flow[self, use_case]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.call(options = {})
|
32
|
+
new(options).call
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.__new__(result, arg)
|
36
|
+
instance = new(arg)
|
37
|
+
instance.__set_result__(result)
|
38
|
+
instance
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.__failure_type(arg, type)
|
42
|
+
return type if type != :error
|
43
|
+
|
44
|
+
case arg
|
45
|
+
when Exception then :exception
|
46
|
+
when Symbol then arg
|
47
|
+
else type
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def call!
|
52
|
+
raise NotImplementedError
|
53
|
+
end
|
54
|
+
|
55
|
+
def call
|
56
|
+
__call
|
57
|
+
end
|
58
|
+
|
59
|
+
def __set_result__(result)
|
60
|
+
raise Error::InvalidResultInstance unless result.is_a?(Result)
|
61
|
+
raise Error::ResultIsAlreadyDefined if @__result
|
62
|
+
|
63
|
+
@__result = result
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def __call
|
69
|
+
result = call!
|
70
|
+
|
71
|
+
return result if result.is_a?(Result)
|
72
|
+
|
73
|
+
raise Error::UnexpectedResult.new(self.class)
|
74
|
+
end
|
75
|
+
|
76
|
+
def __get_result__
|
77
|
+
@__result ||= Result.new
|
78
|
+
end
|
79
|
+
|
80
|
+
def Success(arg = :ok)
|
81
|
+
value, type = block_given? ? [yield, arg] : [arg, :ok]
|
82
|
+
|
83
|
+
__get_result__.__set__(true, value, type, nil)
|
84
|
+
end
|
85
|
+
|
86
|
+
def Failure(arg = :error)
|
87
|
+
value = block_given? ? yield : arg
|
88
|
+
type = self.class.__failure_type(value, block_given? ? arg : :error)
|
4
89
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require 'micro/case/safe'
|
10
|
-
require 'micro/case/strict'
|
11
|
-
require 'micro/case/flow/reducer'
|
12
|
-
require 'micro/case/flow'
|
90
|
+
__get_result__.__set__(false, value, type, self)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/u-case.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Rodrigo Serradura']
|
10
10
|
spec.email = ['rodrigo.serradura@gmail.com']
|
11
11
|
|
12
|
-
spec.summary = %q{Create simple and powerful use cases as objects
|
13
|
-
spec.description = %q{Create simple and powerful use cases as objects
|
12
|
+
spec.summary = %q{Create simple and powerful use cases as objects.}
|
13
|
+
spec.description = %q{Create simple and powerful use cases as objects.}
|
14
14
|
spec.homepage = 'https://github.com/serradura/u-case'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: u-case
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre
|
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-
|
11
|
+
date: 2019-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: u-attributes
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10.0'
|
55
|
-
description:
|
55
|
+
description: Create simple and powerful use cases as objects.
|
56
56
|
email:
|
57
57
|
- rodrigo.serradura@gmail.com
|
58
58
|
executables: []
|
@@ -71,12 +71,12 @@ files:
|
|
71
71
|
- bin/console
|
72
72
|
- bin/setup
|
73
73
|
- lib/micro/case.rb
|
74
|
-
- lib/micro/case/base.rb
|
75
74
|
- lib/micro/case/error.rb
|
76
75
|
- lib/micro/case/flow.rb
|
77
76
|
- lib/micro/case/flow/reducer.rb
|
78
77
|
- lib/micro/case/result.rb
|
79
78
|
- lib/micro/case/safe.rb
|
79
|
+
- lib/micro/case/safe/flow.rb
|
80
80
|
- lib/micro/case/strict.rb
|
81
81
|
- lib/micro/case/version.rb
|
82
82
|
- lib/micro/case/with_validation.rb
|
@@ -99,12 +99,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
99
|
version: 2.2.0
|
100
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - "
|
102
|
+
- - ">"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
104
|
+
version: 1.3.1
|
105
105
|
requirements: []
|
106
106
|
rubygems_version: 3.0.3
|
107
107
|
signing_key:
|
108
108
|
specification_version: 4
|
109
|
-
summary:
|
109
|
+
summary: Create simple and powerful use cases as objects.
|
110
110
|
test_files: []
|
data/lib/micro/case/base.rb
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Micro
|
4
|
-
module Case
|
5
|
-
class Base
|
6
|
-
include Micro::Attributes.without(:strict_initialize)
|
7
|
-
|
8
|
-
def self.to_proc
|
9
|
-
Proc.new { |arg| call(arg) }
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.>>(use_case)
|
13
|
-
Flow[self, use_case]
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.&(use_case)
|
17
|
-
Flow::Safe[self, use_case]
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.call(options = {})
|
21
|
-
new(options).call
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.__new__(result, arg)
|
25
|
-
instance = new(arg)
|
26
|
-
instance.__set_result__(result)
|
27
|
-
instance
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.__failure_type(arg, type)
|
31
|
-
return type if type != :error
|
32
|
-
|
33
|
-
case arg
|
34
|
-
when Exception then :exception
|
35
|
-
when Symbol then arg
|
36
|
-
else type
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def call!
|
41
|
-
raise NotImplementedError
|
42
|
-
end
|
43
|
-
|
44
|
-
def call
|
45
|
-
__call
|
46
|
-
end
|
47
|
-
|
48
|
-
def __set_result__(result)
|
49
|
-
raise Error::InvalidResultInstance unless result.is_a?(Result)
|
50
|
-
raise Error::ResultIsAlreadyDefined if @__result
|
51
|
-
@__result = result
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def __call
|
57
|
-
result = call!
|
58
|
-
return result if result.is_a?(Result)
|
59
|
-
raise Error::UnexpectedResult.new(self.class)
|
60
|
-
end
|
61
|
-
|
62
|
-
def __get_result__
|
63
|
-
@__result ||= Result.new
|
64
|
-
end
|
65
|
-
|
66
|
-
def Success(arg = :ok)
|
67
|
-
value, type = block_given? ? [yield, arg] : [arg, :ok]
|
68
|
-
__get_result__.__set__(true, value, type, nil)
|
69
|
-
end
|
70
|
-
|
71
|
-
def Failure(arg = :error)
|
72
|
-
value = block_given? ? yield : arg
|
73
|
-
type = self.class.__failure_type(value, block_given? ? arg : :error)
|
74
|
-
__get_result__.__set__(false, value, type, self)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|