op_set_status.go

  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}