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