filters.mx raw

   1  package filter
   2  
   3  import (
   4  	"smesh.lol/pkg/nostr/event"
   5  	"smesh.lol/pkg/lol/errorf"
   6  )
   7  
   8  type S []*F
   9  
  10  func NewS(ff ...*F) *S {
  11  	s := S(ff)
  12  	return &s
  13  }
  14  
  15  func (s *S) Match(event *event.E) bool {
  16  	for _, f := range *s {
  17  		if f.Matches(event) {
  18  			return true
  19  		}
  20  	}
  21  	return false
  22  }
  23  
  24  func (s *S) Marshal(dst []byte) (b []byte) {
  25  	if s == nil {
  26  		panic("nil filter slice")
  27  	}
  28  	b = dst
  29  	b = append(b, '[')
  30  	first := false
  31  	for _, f := range *s {
  32  		if f == nil {
  33  			continue
  34  		}
  35  		if first {
  36  			b = append(b, ',')
  37  		} else {
  38  			first = true
  39  		}
  40  		b = f.Marshal(b)
  41  	}
  42  	b = append(b, ']')
  43  	return
  44  }
  45  
  46  func (s *S) Unmarshal(b []byte) (r []byte, err error) {
  47  	r = b
  48  	if len(r) == 0 {
  49  		return
  50  	}
  51  	isArrayWrapped := r[0] == '['
  52  	if isArrayWrapped {
  53  		r = r[1:]
  54  		if len(r) > 0 && r[0] == ']' {
  55  			r = r[1:]
  56  			return
  57  		}
  58  	}
  59  	for {
  60  		if len(r) == 0 {
  61  			return
  62  		}
  63  		f := New()
  64  		var rem []byte
  65  		if rem, err = f.Unmarshal(r); err != nil {
  66  			return
  67  		}
  68  		*s = append(*s, f)
  69  		r = rem
  70  		if len(r) == 0 {
  71  			return
  72  		}
  73  		if r[0] == ',' {
  74  			r = r[1:]
  75  			continue
  76  		}
  77  		if r[0] == ']' {
  78  			if isArrayWrapped {
  79  				r = r[1:]
  80  			}
  81  			return
  82  		}
  83  		err = errorf.E(
  84  			[]byte("filters.Unmarshal: expected ',' or ']' after filter, got: %q"),
  85  			r[0],
  86  		)
  87  		return
  88  	}
  89  }
  90  
  91  func (s *S) MatchIgnoringTimestampConstraints(ev *event.E) bool {
  92  	for _, ff := range *s {
  93  		if ff.MatchesIgnoringTimestampConstraints(ev) {
  94  			return true
  95  		}
  96  	}
  97  	return false
  98  }
  99