package nostr // Tag is a single NIP-01 tag: a non-empty JSON array of strings whose first // element names the tag. type Tag []string // Tags is the ordered tag list of an event. type Tags []Tag // Name returns the tag name, or "" for an empty tag. func (t Tag) Name() string { if len(t) == 0 { return "" } return t[0] } // Value returns the first value (index 1) of the tag, or "". func (t Tag) Value() string { if len(t) < 2 { return "" } return t[1] } // First returns the value of the first tag with the given name. func (ts Tags) First(name string) (string, bool) { for _, t := range ts { if t.Name() == name { return t.Value(), true } } return "", false } // Values returns every value of every tag with the given name. func (ts Tags) Values(name string) []string { var out []string for _, t := range ts { if t.Name() == name && len(t) >= 2 { out = append(out, t[1]) } } return out } // Has reports whether a tag with the given name and value exists. func (ts Tags) Has(name, value string) bool { for _, t := range ts { if t.Name() == name && t.Value() == value { return true } } return false } // HasName reports whether any tag with the given name exists. func (ts Tags) HasName(name string) bool { for _, t := range ts { if t.Name() == name { return true } } return false } // DTag returns the first "d" tag value, or "". func (e *Event) DTag() string { v, _ := e.Tags.First("d") return v } // AppendJSON appends the tag list as a JSON array. func (ts Tags) AppendJSON(dst []byte) []byte { dst = append(dst, '[') for i, t := range ts { if i > 0 { dst = append(dst, ',') } dst = t.AppendJSON(dst) } return append(dst, ']') } // AppendJSON appends one tag as a JSON array of strings. func (t Tag) AppendJSON(dst []byte) []byte { dst = append(dst, '[') for i, s := range t { if i > 0 { dst = append(dst, ',') } dst = AppendJSONString(dst, s) } return append(dst, ']') } // IndexableTags calls fn for every single-letter tag that the store indexes. // NIP-01 only defines filters for single-letter tag names; multi-letter tags // are not indexed. func (ts Tags) IndexableTags(fn func(name string, value string)) { for _, t := range ts { if len(t) < 2 { continue } if len(t[0]) != 1 { continue } fn(t[0], t[1]) } }