-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathcourse.go
More file actions
149 lines (118 loc) · 3.13 KB
/
course.go
File metadata and controls
149 lines (118 loc) · 3.13 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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package mooc
import (
"context"
"errors"
"fmt"
"github.com/CodelyTV/go-hexagonal_http_api-course/08-03-debugging/kit/event"
"github.com/google/uuid"
)
var ErrInvalidCourseID = errors.New("invalid Course ID")
// CourseID represents the course unique identifier.
type CourseID struct {
value string
}
// NewCourseID instantiate the VO for CourseID
func NewCourseID(value string) (CourseID, error) {
v, err := uuid.Parse(value)
if err != nil {
return CourseID{}, fmt.Errorf("%w: %s", ErrInvalidCourseID, value)
}
return CourseID{
value: v.String(),
}, nil
}
// String type converts the CourseID into string.
func (id CourseID) String() string {
return id.value
}
var ErrEmptyCourseName = errors.New("the field Course Name can not be empty")
// CourseName represents the course name.
type CourseName struct {
value string
}
// NewCourseName instantiate VO for CourseName
func NewCourseName(value string) (CourseName, error) {
if value == "" {
return CourseName{}, ErrEmptyCourseName
}
return CourseName{
value: value,
}, nil
}
// String type converts the CourseName into string.
func (name CourseName) String() string {
return name.value
}
var ErrEmptyDuration = errors.New("the field Duration can not be empty")
// CourseDuration represents the course duration.
type CourseDuration struct {
value string
}
func NewCourseDuration(value string) (CourseDuration, error) {
if value == "" {
return CourseDuration{}, ErrEmptyDuration
}
return CourseDuration{
value: value,
}, nil
}
// String type converts the CourseDuration into string.
func (duration CourseDuration) String() string {
return duration.value
}
// Course is the data structure that represents a course.
type Course struct {
id CourseID
name CourseName
duration CourseDuration
events []event.Event
}
// CourseRepository defines the expected behaviour from a course storage.
type CourseRepository interface {
Save(ctx context.Context, course Course) error
}
//go:generate mockery --case=snake --outpkg=storagemocks --output=platform/storage/storagemocks --name=CourseRepository
// NewCourse creates a new course.
func NewCourse(id, name, duration string) (Course, error) {
idVO, err := NewCourseID(id)
if err != nil {
return Course{}, err
}
nameVO, err := NewCourseName(name)
if err != nil {
return Course{}, err
}
durationVO, err := NewCourseDuration(duration)
if err != nil {
return Course{}, err
}
course := Course{
id: idVO,
name: nameVO,
duration: durationVO,
}
course.Record(NewCourseCreatedEvent(idVO.String(), nameVO.String(), durationVO.String()))
return course, nil
}
// ID returns the course unique identifier.
func (c Course) ID() CourseID {
return c.id
}
// Name returns the course name.
func (c Course) Name() CourseName {
return c.name
}
// Duration returns the course duration.
func (c Course) Duration() CourseDuration {
return c.duration
}
// Record records a new domain event.
func (c *Course) Record(evt event.Event) {
c.events = append(c.events, evt)
}
// PullEvents returns all the recorded domain events.
func (c *Course) PullEvents() []event.Event {
evt := c.events
c.events = []event.Event{}
return evt
}