kind.mx raw
1 package kind
2
3 import (
4 "runtime"
5
6 "git.smesh.lol/nostr/pkg/ints"
7 "git.smesh.lol/nostr/pkg/lol/chk"
8 )
9
10 type Integer interface {
11 ~int32 | ~int8 | ~int16 | ~int64 | ~uint32 | ~uint8 | ~uint16 | ~uint64
12 }
13
14 type K struct {
15 K uint16
16 }
17
18 func New[V Integer](k V) (kp *K) { return &K{uint16(k)} }
19
20 func (k *K) ToInt() (n int32) {
21 if k == nil {
22 return 0
23 }
24 return int32(k.K)
25 }
26
27 func (k *K) ToU16() (n uint16) {
28 if k == nil {
29 return 0
30 }
31 return k.K
32 }
33
34 func (k *K) ToI32() (n int32) {
35 if k == nil {
36 return 0
37 }
38 return int32(k.K)
39 }
40
41 func (k *K) ToU64() (n uint64) {
42 if k == nil {
43 return 0
44 }
45 return uint64(k.K)
46 }
47
48 func (k *K) Name() (buf []byte) { return []byte(GetString(k.K)) }
49
50 func (k *K) Equal(k2 uint16) (ok bool) {
51 if k == nil {
52 return false
53 }
54 return k.K == k2
55 }
56
57 var Privileged []*K
58 var Directory []*K
59
60 var _kindsReady bool
61
62 func initKinds() {
63 if _kindsReady {
64 return
65 }
66 _kindsReady = true
67 // Every allocation here is stored into a package global, so it must
68 // outlive this call. The current frame arena is released on return, so
69 // borrow the root arena for the duration; a global pointing at a
70 // released frame arena is a dangling pointer as soon as the pooled
71 // arena is unmapped.
72 runtime.SovereignSetArena(runtime.RootArena())
73 Map = map[uint16]string{}
74 ProfileMetadata = &K{0}
75 SetMetadata = &K{0}
76 TextNote = &K{1}
77 RecommendRelay = &K{2}
78 FollowList = &K{3}
79 Follows = &K{3}
80 EncryptedDirectMessage = &K{4}
81 EventDeletion = &K{5}
82 Deletion = &K{5}
83 Repost = &K{6}
84 Reaction = &K{7}
85 BadgeAward = &K{8}
86 ChatMessage = &K{9}
87 GroupChatThreadedReply = &K{10}
88 Thread = &K{11}
89 GroupThreadReply = &K{12}
90 Seal = &K{13}
91 DirectMessage = &K{14}
92 FileMessage = &K{15}
93 GenericRepost = &K{16}
94 ReactionToWebsite = &K{17}
95 Picture = &K{20}
96 VideoEventHorizontal = &K{34235}
97 VideoEventVertical = &K{34236}
98 MLSKeyPackage = &K{443}
99 MLSWelcome = &K{444}
100 MLSGroupEvent = &K{445}
101 ChannelCreation = &K{40}
102 ChannelMetadata = &K{41}
103 ChannelMessage = &K{42}
104 ChannelHideMessage = &K{43}
105 ChannelMuteUser = &K{44}
106 Bid = &K{1021}
107 BidConfirmation = &K{1022}
108 OpenTimestamps = &K{1040}
109 GiftWrap = &K{1059}
110 GiftWrapWithKind4 = &K{1060}
111 FileMetadata = &K{1063}
112 LiveChatMessage = &K{1311}
113 BitcoinBlock = &K{1517}
114 LiveStream = &K{1808}
115 ProblemTracker = &K{1971}
116 MemoryHole = &K{1984}
117 Reporting = &K{1984}
118 Label = &K{1985}
119 CommunityPostApproval = &K{4550}
120 JobRequestStart = &K{5000}
121 JobRequestEnd = &K{5999}
122 JobResultStart = &K{6000}
123 JobResultEnd = &K{6999}
124 JobFeedback = &K{7000}
125 ZapGoal = &K{9041}
126 ZapRequest = &K{9734}
127 Zap = &K{9735}
128 Highlights = &K{9802}
129 ReplaceableStart = &K{10000}
130 MuteList = &K{10000}
131 BlockList = &K{10000}
132 PinList = &K{10001}
133 RelayListMetadata = &K{10002}
134 BookmarkList = &K{10003}
135 CommunitiesList = &K{10004}
136 PublicChatsList = &K{10005}
137 BlockedRelaysList = &K{10006}
138 SearchRelaysList = &K{10007}
139 RelayGroupConfig = &K{10008}
140 InterestsList = &K{10015}
141 UserEmojiList = &K{10030}
142 DMRelaysList = &K{10050}
143 KeyPackageRelaysList = &K{10051}
144 FileStorageServerList = &K{10096}
145 JWTBinding = &K{13004}
146 NWCWalletServiceInfo = &K{13194}
147 WalletServiceInfo = &K{13194}
148 ReplaceableEnd = &K{19999}
149 EphemeralStart = &K{20000}
150 LightningPubRPC = &K{21000}
151 ClientAuthentication = &K{22242}
152 NWCWalletRequest = &K{23194}
153 WalletRequest = &K{23194}
154 NWCWalletResponse = &K{23195}
155 WalletResponse = &K{23195}
156 NWCNotification = &K{23196}
157 WalletNotificationNip4 = &K{23196}
158 WalletNotification = &K{23197}
159 NostrConnect = &K{24133}
160 HTTPAuth = &K{27235}
161 EphemeralEnd = &K{29999}
162 ParameterizedReplaceableStart = &K{30000}
163 CategorizedPeopleList = &K{30000}
164 FollowSets = &K{30000}
165 CategorizedBookmarksList = &K{30001}
166 GenericLists = &K{30001}
167 RelaySets = &K{30002}
168 BookmarkSets = &K{30003}
169 CurationSets = &K{30004}
170 ProfileBadges = &K{30008}
171 BadgeDefinition = &K{30009}
172 InterestSets = &K{30015}
173 StallDefinition = &K{30017}
174 ProductDefinition = &K{30018}
175 MarketplaceUIUX = &K{30019}
176 ProductSoldAsAuction = &K{30020}
177 Article = &K{30023}
178 LongFormContent = &K{30023}
179 DraftLongFormContent = &K{30024}
180 EmojiSets = &K{30030}
181 ApplicationSpecificData = &K{30078}
182 LiveEvent = &K{30311}
183 UserStatuses = &K{30315}
184 ClassifiedListing = &K{30402}
185 DraftClassifiedListing = &K{30403}
186 DateBasedCalendarEvent = &K{31922}
187 TimeBasedCalendarEvent = &K{31923}
188 Calendar = &K{31924}
189 CalendarEventRSVP = &K{31925}
190 HandlerRecommendation = &K{31989}
191 HandlerInformation = &K{31990}
192 WaveLakeTrack = &K{32123}
193 CommunityDefinition = &K{34550}
194 ACLEvent = &K{39998}
195 PolicyConfig = &K{12345}
196 ParameterizedReplaceableEnd = &K{40000}
197 Privileged = []*K{
198 EncryptedDirectMessage, GiftWrap, GiftWrapWithKind4, JWTBinding,
199 ApplicationSpecificData, Seal, DirectMessage, FileMessage,
200 MLSKeyPackage, KeyPackageRelaysList,
201 ChannelCreation, ChannelMetadata, ChannelMessage, ChannelHideMessage, ChannelMuteUser,
202 }
203 Directory = []*K{
204 ProfileMetadata, FollowList, EventDeletion, Reporting,
205 RelayListMetadata, MuteList, DMRelaysList,
206 }
207 runtime.SovereignRestoreArena(runtime.RootArena())
208 }
209
210 // Ensure materializes the kind table. Callers that read a package-level
211 // kind pointer directly (kind.NewS(kind.MuteList)) must call this first:
212 // the pointers are nil until initKinds runs, and boxing a nil pointer
213 // crashes whichever index scan dereferences it.
214 func Ensure() { initKinds() }
215
216 func IsChannelKind(k uint16) (ok bool) {
217 initKinds()
218 return k >= ChannelCreation.K && k <= ChannelMuteUser.K
219 }
220
221 func IsDiscoverableChannelKind(k uint16) (ok bool) {
222 initKinds()
223 return k == ChannelCreation.K || k == ChannelMetadata.K
224 }
225
226 func IsPrivileged(k uint16) (ok bool) {
227 initKinds()
228 for i := range Privileged {
229 if k == Privileged[i].K {
230 return true
231 }
232 }
233 return false
234 }
235
236 func (k *K) Marshal(dst []byte) (buf []byte) {
237 return ints.New(k.ToU64()).Marshal(dst)
238 }
239
240 func (k *K) Unmarshal(b []byte) (r []byte, err error) {
241 n := ints.New(0)
242 if r, err = n.Unmarshal(b); chk.T(err) {
243 return
244 }
245 k.K = n.Uint16()
246 return
247 }
248
249 func GetString(t uint16) (s string) {
250 initKinds()
251 return Map[t]
252 }
253
254 func IsEphemeral(k uint16) (ok bool) {
255 initKinds()
256 return k >= EphemeralStart.K && k < EphemeralEnd.K
257 }
258
259 func IsReplaceable(k uint16) (ok bool) {
260 initKinds()
261 return k == ProfileMetadata.K || k == FollowList.K ||
262 (k >= ReplaceableStart.K && k < ReplaceableEnd.K)
263 }
264
265 func IsParameterizedReplaceable(k uint16) (ok bool) {
266 initKinds()
267 return k >= ParameterizedReplaceableStart.K &&
268 k < ParameterizedReplaceableEnd.K
269 }
270
271 func IsDirectoryEvent(k uint16) (ok bool) {
272 initKinds()
273 for i := range Directory {
274 if k == Directory[i].K {
275 return true
276 }
277 }
278 return false
279 }
280
281 var (
282 ProfileMetadata *K
283 SetMetadata *K
284 TextNote *K
285 RecommendRelay *K
286 FollowList *K
287 Follows *K
288 EncryptedDirectMessage *K
289 EventDeletion *K
290 Deletion *K
291 Repost *K
292 Reaction *K
293 BadgeAward *K
294 ChatMessage *K
295 GroupChatThreadedReply *K
296 Thread *K
297 GroupThreadReply *K
298 Seal *K
299 DirectMessage *K
300 FileMessage *K
301 GenericRepost *K
302 ReactionToWebsite *K
303 Picture *K
304 VideoEventHorizontal *K
305 VideoEventVertical *K
306 MLSKeyPackage *K
307 MLSWelcome *K
308 MLSGroupEvent *K
309 ChannelCreation *K
310 ChannelMetadata *K
311 ChannelMessage *K
312 ChannelHideMessage *K
313 ChannelMuteUser *K
314 Bid *K
315 BidConfirmation *K
316 OpenTimestamps *K
317 GiftWrap *K
318 GiftWrapWithKind4 *K
319 FileMetadata *K
320 LiveChatMessage *K
321 BitcoinBlock *K
322 LiveStream *K
323 ProblemTracker *K
324 MemoryHole *K
325 Reporting *K
326 Label *K
327 CommunityPostApproval *K
328 JobRequestStart *K
329 JobRequestEnd *K
330 JobResultStart *K
331 JobResultEnd *K
332 JobFeedback *K
333 ZapGoal *K
334 ZapRequest *K
335 Zap *K
336 Highlights *K
337 ReplaceableStart *K
338 MuteList *K
339 BlockList *K
340 PinList *K
341 RelayListMetadata *K
342 BookmarkList *K
343 CommunitiesList *K
344 PublicChatsList *K
345 BlockedRelaysList *K
346 SearchRelaysList *K
347 RelayGroupConfig *K
348 InterestsList *K
349 UserEmojiList *K
350 DMRelaysList *K
351 KeyPackageRelaysList *K
352 FileStorageServerList *K
353 JWTBinding *K
354 NWCWalletServiceInfo *K
355 WalletServiceInfo *K
356 ReplaceableEnd *K
357 EphemeralStart *K
358 LightningPubRPC *K
359 ClientAuthentication *K
360 NWCWalletRequest *K
361 WalletRequest *K
362 NWCWalletResponse *K
363 WalletResponse *K
364 NWCNotification *K
365 WalletNotificationNip4 *K
366 WalletNotification *K
367 NostrConnect *K
368 HTTPAuth *K
369 EphemeralEnd *K
370 ParameterizedReplaceableStart *K
371 CategorizedPeopleList *K
372 FollowSets *K
373 CategorizedBookmarksList *K
374 GenericLists *K
375 RelaySets *K
376 BookmarkSets *K
377 CurationSets *K
378 ProfileBadges *K
379 BadgeDefinition *K
380 InterestSets *K
381 StallDefinition *K
382 ProductDefinition *K
383 MarketplaceUIUX *K
384 ProductSoldAsAuction *K
385 Article *K
386 LongFormContent *K
387 DraftLongFormContent *K
388 EmojiSets *K
389 ApplicationSpecificData *K
390 LiveEvent *K
391 UserStatuses *K
392 ClassifiedListing *K
393 DraftClassifiedListing *K
394 DateBasedCalendarEvent *K
395 TimeBasedCalendarEvent *K
396 Calendar *K
397 CalendarEventRSVP *K
398 HandlerRecommendation *K
399 HandlerInformation *K
400 WaveLakeTrack *K
401 CommunityDefinition *K
402 ACLEvent *K
403 PolicyConfig *K
404 ParameterizedReplaceableEnd *K
405 Map map[uint16]string
406 )
407