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