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 Evidences []syntax.ATURI
42 CreatedAt time.Time
43}
44
45func (v Vouch) IsVouch() bool {
46 return v.Kind == VouchKindVouch
47}
48
49func (v Vouch) IsDenounce() bool {
50 return v.Kind == VouchKindDenounce
51}
52
53type VouchStats struct {
54 Vouches int64
55 Denounces int64
56}
57
58type VouchRelationship struct {
59 ViewerDid syntax.DID
60 SubjectDid syntax.DID
61
62 NetworkVouches []Vouch
63}
64
65func (vr *VouchRelationship) IsDirectVouch() bool {
66 for _, v := range vr.NetworkVouches {
67 if v.Did == vr.ViewerDid && v.SubjectDid == vr.SubjectDid && v.Kind == VouchKindVouch {
68 return true
69 }
70 }
71 return false
72}
73
74func (vr *VouchRelationship) IsDirectDenounce() bool {
75 for _, v := range vr.NetworkVouches {
76 if v.Did == vr.ViewerDid && v.SubjectDid == vr.SubjectDid && v.Kind == VouchKindDenounce {
77 return true
78 }
79 }
80 return false
81}
82
83func (vr *VouchRelationship) IndirectVouches() []Vouch {
84 var indirectVouches []Vouch
85 for _, v := range vr.NetworkVouches {
86 if v.Did != vr.ViewerDid {
87 indirectVouches = append(indirectVouches, v)
88 }
89 }
90 return indirectVouches
91}
92
93func (vr *VouchRelationship) IsEmpty() bool {
94 return len(vr.NetworkVouches) == 0
95}
96
97func (vr *VouchRelationship) GetDirectVouch() *Vouch {
98 for _, v := range vr.NetworkVouches {
99 if v.Did == vr.ViewerDid && v.SubjectDid == vr.SubjectDid {
100 return &v
101 }
102 }
103 return nil
104}
105
106func (vr *VouchRelationship) IsIndirectVouch() bool {
107 if vr.IsDirectVouch() || vr.IsDirectDenounce() {
108 return false
109 }
110 for _, v := range vr.NetworkVouches {
111 if v.Did != vr.ViewerDid && v.Kind == VouchKindVouch {
112 return true
113 }
114 }
115 return false
116}
117
118func (vr *VouchRelationship) IsIndirectDenounce() bool {
119 if vr.IsDirectVouch() || vr.IsDirectDenounce() {
120 return false
121 }
122 for _, v := range vr.NetworkVouches {
123 if v.Did != vr.ViewerDid && v.Kind == VouchKindDenounce {
124 return true
125 }
126 }
127 return false
128}
129
130func (vr *VouchRelationship) IsMixed() bool {
131 if vr.IsDirectVouch() || vr.IsDirectDenounce() {
132 return false
133 }
134 hasVouch := false
135 hasDenounce := false
136 for _, v := range vr.NetworkVouches {
137 if v.Did != vr.ViewerDid {
138 switch v.Kind {
139 case VouchKindVouch:
140 hasVouch = true
141 case VouchKindDenounce:
142 hasDenounce = true
143 }
144 }
145 }
146 return hasVouch && hasDenounce
147}
148
149func (vr *VouchRelationship) VouchStrength() int {
150 count := 0
151 for _, v := range vr.NetworkVouches {
152 if v.Did != vr.ViewerDid && v.Kind == VouchKindVouch {
153 count++
154 }
155 }
156 return count
157}
158
159func (vr *VouchRelationship) DenounceStrength() int {
160 count := 0
161 for _, v := range vr.NetworkVouches {
162 if v.Did != vr.ViewerDid && v.Kind == VouchKindDenounce {
163 count++
164 }
165 }
166 return count
167}