From 08d6943dd1cc20462e8edeead0684fb45e20ec25 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Tue, 31 Dec 2024 23:09:56 -0300 Subject: [PATCH] references returns an iterator because why not? --- sdk/references.go | 140 +++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/sdk/references.go b/sdk/references.go index 3c73be5..f16b6b8 100644 --- a/sdk/references.go +++ b/sdk/references.go @@ -1,6 +1,7 @@ package sdk import ( + "iter" "regexp" "strconv" "strings" @@ -21,88 +22,87 @@ type Reference struct { var mentionRegex = regexp.MustCompile(`\bnostr:((note|npub|naddr|nevent|nprofile)1\w+)\b|#\[(\d+)\]`) // ParseReferences parses both NIP-08 and NIP-27 references in a single unifying interface. -func ParseReferences(evt *nostr.Event) []*Reference { - var references []*Reference - content := evt.Content +func ParseReferences(evt nostr.Event) iter.Seq[Reference] { + return func(yield func(Reference) bool) { + for _, ref := range mentionRegex.FindAllStringSubmatchIndex(evt.Content, -1) { + reference := Reference{ + Text: evt.Content[ref[0]:ref[1]], + Start: ref[0], + End: ref[1], + } - for _, ref := range mentionRegex.FindAllStringSubmatchIndex(evt.Content, -1) { - reference := &Reference{ - Text: content[ref[0]:ref[1]], - Start: ref[0], - End: ref[1], - } + if ref[6] == -1 { + // didn't find a NIP-10 #[0] reference, so it's a NIP-27 mention + nip19code := evt.Content[ref[2]:ref[3]] - if ref[6] == -1 { - // didn't find a NIP-10 #[0] reference, so it's a NIP-27 mention - nip19code := content[ref[2]:ref[3]] - - if prefix, data, err := nip19.Decode(nip19code); err == nil { - switch prefix { - case "npub": - reference.Profile = &nostr.ProfilePointer{ - PublicKey: data.(string), Relays: []string{}, + if prefix, data, err := nip19.Decode(nip19code); err == nil { + switch prefix { + case "npub": + reference.Profile = &nostr.ProfilePointer{ + PublicKey: data.(string), Relays: []string{}, + } + case "nprofile": + pp := data.(nostr.ProfilePointer) + reference.Profile = &pp + case "note": + reference.Event = &nostr.EventPointer{ID: data.(string), Relays: []string{}} + case "nevent": + evp := data.(nostr.EventPointer) + reference.Event = &evp + case "naddr": + addr := data.(nostr.EntityPointer) + reference.Entity = &addr } - case "nprofile": - pp := data.(nostr.ProfilePointer) - reference.Profile = &pp - case "note": - reference.Event = &nostr.EventPointer{ID: data.(string), Relays: []string{}} - case "nevent": - evp := data.(nostr.EventPointer) - reference.Event = &evp - case "naddr": - addr := data.(nostr.EntityPointer) - reference.Entity = &addr } - } - } else { - // it's a NIP-10 mention. - // parse the number, get data from event tags. - n := content[ref[6]:ref[7]] - idx, err := strconv.Atoi(n) - if err != nil || len(evt.Tags) <= idx { - continue - } - if tag := evt.Tags[idx]; tag != nil && len(tag) >= 2 { - switch tag[0] { - case "p": - relays := make([]string, 0, 1) - if len(tag) > 2 && tag[2] != "" { - relays = append(relays, tag[2]) - } - reference.Profile = &nostr.ProfilePointer{ - PublicKey: tag[1], - Relays: relays, - } - case "e": - relays := make([]string, 0, 1) - if len(tag) > 2 && tag[2] != "" { - relays = append(relays, tag[2]) - } - reference.Event = &nostr.EventPointer{ - ID: tag[1], - Relays: relays, - } - case "a": - if parts := strings.Split(tag[1], ":"); len(parts) == 3 { - kind, _ := strconv.Atoi(parts[0]) + } else { + // it's a NIP-10 mention. + // parse the number, get data from event tags. + n := evt.Content[ref[6]:ref[7]] + idx, err := strconv.Atoi(n) + if err != nil || len(evt.Tags) <= idx { + continue + } + if tag := evt.Tags[idx]; tag != nil && len(tag) >= 2 { + switch tag[0] { + case "p": relays := make([]string, 0, 1) if len(tag) > 2 && tag[2] != "" { relays = append(relays, tag[2]) } - reference.Entity = &nostr.EntityPointer{ - Identifier: parts[2], - PublicKey: parts[1], - Kind: kind, - Relays: relays, + reference.Profile = &nostr.ProfilePointer{ + PublicKey: tag[1], + Relays: relays, + } + case "e": + relays := make([]string, 0, 1) + if len(tag) > 2 && tag[2] != "" { + relays = append(relays, tag[2]) + } + reference.Event = &nostr.EventPointer{ + ID: tag[1], + Relays: relays, + } + case "a": + if parts := strings.Split(tag[1], ":"); len(parts) == 3 { + kind, _ := strconv.Atoi(parts[0]) + relays := make([]string, 0, 1) + if len(tag) > 2 && tag[2] != "" { + relays = append(relays, tag[2]) + } + reference.Entity = &nostr.EntityPointer{ + Identifier: parts[2], + PublicKey: parts[1], + Kind: kind, + Relays: relays, + } } } } } + + if !yield(reference) { + return + } } - - references = append(references, reference) } - - return references }