-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathusecase.go
More file actions
executable file
·68 lines (59 loc) · 2.09 KB
/
usecase.go
File metadata and controls
executable file
·68 lines (59 loc) · 2.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package cleango
import (
"context"
"fmt"
)
// UseCase defines the core of the computational space. It only works on input and returns an Answer to the presenter
// via dependency inject. Notice this method does not return a value. It doesn't even return an error. Any errors
// encountered during calculation should be sent to the presenter via the Present method.
type UseCase[Input any, Answer any] interface {
Execute(Input, Presenter[Answer])
}
// Same idea as the regular use case but context aware.
type UseCaseWithContext[Input any, Answer any] interface {
Execute(context.Context, Input, PresenterWithContext[Answer])
}
// WrappingUseCase a use case that holds another use case in order to make sure presenter is always caused with
// an error in case of a panic.
type WrappingUseCase[Input any, Answer any] struct {
Implementation UseCase[Input, Answer]
}
var RecoveryMessage = "wrapper recovery"
func (w *WrappingUseCase[Input, Answer]) Execute(input Input, p Presenter[Answer]) {
defer func() {
if r := recover(); r != nil {
var blank Answer
p.Present(struct {
Answer Answer
Err error
}{
Answer: blank,
Err: &DomainError{
Kind: System,
Message: RecoveryMessage,
UnderlyingCause: fmt.Errorf("%s", r),
Issues: nil,
},
})
}
}()
w.Implementation.Execute(input, p)
}
// FunctionalUseCase is a generic implementation of UseCase that takes a function to act as the Execute method.
type FunctionalUseCase[Input any, Answer any] struct {
ExecuteFunc func(Input) (Answer, error)
}
// Execute runs the provided function and passes its result to the presenter.
func (f *FunctionalUseCase[Input, Answer]) Execute(input Input, p Presenter[Answer]) {
answer, err := f.ExecuteFunc(input)
p.Present(Output[Answer]{
Answer: answer,
Err: err,
})
}
// NewFunctionalUseCase creates a new FunctionalUseCase with the provided function.
func NewFunctionalUseCase[Input any, Answer any](executeFunc func(Input) (Answer, error)) *FunctionalUseCase[Input, Answer] {
return &FunctionalUseCase[Input, Answer]{
ExecuteFunc: executeFunc,
}
}