forked from
tangled.org/core
Monorepo for Tangled
3.3 kB
113 lines
1package models
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/bluesky-social/indigo/atproto/syntax"
8 "github.com/samber/lo"
9 "tangled.org/core/api/tangled"
10)
11
12type StateValue string
13
14const (
15 StateOpen StateValue = "open"
16 StateClosed StateValue = "closed"
17 StateMerged StateValue = "merged"
18)
19
20type StateRecord struct {
21 Did string
22 Rkey string
23 Subject syntax.ATURI
24 Value StateValue
25 SortMicros int64
26}
27
28func sortMicros(createdAt, rkey string) int64 {
29 if t, err := syntax.ParseDatetimeTime(createdAt); err == nil {
30 return t.UnixMicro()
31 }
32 if tid, err := syntax.ParseTID(rkey); err == nil {
33 return tid.Time().UnixMicro()
34 }
35 return 0
36}
37
38func newStateRecord(did, rkey, subjectUri, createdAt string, value StateValue) (StateRecord, error) {
39 subject, err := syntax.ParseATURI(subjectUri)
40 if err != nil {
41 return StateRecord{}, fmt.Errorf("invalid subject uri: %w", err)
42 }
43 return StateRecord{
44 Did: did,
45 Rkey: rkey,
46 Subject: subject,
47 Value: value,
48 SortMicros: sortMicros(createdAt, rkey),
49 }, nil
50}
51
52func IssueStateFromRecord(did, rkey string, record tangled.RepoIssueState) (StateRecord, error) {
53 switch record.State {
54 case tangled.RepoIssueStateOpen:
55 return newStateRecord(did, rkey, record.Issue, record.CreatedAt, StateOpen)
56 case tangled.RepoIssueStateClosed:
57 return newStateRecord(did, rkey, record.Issue, record.CreatedAt, StateClosed)
58 default:
59 return StateRecord{}, fmt.Errorf("unknown issue state variant: %q", record.State)
60 }
61}
62
63func PullStatusFromRecord(did, rkey string, record tangled.RepoPullStatus) (StateRecord, error) {
64 switch record.Status {
65 case tangled.RepoPullStatusOpen:
66 return newStateRecord(did, rkey, record.Pull, record.CreatedAt, StateOpen)
67 case tangled.RepoPullStatusClosed:
68 return newStateRecord(did, rkey, record.Pull, record.CreatedAt, StateClosed)
69 case tangled.RepoPullStatusMerged:
70 return newStateRecord(did, rkey, record.Pull, record.CreatedAt, StateMerged)
71 default:
72 return StateRecord{}, fmt.Errorf("unknown pull status variant: %q", record.Status)
73 }
74}
75
76func AsIssueStateRecord(subject syntax.ATURI, value StateValue, createdAt time.Time) (tangled.RepoIssueState, error) {
77 var variant string
78 switch value {
79 case StateOpen:
80 variant = tangled.RepoIssueStateOpen
81 case StateClosed:
82 variant = tangled.RepoIssueStateClosed
83 default:
84 return tangled.RepoIssueState{}, fmt.Errorf("invalid issue state: %q", value)
85 }
86 return tangled.RepoIssueState{
87 Issue: subject.String(),
88 State: variant,
89 CreatedAt: createdAt.UTC().Format(syntax.AtprotoDatetimeLayout),
90 }, nil
91}
92
93func AsPullStatusRecords(subjects []syntax.ATURI, value StateValue, createdAt time.Time) ([]tangled.RepoPullStatus, error) {
94 var variant string
95 switch value {
96 case StateOpen:
97 variant = tangled.RepoPullStatusOpen
98 case StateClosed:
99 variant = tangled.RepoPullStatusClosed
100 case StateMerged:
101 variant = tangled.RepoPullStatusMerged
102 default:
103 return nil, fmt.Errorf("invalid pull status: %q", value)
104 }
105 created := createdAt.UTC().Format(syntax.AtprotoDatetimeLayout)
106 return lo.Map(subjects, func(subject syntax.ATURI, _ int) tangled.RepoPullStatus {
107 return tangled.RepoPullStatus{
108 Pull: subject.String(),
109 Status: variant,
110 CreatedAt: created,
111 }
112 }), nil
113}