governedset.gno
2.58 Kb · 103 lines
1package kourt
2import (
3 "strconv"
4 "strings"
5 "chain"
6)
7const (
8 setMark = "\U00013080"
9 shutMark = "\U0001307C"
10 setPrefix = setMark + " "
11 shutPrefix = shutMark + " "
12)
13func parseSetTitle(title string) (name string, shown bool, ok bool) {
14 pre := ""
15 switch {
16 case strings.HasPrefix(title, setPrefix):
17 pre, shown = setPrefix, true
18 case strings.HasPrefix(title, shutPrefix):
19 pre, shown = shutPrefix, false
20 default:
21 return "", false, false
22 }
23 name = title[len(pre):]
24 if !folderTextOK(name, "") {
25 return "", false, false
26 }
27 return name, shown, true
28}
29func IsSetClaim(courtSlug string, claimID uint64) bool {
30 cs := mustClaim(mustCourt(courtSlug), claimID)
31 _, _, ok := parseSetTitle(cs.title)
32 return ok
33}
34func ClaimSet(courtSlug string, claimID uint64) uint64 {
35 c := mustCourt(courtSlug)
36 if c.mod == nil || c.mod.folders == nil {
37 return 0
38 }
39 var out uint64
40 c.mod.folders.Iterate("", "", func(_ string, v any) bool {
41 f := v.(*folder)
42 if f.bornOf == claimID {
43 out = f.id
44 return true
45 }
46 return false
47 })
48 return out
49}
50func SetBornOf(courtSlug string, folderID uint64) uint64 {
51 c := mustCourt(courtSlug)
52 if c.mod == nil {
53 return 0
54 }
55 return c.mod.mustFolder(folderID).bornOf
56}
57func New(cur realm, courtSlug string, claimID uint64) uint64 {
58 if !cur.IsCurrent() {
59 panic(errStaleRealm)
60 }
61 c := mustCourt(courtSlug)
62 cs := mustClaim(c, claimID)
63 name, shown, ok := parseSetTitle(cs.title)
64 if !ok {
65 panic("kourtv2: this claim's title is not a set heading")
66 }
67 if cs.verdictAt == 0 || cs.provClose {
68 panic("kourtv2: no final verdict")
69 }
70 if cs.provisional != 0 {
71 panic("kourtv2: the verdict was not YES")
72 }
73 if prior := ClaimSet(courtSlug, claimID); prior != 0 {
74 panic("kourtv2: this claim already carries set " + strconv.FormatUint(prior, 10))
75 }
76 cm := ensureMod(c)
77 if folderNameTaken(cm, name) {
78 panic("kourtv2: a folder by that name already exists")
79 }
80 var parent uint64
81 if in := ClaimFolders(courtSlug, claimID); len(in) == 1 {
82 parent = in[0]
83 } else if len(in) > 1 {
84 panic("kourtv2: this claim is filed in more than one set; a born set needs exactly one parent")
85 }
86 if parent != 0 && cm.mustFolder(parent).retired {
87 panic("kourtv2: the set this claim is filed in has been retired")
88 }
89 fid := newFolderCore(cm, name, "", parent)
90 f := cm.mustFolder(fid)
91 f.bornOf = claimID
92 f.focusByDefault = shown
93 emitModAct(c.id, claimID, "new", cs.author)
94 chain.Emit("SetAffirmed",
95 "court", c.id,
96 "claim", strconv.FormatUint(claimID, 10),
97 "folder", strconv.FormatUint(fid, 10),
98 "parent", strconv.FormatUint(parent, 10),
99 "name", name,
100 "height", eventHeight(),
101 )
102 return fid
103}