Files
nostrlib/filter_easyjson.go

274 lines
5.3 KiB
Go

package nostr
import (
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
"github.com/templexxx/xhex"
)
func easyjsonDecodeFilter(in *jlexer.Lexer, out *Filter) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "ids":
in.Delim('[')
if out.IDs == nil {
if !in.IsDelim(']') {
out.IDs = make([]ID, 0, 20)
} else {
out.IDs = []ID{}
}
} else {
out.IDs = (out.IDs)[:0]
}
for !in.IsDelim(']') {
id := ID{}
b := in.UnsafeBytes()
if len(b) == 64 {
xhex.Decode(id[:], b)
}
out.IDs = append(out.IDs, id)
in.WantComma()
}
in.Delim(']')
case "kinds":
in.Delim('[')
if out.Kinds == nil {
if !in.IsDelim(']') {
out.Kinds = make([]Kind, 0, 8)
} else {
out.Kinds = []Kind{}
}
} else {
out.Kinds = (out.Kinds)[:0]
}
for !in.IsDelim(']') {
out.Kinds = append(out.Kinds, Kind(in.Int()))
in.WantComma()
}
in.Delim(']')
case "authors":
in.Delim('[')
if out.Authors == nil {
if !in.IsDelim(']') {
out.Authors = make([]PubKey, 0, 40)
} else {
out.Authors = []PubKey{}
}
} else {
out.Authors = (out.Authors)[:0]
}
for !in.IsDelim(']') {
pk := PubKey{}
b := in.UnsafeBytes()
if len(b) == 64 {
xhex.Decode(pk[:], b)
}
out.Authors = append(out.Authors, pk)
in.WantComma()
}
in.Delim(']')
case "since":
out.Since = Timestamp(in.Int64())
case "until":
out.Until = Timestamp(in.Int64())
case "limit":
out.Limit = int(in.Int())
if out.Limit == 0 {
out.LimitZero = true
}
case "search":
out.Search = in.String()
default:
if len(key) > 1 && key[0] == '#' {
if out.Tags == nil {
out.Tags = make(TagMap, 1)
}
tagValues := make([]string, 0, 40)
in.Delim('[')
if out.Authors == nil {
if !in.IsDelim(']') {
tagValues = make([]string, 0, 4)
} else {
tagValues = []string{}
}
} else {
tagValues = (tagValues)[:0]
}
for !in.IsDelim(']') {
tagValues = append(tagValues, in.String())
in.WantComma()
}
in.Delim(']')
out.Tags[key[1:]] = tagValues
} else {
in.SkipRecursive()
}
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonEncodeFilter(out *jwriter.Writer, in Filter) {
out.RawByte('{')
first := true
_ = first
if len(in.IDs) != 0 {
first = false
out.RawString("\"ids\":")
{
out.RawByte('[')
for i, id := range in.IDs {
if i > 0 {
out.RawByte(',')
}
out.RawString("\"" + HexEncodeToString(id[:]) + "\"")
}
out.RawByte(']')
}
}
if len(in.Kinds) != 0 {
const prefix string = ",\"kinds\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
{
out.RawByte('[')
for i, kind := range in.Kinds {
if i > 0 {
out.RawByte(',')
}
out.Int(int(kind))
}
out.RawByte(']')
}
}
if len(in.Authors) != 0 {
const prefix string = ",\"authors\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
{
out.RawByte('[')
for i, pk := range in.Authors {
if i > 0 {
out.RawByte(',')
}
out.RawString("\"" + HexEncodeToString(pk[:]) + "\"")
}
out.RawByte(']')
}
}
if in.Since != 0 {
const prefix string = ",\"since\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.Int64(int64(in.Since))
}
if in.Until != 0 {
const prefix string = ",\"until\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.Int64(int64(in.Until))
}
if in.Limit != 0 || in.LimitZero {
const prefix string = ",\"limit\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.Int(int(in.Limit))
}
if in.Search != "" {
const prefix string = ",\"search\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(in.Search)
}
for tag, values := range in.Tags {
const prefix string = ",\"authors\":"
if first {
first = false
out.RawString("\"#" + tag + "\":")
} else {
out.RawString(",\"#" + tag + "\":")
}
{
out.RawByte('[')
for i, v := range values {
if i > 0 {
out.RawByte(',')
}
out.String(v)
}
out.RawByte(']')
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v Filter) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{NoEscapeHTML: true}
easyjsonEncodeFilter(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v Filter) MarshalEasyJSON(w *jwriter.Writer) {
w.NoEscapeHTML = true
easyjsonEncodeFilter(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *Filter) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonDecodeFilter(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *Filter) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonDecodeFilter(l, v)
}