Monorepo for Tangled
tangled.org
1package models
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/bluesky-social/indigo/atproto/syntax"
8 "github.com/ipfs/go-cid"
9)
10
11type VouchSuggestion struct {
12 Did syntax.DID
13 Reason string
14 VouchRelationship *VouchRelationship
15}
16
17type VouchKind string
18
19const (
20 VouchKindVouch VouchKind = "vouch"
21 VouchKindDenounce VouchKind = "denounce"
22)
23
24func ParseVouchKind(v string) (VouchKind, error) {
25 switch v {
26 case "vouch":
27 return VouchKindVouch, nil
28 case "denounce":
29 return VouchKindDenounce, nil
30 default:
31 return VouchKindVouch, fmt.Errorf("invalid vouch kind: %s", v)
32 }
33}
34
35type Vouch struct {
36 Did syntax.DID
37 SubjectDid syntax.DID
38 Cid cid.Cid
39 Kind VouchKind
40 Reason *string
41 CreatedAt time.Time
42}
43
44func (v Vouch) IsVouch() bool {
45 return v.Kind == VouchKindVouch
46}
47
48func (v Vouch) IsDenounce() bool {
49 return v.Kind == VouchKindDenounce
50}
51
52type VouchStats struct {
53 Vouches int64
54 Denounces int64
55}
56
57type VouchRelationship struct {
58 ViewerDid syntax.DID
59 SubjectDid syntax.DID
60
61 NetworkVouches []Vouch
62}
63
64func (vr *VouchRelationship) IsDirectVouch() bool {
65 for _, v := range vr.NetworkVouches {
66 if v.Did == vr.ViewerDid && v.SubjectDid == vr.SubjectDid && v.Kind == VouchKindVouch {
67 return true
68 }
69 }
70 return false
71}
72
73func (vr *VouchRelationship) IsDirectDenounce() bool {
74 for _, v := range vr.NetworkVouches {
75 if v.Did == vr.ViewerDid && v.SubjectDid == vr.SubjectDid && v.Kind == VouchKindDenounce {
76 return true
77 }
78 }
79 return false
80}
81
82func (vr *VouchRelationship) IndirectVouches() []Vouch {
83 var indirectVouches []Vouch
84 for _, v := range vr.NetworkVouches {
85 if v.Did != vr.ViewerDid {
86 indirectVouches = append(indirectVouches, v)
87 }
88 }
89 return indirectVouches
90}
91
92func (vr *VouchRelationship) IsEmpty() bool {
93 return len(vr.NetworkVouches) == 0
94}
95
96func (vr *VouchRelationship) GetDirectVouch() *Vouch {
97 for _, v := range vr.NetworkVouches {
98 if v.Did == vr.ViewerDid && v.SubjectDid == vr.SubjectDid {
99 return &v
100 }
101 }
102 return nil
103}
104
105func (vr *VouchRelationship) IsIndirectVouch() bool {
106 if vr.IsDirectVouch() || vr.IsDirectDenounce() {
107 return false
108 }
109 for _, v := range vr.NetworkVouches {
110 if v.Did != vr.ViewerDid && v.Kind == VouchKindVouch {
111 return true
112 }
113 }
114 return false
115}
116
117func (vr *VouchRelationship) IsIndirectDenounce() bool {
118 if vr.IsDirectVouch() || vr.IsDirectDenounce() {
119 return false
120 }
121 for _, v := range vr.NetworkVouches {
122 if v.Did != vr.ViewerDid && v.Kind == VouchKindDenounce {
123 return true
124 }
125 }
126 return false
127}
128
129func (vr *VouchRelationship) IsMixed() bool {
130 if vr.IsDirectVouch() || vr.IsDirectDenounce() {
131 return false
132 }
133 hasVouch := false
134 hasDenounce := false
135 for _, v := range vr.NetworkVouches {
136 if v.Did != vr.ViewerDid {
137 switch v.Kind {
138 case VouchKindVouch:
139 hasVouch = true
140 case VouchKindDenounce:
141 hasDenounce = true
142 }
143 }
144 }
145 return hasVouch && hasDenounce
146}
147
148func (vr *VouchRelationship) VouchStrength() int {
149 count := 0
150 for _, v := range vr.NetworkVouches {
151 if v.Did != vr.ViewerDid && v.Kind == VouchKindVouch {
152 count++
153 }
154 }
155 return count
156}
157
158func (vr *VouchRelationship) DenounceStrength() int {
159 count := 0
160 for _, v := range vr.NetworkVouches {
161 if v.Did != vr.ViewerDid && v.Kind == VouchKindDenounce {
162 count++
163 }
164 }
165 return count
166}