1package bug
2
3import (
4 "fmt"
5
6 "github.com/MichaelMure/git-bug/entity"
7 "github.com/MichaelMure/git-bug/entity/dag"
8 "github.com/MichaelMure/git-bug/identity"
9 "github.com/MichaelMure/git-bug/util/timestamp"
10
11 "github.com/MichaelMure/git-bug/util/text"
12)
13
14var _ Operation = &SetTitleOperation{}
15
16// SetTitleOperation will change the title of a bug
17type SetTitleOperation struct {
18 dag.OpBase
19 Title string `json:"title"`
20 Was string `json:"was"`
21}
22
23func (op *SetTitleOperation) Id() entity.Id {
24 return dag.IdOperation(op, &op.OpBase)
25}
26
27func (op *SetTitleOperation) Apply(snapshot *Snapshot) {
28 snapshot.Title = op.Title
29 snapshot.addActor(op.Author())
30
31 item := &SetTitleTimelineItem{
32 id: op.Id(),
33 Author: op.Author(),
34 UnixTime: timestamp.Timestamp(op.UnixTime),
35 Title: op.Title,
36 Was: op.Was,
37 }
38
39 snapshot.Timeline = append(snapshot.Timeline, item)
40}
41
42func (op *SetTitleOperation) Validate() error {
43 if err := op.OpBase.Validate(op, SetTitleOp); err != nil {
44 return err
45 }
46
47 if text.Empty(op.Title) {
48 return fmt.Errorf("title is empty")
49 }
50
51 if !text.SafeOneLine(op.Title) {
52 return fmt.Errorf("title has unsafe characters")
53 }
54
55 if !text.SafeOneLine(op.Was) {
56 return fmt.Errorf("previous title has unsafe characters")
57 }
58
59 return nil
60}
61
62func NewSetTitleOp(author identity.Interface, unixTime int64, title string, was string) *SetTitleOperation {
63 return &SetTitleOperation{
64 OpBase: dag.NewOpBase(SetTitleOp, author, unixTime),
65 Title: title,
66 Was: was,
67 }
68}
69
70type SetTitleTimelineItem struct {
71 id entity.Id
72 Author identity.Interface
73 UnixTime timestamp.Timestamp
74 Title string
75 Was string
76}
77
78func (s SetTitleTimelineItem) Id() entity.Id {
79 return s.id
80}
81
82// IsAuthored is a sign post method for gqlgen
83func (s *SetTitleTimelineItem) IsAuthored() {}
84
85// Convenience function to apply the operation
86func SetTitle(b Interface, author identity.Interface, unixTime int64, title string) (*SetTitleOperation, error) {
87 var lastTitleOp *SetTitleOperation
88 for _, op := range b.Operations() {
89 switch op := op.(type) {
90 case *SetTitleOperation:
91 lastTitleOp = op
92 }
93 }
94
95 var was string
96 if lastTitleOp != nil {
97 was = lastTitleOp.Title
98 } else {
99 was = b.FirstOp().(*CreateOperation).Title
100 }
101
102 setTitleOp := NewSetTitleOp(author, unixTime, title, was)
103
104 if err := setTitleOp.Validate(); err != nil {
105 return nil, err
106 }
107
108 b.Append(setTitleOp)
109 return setTitleOp, nil
110}