1package bug
2
3import (
4 "encoding/json"
5
6 "github.com/pkg/errors"
7
8 "github.com/MichaelMure/git-bug/entity"
9 "github.com/MichaelMure/git-bug/identity"
10 "github.com/MichaelMure/git-bug/util/timestamp"
11)
12
13var _ Operation = &SetStatusOperation{}
14
15// SetStatusOperation will change the status of a bug
16type SetStatusOperation struct {
17 OpBase
18 Status Status `json:"status"`
19}
20
21func (op *SetStatusOperation) base() *OpBase {
22 return &op.OpBase
23}
24
25func (op *SetStatusOperation) Id() entity.Id {
26 return idOperation(op)
27}
28
29func (op *SetStatusOperation) Apply(snapshot *Snapshot) {
30 snapshot.Status = op.Status
31 snapshot.addActor(op.Author)
32
33 item := &SetStatusTimelineItem{
34 id: op.Id(),
35 Author: op.Author,
36 UnixTime: timestamp.Timestamp(op.UnixTime),
37 Status: op.Status,
38 }
39
40 snapshot.Timeline = append(snapshot.Timeline, item)
41}
42
43func (op *SetStatusOperation) Validate() error {
44 if err := opBaseValidate(op, SetStatusOp); err != nil {
45 return err
46 }
47
48 if err := op.Status.Validate(); err != nil {
49 return errors.Wrap(err, "status")
50 }
51
52 return nil
53}
54
55// UnmarshalJSON is a two step JSON unmarshaling
56// This workaround is necessary to avoid the inner OpBase.MarshalJSON
57// overriding the outer op's MarshalJSON
58func (op *SetStatusOperation) UnmarshalJSON(data []byte) error {
59 // Unmarshal OpBase and the op separately
60
61 base := OpBase{}
62 err := json.Unmarshal(data, &base)
63 if err != nil {
64 return err
65 }
66
67 aux := struct {
68 Status Status `json:"status"`
69 }{}
70
71 err = json.Unmarshal(data, &aux)
72 if err != nil {
73 return err
74 }
75
76 op.OpBase = base
77 op.Status = aux.Status
78
79 return nil
80}
81
82// Sign post method for gqlgen
83func (op *SetStatusOperation) IsAuthored() {}
84
85func NewSetStatusOp(author identity.Interface, unixTime int64, status Status) *SetStatusOperation {
86 return &SetStatusOperation{
87 OpBase: newOpBase(SetStatusOp, author, unixTime),
88 Status: status,
89 }
90}
91
92type SetStatusTimelineItem struct {
93 id entity.Id
94 Author identity.Interface
95 UnixTime timestamp.Timestamp
96 Status Status
97}
98
99func (s SetStatusTimelineItem) Id() entity.Id {
100 return s.id
101}
102
103// Sign post method for gqlgen
104func (s *SetStatusTimelineItem) IsAuthored() {}
105
106// Convenience function to apply the operation
107func Open(b Interface, author identity.Interface, unixTime int64) (*SetStatusOperation, error) {
108 op := NewSetStatusOp(author, unixTime, OpenStatus)
109 if err := op.Validate(); err != nil {
110 return nil, err
111 }
112 b.Append(op)
113 return op, nil
114}
115
116// Convenience function to apply the operation
117func Close(b Interface, author identity.Interface, unixTime int64) (*SetStatusOperation, error) {
118 op := NewSetStatusOp(author, unixTime, ClosedStatus)
119 if err := op.Validate(); err != nil {
120 return nil, err
121 }
122 b.Append(op)
123 return op, nil
124}