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