84 lines
1.8 KiB
Go
84 lines
1.8 KiB
Go
package filter
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/lixenwraith/vif-log/internal/logfile"
|
|
)
|
|
|
|
func init() {
|
|
Register(Desc{Kind: "find", Help: "regexp over the focused column, smart-case", New: newFind})
|
|
}
|
|
|
|
// Find keeps records whose focused column matches the pattern. Time, tick, sub
|
|
// and msg resolve from the index row, so only fields and all read the file.
|
|
type Find struct {
|
|
Query string
|
|
Col logfile.Column
|
|
pat Pattern
|
|
scratch []byte
|
|
}
|
|
|
|
// NewFind returns an inert find filter.
|
|
func NewFind() *Find { return &Find{} }
|
|
|
|
func newFind(arg string) (Filter, error) {
|
|
f := NewFind()
|
|
if err := f.Set(arg, logfile.ColAll); err != nil {
|
|
return nil, err
|
|
}
|
|
return f, nil
|
|
}
|
|
|
|
// Set replaces the pattern and its column scope.
|
|
func (f *Find) Set(q string, col logfile.Column) error {
|
|
p, err := NewPattern(q)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
f.Query, f.Col, f.pat = q, col, p
|
|
return nil
|
|
}
|
|
|
|
// Active reports whether the filter constrains anything.
|
|
func (f *Find) Active() bool { return !f.pat.Empty() }
|
|
|
|
func (f *Find) Kind() string { return "find" }
|
|
|
|
func (f *Find) Needs() Need {
|
|
if !f.Active() {
|
|
return 0
|
|
}
|
|
switch f.Col {
|
|
case logfile.ColFields, logfile.ColAll:
|
|
return NeedFields
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (f *Find) Match(c *Ctx) bool {
|
|
if !f.Active() {
|
|
return true
|
|
}
|
|
switch f.Col {
|
|
case logfile.ColTime:
|
|
f.scratch = append(f.scratch[:0], logfile.StampText(c.Meta)...)
|
|
case logfile.ColTick:
|
|
f.scratch = strconv.AppendUint(f.scratch[:0], uint64(c.Meta.Tick), 10)
|
|
case logfile.ColSub:
|
|
f.scratch = append(f.scratch[:0], c.Idx.SubName(c.Meta.Sub)...)
|
|
case logfile.ColMsg:
|
|
f.scratch = append(f.scratch[:0], c.Idx.MsgName(c.Meta.Msg)...)
|
|
default:
|
|
return f.pat.MatchBytes(c.Record().ColumnBytes(f.Col))
|
|
}
|
|
return f.pat.MatchBytes(f.scratch)
|
|
}
|
|
|
|
func (f *Find) Label() string {
|
|
if !f.Active() {
|
|
return ""
|
|
}
|
|
return "/" + f.Col.String() + ":" + f.Query
|
|
}
|