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