operation.go

 1package board
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6
 7	"github.com/git-bug/git-bug/entities/bug"
 8	"github.com/git-bug/git-bug/entity"
 9	"github.com/git-bug/git-bug/entity/dag"
10)
11
12// OperationType is an operation type identifier
13type OperationType dag.OperationType
14
15const (
16	_ dag.OperationType = iota
17	CreateOp
18	SetMetadataOp
19	SetTitleOp
20	SetDescriptionOp
21	AddItemEntityOp
22	AddItemDraftOp
23	MoveItemOp
24	RemoveItemOp
25
26	// TODO: change columns?
27)
28
29type Operation interface {
30	dag.Operation
31	// Apply the operation to a Snapshot to create the final state
32	Apply(snapshot *Snapshot)
33}
34
35func operationUnmarshaler(raw json.RawMessage, resolvers entity.Resolvers) (dag.Operation, error) {
36	var t struct {
37		OperationType dag.OperationType `json:"type"`
38	}
39
40	if err := json.Unmarshal(raw, &t); err != nil {
41		return nil, err
42	}
43
44	var op dag.Operation
45
46	switch t.OperationType {
47	case CreateOp:
48		op = &CreateOperation{}
49	case SetMetadataOp:
50		op = &dag.SetMetadataOperation[*Snapshot]{}
51	case SetTitleOp:
52		op = &SetTitleOperation{}
53	case SetDescriptionOp:
54		op = &SetDescriptionOperation{}
55	case AddItemDraftOp:
56		op = &AddItemDraftOperation{}
57	case AddItemEntityOp:
58		op = &AddItemEntityOperation{}
59	default:
60		panic(fmt.Sprintf("unknown operation type %v", t.OperationType))
61	}
62
63	err := json.Unmarshal(raw, &op)
64	if err != nil {
65		return nil, err
66	}
67
68	switch op := op.(type) {
69	case *AddItemEntityOperation:
70		switch op.EntityType {
71		case EntityTypeBug:
72			op.entity, err = entity.Resolve[bug.ReadOnly](resolvers, op.EntityId)
73		default:
74			return nil, fmt.Errorf("unknown entity type")
75		}
76		if err != nil {
77			return nil, err
78		}
79	}
80
81	return op, nil
82}