diff --git a/director.go b/director.go index 862e005..19dba90 100644 --- a/director.go +++ b/director.go @@ -3,8 +3,8 @@ package tv import ( "io/fs" + "github.com/snivilised/traverse/internal/feat/filter" "github.com/snivilised/traverse/internal/feat/hiber" - "github.com/snivilised/traverse/internal/feat/refine" "github.com/snivilised/traverse/internal/feat/resume" "github.com/snivilised/traverse/internal/feat/sampling" "github.com/snivilised/traverse/internal/kernel" @@ -29,7 +29,7 @@ func features(o *pref.Options, mediator types.Mediator, // order. How can we decouple ourselves from this // requirement? => the cure is worse than the disease // - hiber.IfActive, refine.IfActive, sampling.IfActive, + hiber.IfActive, filter.IfActive, sampling.IfActive, } ) diff --git a/internal/feat/filter/base.go b/internal/feat/filter/base.go new file mode 100644 index 0000000..392aa74 --- /dev/null +++ b/internal/feat/filter/base.go @@ -0,0 +1,48 @@ +package filter + +import ( + "github.com/snivilised/traverse/core" + "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/internal/third/lo" +) + +// Base Filter ================================================================ + +// Base base filter struct. +type Base struct { + name string + pattern string + scope enums.FilterScope // defines which file system nodes the filter should be applied to + negate bool // select to define a negative match + ifNotApplicable bool +} + +// Description description of the filter +func (f *Base) Description() string { + return f.name +} + +// Source text defining the filter +func (f *Base) Source() string { + return f.pattern +} + +func (f *Base) IsApplicable(node *core.Node) bool { + return (f.scope & node.Extension.Scope) > 0 +} + +func (f *Base) Scope() enums.FilterScope { + return f.scope +} + +func (f *Base) invert(result bool) bool { + return lo.Ternary(f.negate, !result, result) +} + +func (f *Base) Validate() error { + if f.scope == enums.ScopeUndefined { + f.scope = enums.ScopeAll + } + + return nil +} diff --git a/internal/feat/filter/child.go b/internal/feat/filter/child.go new file mode 100644 index 0000000..e453e8b --- /dev/null +++ b/internal/feat/filter/child.go @@ -0,0 +1,30 @@ +package filter + +import ( + "github.com/snivilised/traverse/internal/third/lo" +) + +// Child Filter =============================================================== + +// Child filter used when subscription is FoldersWithFiles +type Child struct { + Name string + Pattern string + Negate bool +} + +func (f *Child) Description() string { + return f.Name +} + +func (f *Child) Validate() error { + return nil +} + +func (f *Child) Source() string { + return f.Pattern +} + +func (f *Child) invert(result bool) bool { + return lo.Ternary(f.Negate, !result, result) +} diff --git a/internal/feat/refine/extended-glob.go b/internal/feat/filter/extended-glob.go similarity index 98% rename from internal/feat/refine/extended-glob.go rename to internal/feat/filter/extended-glob.go index a038a76..f93c368 100644 --- a/internal/feat/refine/extended-glob.go +++ b/internal/feat/filter/extended-glob.go @@ -1,4 +1,4 @@ -package refine +package filter import ( "io/fs" @@ -10,7 +10,7 @@ import ( ) type ExtendedGlobFilter struct { - Filter + Base baseGlob string suffixes []string anyExtension bool @@ -75,7 +75,7 @@ func (f *ExtendedGlobFilter) IsMatch(node *core.Node) bool { // ChildExtendedGlobFilter ========================================================== type ChildExtendedGlobFilter struct { - ChildFilter + Child baseGlob string exclusion string suffixes []string diff --git a/internal/feat/refine/filter-plugin.go b/internal/feat/filter/filter-plugin.go similarity index 96% rename from internal/feat/refine/filter-plugin.go rename to internal/feat/filter/filter-plugin.go index 7cdae08..f0f2dba 100644 --- a/internal/feat/refine/filter-plugin.go +++ b/internal/feat/filter/filter-plugin.go @@ -1,6 +1,6 @@ -package refine +package filter -// 📦 pkg: refine - defines filters +// 📦 pkg: filter - defines filters import ( "github.com/snivilised/traverse/core" diff --git a/internal/feat/refine/glob.go b/internal/feat/filter/glob.go similarity index 98% rename from internal/feat/refine/glob.go rename to internal/feat/filter/glob.go index ed7a69f..2feb1e1 100644 --- a/internal/feat/refine/glob.go +++ b/internal/feat/filter/glob.go @@ -1,4 +1,4 @@ -package refine +package filter import ( "io/fs" @@ -10,7 +10,7 @@ import ( // GlobFilter wildcard filter. type GlobFilter struct { - Filter + Base } // IsMatch does this node match the filter @@ -26,7 +26,7 @@ func (f *GlobFilter) IsMatch(node *core.Node) bool { // ChildGlobFilter ============================================================ type ChildGlobFilter struct { - ChildFilter + Child } // Matching returns the collection of files contained within this diff --git a/internal/feat/refine/new-filter.go b/internal/feat/filter/new-filter.go similarity index 97% rename from internal/feat/refine/new-filter.go rename to internal/feat/filter/new-filter.go index d4aa41a..367d3b4 100644 --- a/internal/feat/refine/new-filter.go +++ b/internal/feat/filter/new-filter.go @@ -1,4 +1,4 @@ -package refine +package filter import ( "slices" @@ -56,7 +56,7 @@ func newNodeFilter(def *core.FilterDef, base, exclusion := splitGlob(segments[0]) filter = &ExtendedGlobFilter{ - Filter: Filter{ + Base: Base{ name: def.Description, scope: def.Scope, pattern: def.Pattern, @@ -73,7 +73,7 @@ func newNodeFilter(def *core.FilterDef, case enums.FilterTypeRegex: filter = &RegexFilter{ - Filter: Filter{ + Base: Base{ name: def.Description, scope: def.Scope, pattern: def.Pattern, @@ -84,7 +84,7 @@ func newNodeFilter(def *core.FilterDef, case enums.FilterTypeGlob: filter = &GlobFilter{ - Filter: Filter{ + Base: Base{ name: def.Description, scope: def.Scope, pattern: def.Pattern, @@ -186,7 +186,7 @@ func newChildFilter(def *core.ChildFilterDef) (core.ChildTraverseFilter, error) base, exclusion := splitGlob(segments[0]) filter = &ChildExtendedGlobFilter{ - ChildFilter: ChildFilter{ + Child: Child{ Name: def.Description, Pattern: def.Pattern, Negate: def.Negate, @@ -201,7 +201,7 @@ func newChildFilter(def *core.ChildFilterDef) (core.ChildTraverseFilter, error) case enums.FilterTypeRegex: filter = &ChildRegexFilter{ - ChildFilter: ChildFilter{ + Child: Child{ Name: def.Description, Pattern: def.Pattern, Negate: def.Negate, @@ -210,7 +210,7 @@ func newChildFilter(def *core.ChildFilterDef) (core.ChildTraverseFilter, error) case enums.FilterTypeGlob: filter = &ChildGlobFilter{ - ChildFilter: ChildFilter{ + Child: Child{ Name: def.Description, Pattern: def.Pattern, Negate: def.Negate, @@ -247,7 +247,7 @@ func newSampleFilter(def *core.SampleFilterDef, } base := SampleFilter{ - Filter: Filter{ + Base: Base{ name: def.Description, scope: def.Scope.Scrub(), pattern: def.Pattern, diff --git a/internal/feat/refine/poly.go b/internal/feat/filter/poly.go similarity index 99% rename from internal/feat/refine/poly.go rename to internal/feat/filter/poly.go index 020a2c3..4230ea9 100644 --- a/internal/feat/refine/poly.go +++ b/internal/feat/filter/poly.go @@ -1,4 +1,4 @@ -package refine +package filter import ( "fmt" diff --git a/internal/feat/refine/regex.go b/internal/feat/filter/regex.go similarity index 94% rename from internal/feat/refine/regex.go rename to internal/feat/filter/regex.go index 6144ea5..b3d0fe1 100644 --- a/internal/feat/refine/regex.go +++ b/internal/feat/filter/regex.go @@ -1,4 +1,4 @@ -package refine +package filter import ( "io/fs" @@ -12,13 +12,13 @@ import ( // RegexFilter regex filter. type RegexFilter struct { - Filter + Base rex *regexp.Regexp } // Validate ensures the filter definition is valid, panics when invalid func (f *RegexFilter) Validate() error { - if err := f.Filter.Validate(); err != nil { + if err := f.Base.Validate(); err != nil { return err } @@ -42,7 +42,7 @@ func (f *RegexFilter) IsMatch(node *core.Node) bool { // ChildRegexFilter =========================================================== type ChildRegexFilter struct { - ChildFilter + Child rex *regexp.Regexp } @@ -76,7 +76,7 @@ type SampleRegexFilter struct { // Validate ensures the filter definition is valid, panics when invalid func (f *SampleRegexFilter) Validate() error { - if err := f.Filter.Validate(); err != nil { + if err := f.Base.Validate(); err != nil { return err } diff --git a/internal/feat/refine/base.go b/internal/feat/filter/sample.go similarity index 50% rename from internal/feat/refine/base.go rename to internal/feat/filter/sample.go index 165107f..8e65c15 100644 --- a/internal/feat/refine/base.go +++ b/internal/feat/filter/sample.go @@ -1,94 +1,27 @@ -package refine +package filter import ( "io/fs" - "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" "github.com/snivilised/traverse/internal/third/lo" "github.com/snivilised/traverse/nfs" ) -// Filter ===================================================================== - -// Filter base filter struct. -type Filter struct { - name string - pattern string - scope enums.FilterScope // defines which file system nodes the filter should be applied to - negate bool // select to define a negative match - ifNotApplicable bool -} - -// Description description of the filter -func (f *Filter) Description() string { - return f.name -} - -// Source text defining the filter -func (f *Filter) Source() string { - return f.pattern -} - -func (f *Filter) IsApplicable(node *core.Node) bool { - return (f.scope & node.Extension.Scope) > 0 -} - -func (f *Filter) Scope() enums.FilterScope { - return f.scope -} - -func (f *Filter) invert(result bool) bool { - return lo.Ternary(f.negate, !result, result) -} - -func (f *Filter) Validate() error { - if f.scope == enums.ScopeUndefined { - f.scope = enums.ScopeAll - } - - return nil -} - -// ChildFilter ================================================================ - -// ChildFilter filter used when subscription is FoldersWithFiles -type ChildFilter struct { - Name string - Pattern string - Negate bool -} - -func (f *ChildFilter) Description() string { - return f.Name -} - -func (f *ChildFilter) Validate() error { - return nil -} - -func (f *ChildFilter) Source() string { - return f.Pattern -} - -func (f *ChildFilter) invert(result bool) bool { - return lo.Ternary(f.Negate, !result, result) -} - // BaseSampleFilter =========================================================== type ( candidates func(entries []fs.DirEntry) (wanted, others []fs.DirEntry) ) type SampleFilter struct { - Filter + Base } // NewSampleFilter only needs to be called explicitly when defining // a custom sample filter. func NewSampleFilter(scope enums.FilterScope) SampleFilter { return SampleFilter{ - Filter: Filter{ + Base: Base{ scope: scope, }, } diff --git a/internal/feat/refine/schemes.go b/internal/feat/filter/schemes.go similarity index 97% rename from internal/feat/refine/schemes.go rename to internal/feat/filter/schemes.go index 0126fd1..109a9ff 100644 --- a/internal/feat/refine/schemes.go +++ b/internal/feat/filter/schemes.go @@ -1,10 +1,11 @@ -package refine +package filter import ( "io/fs" "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/internal/filtering" "github.com/snivilised/traverse/internal/measure" "github.com/snivilised/traverse/internal/third/lo" "github.com/snivilised/traverse/internal/types" @@ -66,7 +67,7 @@ type nativeScheme struct { } func (f *nativeScheme) create() error { - filter, err := newNodeFilter(f.o.Filter.Node, &f.o.Filter) + filter, err := filtering.NewNodeFilter(f.o.Filter.Node, &f.o.Filter) if err != nil { return err } diff --git a/internal/feat/resume/resume-defs.go b/internal/feat/resume/resume-defs.go index b35ecbb..c034484 100644 --- a/internal/feat/resume/resume-defs.go +++ b/internal/feat/resume/resume-defs.go @@ -8,8 +8,8 @@ import ( "github.com/snivilised/traverse/pref" ) -// 📦 pkg: resume - depends on hiber, refine and persist. -// refine should also contain persistence concerns (actually +// 📦 pkg: resume - depends on hiber, filter and persist. +// filter should also contain persistence concerns (actually // these may be internal modules, eg internal/serial/JSON). const ( diff --git a/internal/filtering/base.go b/internal/filtering/base.go index 6a89fbd..26e8a35 100644 --- a/internal/filtering/base.go +++ b/internal/filtering/base.go @@ -8,8 +8,8 @@ import ( // Filter ===================================================================== -// Filter base filter struct. -type Filter struct { +// Base base filter struct. +type Base struct { name string pattern string scope enums.FilterScope // defines which file system nodes the filter should be applied to @@ -18,56 +18,31 @@ type Filter struct { } // Description description of the filter -func (f *Filter) Description() string { +func (f *Base) Description() string { return f.name } // Source text defining the filter -func (f *Filter) Source() string { +func (f *Base) Source() string { return f.pattern } -func (f *Filter) IsApplicable(node *core.Node) bool { +func (f *Base) IsApplicable(node *core.Node) bool { return (f.scope & node.Extension.Scope) > 0 } -func (f *Filter) Scope() enums.FilterScope { +func (f *Base) Scope() enums.FilterScope { return f.scope } -func (f *Filter) invert(result bool) bool { +func (f *Base) invert(result bool) bool { return lo.Ternary(f.negate, !result, result) } -func (f *Filter) Validate() error { +func (f *Base) Validate() error { if f.scope == enums.ScopeUndefined { f.scope = enums.ScopeAll } return nil } - -// ChildFilter ================================================================ - -// ChildFilter filter used when subscription is FoldersWithFiles -type ChildFilter struct { - Name string - Pattern string - Negate bool -} - -func (f *ChildFilter) Description() string { - return f.Name -} - -func (f *ChildFilter) Validate() error { - return nil -} - -func (f *ChildFilter) Source() string { - return f.Pattern -} - -func (f *ChildFilter) invert(result bool) bool { - return lo.Ternary(f.Negate, !result, result) -} diff --git a/internal/filtering/child.go b/internal/filtering/child.go new file mode 100644 index 0000000..847019e --- /dev/null +++ b/internal/filtering/child.go @@ -0,0 +1,30 @@ +package filtering + +import ( + "github.com/snivilised/traverse/internal/third/lo" +) + +// ChildFilter ================================================================ + +// Child filter used when subscription is FoldersWithFiles +type Child struct { + Name string + Pattern string + Negate bool +} + +func (f *Child) Description() string { + return f.Name +} + +func (f *Child) Validate() error { + return nil +} + +func (f *Child) Source() string { + return f.Pattern +} + +func (f *Child) invert(result bool) bool { + return lo.Ternary(f.Negate, !result, result) +} diff --git a/internal/filtering/constant.go b/internal/filtering/constant.go index 97aa613..0886768 100644 --- a/internal/filtering/constant.go +++ b/internal/filtering/constant.go @@ -7,7 +7,7 @@ import ( func NewPermissiveTraverseFilter(def *core.FilterDef) core.TraverseFilter { return &permissiveTraverseFilter{ - Filter: Filter{ + Base: Base{ name: def.Description, scope: enums.ScopeTop, }, @@ -15,7 +15,7 @@ func NewPermissiveTraverseFilter(def *core.FilterDef) core.TraverseFilter { } type permissiveTraverseFilter struct { - Filter + Base match bool } @@ -29,7 +29,7 @@ func (f *permissiveTraverseFilter) IsMatch(_ *core.Node) bool { func NewProhibitiveTraverseFilter(def *core.FilterDef) core.TraverseFilter { return &prohibitiveTraverseFilter{ - Filter: Filter{ + Base: Base{ name: def.Description, scope: enums.ScopeTop, }, @@ -37,7 +37,7 @@ func NewProhibitiveTraverseFilter(def *core.FilterDef) core.TraverseFilter { } type prohibitiveTraverseFilter struct { - Filter + Base match bool } diff --git a/internal/filtering/extended-glob.go b/internal/filtering/extended-glob.go index 14bce96..7c371d5 100644 --- a/internal/filtering/extended-glob.go +++ b/internal/filtering/extended-glob.go @@ -23,8 +23,8 @@ func createExtendedGlobFilter(def *core.FilterDef, base, exclusion := splitGlob(segments[0]) - filter := &ExtendedGlobFilter{ - Filter: Filter{ + filter := &ExtendedGlob{ + Base: Base{ name: def.Description, scope: def.Scope, pattern: def.Pattern, @@ -42,8 +42,8 @@ func createExtendedGlobFilter(def *core.FilterDef, return filter, nil } -type ExtendedGlobFilter struct { - Filter +type ExtendedGlob struct { + Base baseGlob string suffixes []string anyExtension bool @@ -51,7 +51,7 @@ type ExtendedGlobFilter struct { } // IsMatch does this node match the filter -func (f *ExtendedGlobFilter) IsMatch(node *core.Node) bool { +func (f *ExtendedGlob) IsMatch(node *core.Node) bool { if f.IsApplicable(node) { result := lo.TernaryF(node.IsFolder(), func() bool { @@ -75,7 +75,7 @@ func (f *ExtendedGlobFilter) IsMatch(node *core.Node) bool { // ChildExtendedGlobFilter ========================================================== type ChildExtendedGlobFilter struct { - ChildFilter + Child baseGlob string exclusion string suffixes []string diff --git a/internal/filtering/filtering-defs.go b/internal/filtering/filtering-defs.go index bae13b6..55790d4 100644 --- a/internal/filtering/filtering-defs.go +++ b/internal/filtering/filtering-defs.go @@ -1,14 +1,14 @@ package filtering // 📦 pkg: filtering - this package is required because filters are required -// not just but the refine plugin, but others too like hibernation. The filter -// required by hibernation could have been implemented by the refine plugin, +// not just but the filter plugin, but others too like hibernation. The filter +// required by hibernation could have been implemented by the filter plugin, // but doing so in this fashion would have mean introducing coupling of -// hibernation on refine; ie how to allow hibernation to access the filter(s) -// created by refine? +// hibernation on filter; ie how to allow hibernation to access the filter(s) +// created by filter? // Instead, we factor out the filter creation code to this package, so that // hibernation can create and apply filters as it needs, without depending on -// refine. So refine, now doesn't own the filter implementations, rather it's +// filter. So filter, now doesn't own the filter implementations, rather it's // simply responsible for the plugin aspects of filtering, not implementation // or creation. // diff --git a/internal/filtering/glob.go b/internal/filtering/glob.go index 2fc5224..b420271 100644 --- a/internal/filtering/glob.go +++ b/internal/filtering/glob.go @@ -11,8 +11,8 @@ import ( func createGlobFilter(def *core.FilterDef, ifNotApplicable bool, ) core.TraverseFilter { - return &GlobFilter{ - Filter: Filter{ + return &Glob{ + Base: Base{ name: def.Description, scope: def.Scope, pattern: def.Pattern, @@ -22,13 +22,13 @@ func createGlobFilter(def *core.FilterDef, } } -// GlobFilter wildcard filter. -type GlobFilter struct { - Filter +// Glob wildcard filter. +type Glob struct { + Base } // IsMatch does this node match the filter -func (f *GlobFilter) IsMatch(node *core.Node) bool { +func (f *Glob) IsMatch(node *core.Node) bool { if f.IsApplicable(node) { matched, _ := filepath.Match(f.pattern, node.Extension.Name) return f.invert(matched) @@ -39,13 +39,13 @@ func (f *GlobFilter) IsMatch(node *core.Node) bool { // ChildGlobFilter ============================================================ -type ChildGlobFilter struct { - ChildFilter +type ChildGlob struct { + Child } // Matching returns the collection of files contained within this // node's folder that matches this filter. -func (f *ChildGlobFilter) Matching(children []fs.DirEntry) []fs.DirEntry { +func (f *ChildGlob) Matching(children []fs.DirEntry) []fs.DirEntry { return lo.Filter(children, func(entry fs.DirEntry, _ int) bool { matched, _ := filepath.Match(f.Pattern, entry.Name()) @@ -56,17 +56,17 @@ func (f *ChildGlobFilter) Matching(children []fs.DirEntry) []fs.DirEntry { // SampleGlobFilter =========================================================== -// SampleGlobFilter is a hybrid between a child filter and a node filter. It +// SampleGlob is a hybrid between a child filter and a node filter. It // is used to filter on a compound basis but has some differences to ChildGlobFilter // that necessitates its use. The biggest difference is that ChildGlobFilter is -// designed to only be applied to file directory entries, where as SampleGlobFilter +// designed to only be applied to file directory entries, where as SampleGlob // can be applied to files or folders. It also possesses a scope field used to // distinguish only between files and folders. -type SampleGlobFilter struct { - SampleFilter +type SampleGlob struct { + Sample } -func (f *SampleGlobFilter) Matching(entries []fs.DirEntry) []fs.DirEntry { +func (f *SampleGlob) Matching(entries []fs.DirEntry) []fs.DirEntry { filterable, bypass := f.fetch(entries) filtered := lo.Filter(filterable, diff --git a/internal/filtering/new-filter.go b/internal/filtering/new-filter.go index c6258e6..94bd84a 100644 --- a/internal/filtering/new-filter.go +++ b/internal/filtering/new-filter.go @@ -118,7 +118,7 @@ func NewChildFilter(def *core.ChildFilterDef) (core.ChildTraverseFilter, error) base, exclusion := splitGlob(segments[0]) filter = &ChildExtendedGlobFilter{ - ChildFilter: ChildFilter{ + Child: Child{ Name: def.Description, Pattern: def.Pattern, Negate: def.Negate, @@ -133,7 +133,7 @@ func NewChildFilter(def *core.ChildFilterDef) (core.ChildTraverseFilter, error) case enums.FilterTypeRegex: filter = &ChildRegexFilter{ - ChildFilter: ChildFilter{ + Child: Child{ Name: def.Description, Pattern: def.Pattern, Negate: def.Negate, @@ -141,8 +141,8 @@ func NewChildFilter(def *core.ChildFilterDef) (core.ChildTraverseFilter, error) } case enums.FilterTypeGlob: - filter = &ChildGlobFilter{ - ChildFilter: ChildFilter{ + filter = &ChildGlob{ + Child: Child{ Name: def.Description, Pattern: def.Pattern, Negate: def.Negate, @@ -194,8 +194,8 @@ func newSampleFilter(def *core.SampleFilterDef, return nil, locale.ErrFilterIsNil } - base := SampleFilter{ - Filter: Filter{ + base := Sample{ + Base: Base{ name: def.Description, scope: def.Scope.Scrub(), pattern: def.Pattern, @@ -215,11 +215,11 @@ func newSampleFilter(def *core.SampleFilterDef, case enums.FilterTypeExtendedGlob: case enums.FilterTypeRegex: filter = &SampleRegexFilter{ - SampleFilter: base, + Sample: base, } case enums.FilterTypeGlob: - filter = &SampleGlobFilter{ - SampleFilter: base, + filter = &SampleGlob{ + Sample: base, } case enums.FilterTypeCustom: diff --git a/internal/filtering/poly.go b/internal/filtering/poly.go index 221c3fe..dd8a31c 100644 --- a/internal/filtering/poly.go +++ b/internal/filtering/poly.go @@ -29,7 +29,7 @@ func createPolyFilter(polyDef *core.PolyFilterDef) (core.TraverseFilter, error) return nil, err } - filter := &PolyFilter{ + filter := &Poly{ File: file, Folder: folder, } @@ -37,7 +37,7 @@ func createPolyFilter(polyDef *core.PolyFilterDef) (core.TraverseFilter, error) return filter, nil } -// PolyFilter is a dual filter that allows files and folders to be filtered +// Poly is a dual filter that allows files and folders to be filtered // independently. The Folder filter only applies when the current node // is a file. This is because, filtering doesn't affect navigation, it only // controls wether the client callback is invoked or not. That is to say, if @@ -47,7 +47,7 @@ func createPolyFilter(polyDef *core.PolyFilterDef) (core.TraverseFilter, error) // the current node is a filter as the client callback will only be invoked // for the file if its parent folder passes the poly folder filter and // the file passes the poly file filter. -type PolyFilter struct { +type Poly struct { // File is the filter that applies to a file. Note that the client does // not have to set the File scope as this is enforced automatically as // well as ensuring that the Folder scope has not been set. The client is @@ -62,14 +62,14 @@ type PolyFilter struct { } // Description -func (f *PolyFilter) Description() string { +func (f *Poly) Description() string { return fmt.Sprintf("Poly - FILE: '%v', FOLDER: '%v'", f.File.Description(), f.Folder.Description(), ) } // Validate ensures that both filters definition are valid, panics when invalid -func (f *PolyFilter) Validate() error { +func (f *Poly) Validate() error { if err := f.File.Validate(); err != nil { return err } @@ -79,7 +79,7 @@ func (f *PolyFilter) Validate() error { // Source returns the Sources of both the File and Folder filters separated // by a '##' -func (f *PolyFilter) Source() string { +func (f *Poly) Source() string { return fmt.Sprintf("%v##%v", f.File.Source(), f.Folder.Source(), ) @@ -88,7 +88,7 @@ func (f *PolyFilter) Source() string { // IsMatch returns true if the current node is a file and both the current // file matches the poly file filter and the file's parent folder matches // the poly folder filter. Returns true of the current node is a folder. -func (f *PolyFilter) IsMatch(node *core.Node) bool { +func (f *Poly) IsMatch(node *core.Node) bool { if !node.IsFolder() { return f.Folder.IsMatch(node.Parent) && f.File.IsMatch(node) } @@ -99,7 +99,7 @@ func (f *PolyFilter) IsMatch(node *core.Node) bool { // IsApplicable returns the result of applying IsApplicable to // the poly Filter filter if the current node is a file, returns false // for folders. -func (f *PolyFilter) IsApplicable(node *core.Node) bool { +func (f *Poly) IsApplicable(node *core.Node) bool { if !node.IsFolder() { return f.File.IsApplicable(node) } @@ -108,6 +108,6 @@ func (f *PolyFilter) IsApplicable(node *core.Node) bool { } // Scope is a bitwise OR combination of both filters -func (f *PolyFilter) Scope() enums.FilterScope { +func (f *Poly) Scope() enums.FilterScope { return f.File.Scope() | f.Folder.Scope() } diff --git a/internal/filtering/regex.go b/internal/filtering/regex.go index 1fb5c19..1329b61 100644 --- a/internal/filtering/regex.go +++ b/internal/filtering/regex.go @@ -11,8 +11,8 @@ import ( func createRegexFilter(def *core.FilterDef, ifNotApplicable bool, ) core.TraverseFilter { - return &RegexFilter{ - Filter: Filter{ + return &RegExpr{ + Base: Base{ name: def.Description, scope: def.Scope, pattern: def.Pattern, @@ -24,15 +24,15 @@ func createRegexFilter(def *core.FilterDef, // RegexFilter ================================================================ -// RegexFilter regex filter. -type RegexFilter struct { - Filter +// RegExpr regex filter. +type RegExpr struct { + Base rex *regexp.Regexp } // Validate ensures the filter definition is valid, panics when invalid -func (f *RegexFilter) Validate() error { - if err := f.Filter.Validate(); err != nil { +func (f *RegExpr) Validate() error { + if err := f.Base.Validate(); err != nil { return err } @@ -45,7 +45,7 @@ func (f *RegexFilter) Validate() error { } // IsMatch -func (f *RegexFilter) IsMatch(node *core.Node) bool { +func (f *RegExpr) IsMatch(node *core.Node) bool { if f.IsApplicable(node) { return f.invert(f.rex.MatchString(node.Extension.Name)) } @@ -56,7 +56,7 @@ func (f *RegexFilter) IsMatch(node *core.Node) bool { // ChildRegexFilter =========================================================== type ChildRegexFilter struct { - ChildFilter + Child rex *regexp.Regexp } @@ -84,13 +84,13 @@ func (f *ChildRegexFilter) Matching(children []fs.DirEntry) []fs.DirEntry { // can be applied to files or folders. It also possesses a scope field used to // distinguish only between files and folders. type SampleRegexFilter struct { - SampleFilter + Sample rex *regexp.Regexp } // Validate ensures the filter definition is valid, panics when invalid func (f *SampleRegexFilter) Validate() error { - if err := f.Filter.Validate(); err != nil { + if err := f.Base.Validate(); err != nil { return err } diff --git a/internal/filtering/sample.go b/internal/filtering/sample.go index 876ea38..2867867 100644 --- a/internal/filtering/sample.go +++ b/internal/filtering/sample.go @@ -14,35 +14,35 @@ type ( candidates func(entries []fs.DirEntry) (wanted, others []fs.DirEntry) ) -type SampleFilter struct { - Filter +type Sample struct { + Base } // NewSampleFilter only needs to be called explicitly when defining // a custom sample filter. -func NewSampleFilter(scope enums.FilterScope) SampleFilter { - return SampleFilter{ - Filter: Filter{ +func NewSampleFilter(scope enums.FilterScope) Sample { + return Sample{ + Base: Base{ scope: scope, }, } } -func (f *SampleFilter) files(entries []fs.DirEntry) (wanted, others []fs.DirEntry) { +func (f *Sample) files(entries []fs.DirEntry) (wanted, others []fs.DirEntry) { wanted, others = nfs.Separate(entries) return wanted, others } -func (f *SampleFilter) folders(entries []fs.DirEntry) (wanted, others []fs.DirEntry) { +func (f *Sample) folders(entries []fs.DirEntry) (wanted, others []fs.DirEntry) { others, wanted = nfs.Separate(entries) return wanted, others } -func (f *SampleFilter) all(entries []fs.DirEntry) (wanted, others []fs.DirEntry) { +func (f *Sample) all(entries []fs.DirEntry) (wanted, others []fs.DirEntry) { return entries, []fs.DirEntry{} } -func (f *SampleFilter) fn() candidates { +func (f *Sample) fn() candidates { if f.scope.IsFolder() { return f.folders } @@ -54,14 +54,14 @@ func (f *SampleFilter) fn() candidates { return f.all } -func (f *SampleFilter) fetch(entries []fs.DirEntry) (wanted, others []fs.DirEntry) { +func (f *Sample) fetch(entries []fs.DirEntry) (wanted, others []fs.DirEntry) { return f.fn()(entries) } // GetMatching sampler func. type GetMatching func(entry fs.DirEntry, index int) bool -func (f *SampleFilter) Matching(children []fs.DirEntry, +func (f *Sample) Matching(children []fs.DirEntry, get GetMatching, ) []fs.DirEntry { filterable, bypass := f.fetch(children) diff --git a/internal/kernel/gomega-matchers_test.go b/internal/kernel/gomega-matchers_test.go index 2cc60ba..16835fb 100644 --- a/internal/kernel/gomega-matchers_test.go +++ b/internal/kernel/gomega-matchers_test.go @@ -5,19 +5,19 @@ import ( . "github.com/onsi/gomega/types" //nolint:revive // ok "github.com/snivilised/traverse/core" - "github.com/snivilised/traverse/internal/feat/refine" + "github.com/snivilised/traverse/internal/filtering" ) // === MatchCurrentRegexFilter === // type IsCurrentRegexMatchMatcher struct { - filter interface{} + rxFilter interface{} } func MatchCurrentRegexFilter(expected interface{}) GomegaMatcher { return &IsCurrentRegexMatchMatcher{ - filter: expected, + rxFilter: expected, } } @@ -27,38 +27,42 @@ func (m *IsCurrentRegexMatchMatcher) Match(actual interface{}) (bool, error) { return false, fmt.Errorf("matcher expected a *TraverseItem (%T)", item) } - filter, filterOk := m.filter.(*refine.RegexFilter) + rxFilter, filterOk := m.rxFilter.(*filtering.RegExpr) if !filterOk { - return false, fmt.Errorf("matcher expected a *RegexFilter (%T)", filter) + return false, fmt.Errorf("matcher expected a *RegexFilter (%T)", rxFilter) } - return filter.IsMatch(item), nil + return rxFilter.IsMatch(item), nil } func (m *IsCurrentRegexMatchMatcher) FailureMessage(actual interface{}) string { item, _ := actual.(*core.Node) - filter, _ := m.filter.(*refine.RegexFilter) + rxFilter, _ := m.rxFilter.(*filtering.RegExpr) - return fmt.Sprintf("🔥 Expected\n\t%v\nto match regex\n\t%v\n", item.Extension.Name, filter.Source()) + return fmt.Sprintf("🔥 Expected\n\t%v\nto match regex\n\t%v\n", + item.Extension.Name, rxFilter.Source(), + ) } func (m *IsCurrentRegexMatchMatcher) NegatedFailureMessage(actual interface{}) string { item, _ := actual.(*core.Node) - filter, _ := m.filter.(*refine.RegexFilter) + rxFilter, _ := m.rxFilter.(*filtering.RegExpr) - return fmt.Sprintf("🔥 Expected\n\t%v\nNOT to match regex\n\t%v\n", item.Extension.Name, filter.Source()) + return fmt.Sprintf("🔥 Expected\n\t%v\nNOT to match regex\n\t%v\n", + item.Extension.Name, rxFilter.Source(), + ) } // === MatchCurrentGlobFilter === // type IsCurrentGlobMatchMatcher struct { - filter interface{} + gbFilter interface{} } func MatchCurrentGlobFilter(expected interface{}) GomegaMatcher { return &IsCurrentGlobMatchMatcher{ - filter: expected, + gbFilter: expected, } } @@ -68,38 +72,42 @@ func (m *IsCurrentGlobMatchMatcher) Match(actual interface{}) (bool, error) { return false, fmt.Errorf("matcher expected a *TraverseItem (%T)", item) } - filter, filterOk := m.filter.(*refine.GlobFilter) + gbFilter, filterOk := m.gbFilter.(*filtering.Glob) if !filterOk { - return false, fmt.Errorf("matcher expected a *GlobFilter (%T)", filter) + return false, fmt.Errorf("matcher expected a *GlobFilter (%T)", gbFilter) } - return filter.IsMatch(item), nil + return gbFilter.IsMatch(item), nil } func (m *IsCurrentGlobMatchMatcher) FailureMessage(actual interface{}) string { item, _ := actual.(*core.Node) - filter, _ := m.filter.(*refine.GlobFilter) + gbFilter, _ := m.gbFilter.(*filtering.Glob) - return fmt.Sprintf("🔥 Expected\n\t%v\nto match glob\n\t%v\n", item.Extension.Name, filter.Source()) + return fmt.Sprintf("🔥 Expected\n\t%v\nto match glob\n\t%v\n", + item.Extension.Name, gbFilter.Source(), + ) } func (m *IsCurrentGlobMatchMatcher) NegatedFailureMessage(actual interface{}) string { item, _ := actual.(*core.Node) - filter, _ := m.filter.(*refine.GlobFilter) + gbFilter, _ := m.gbFilter.(*filtering.Glob) - return fmt.Sprintf("🔥 Expected\n\t%v\nNOT to match glob\n\t%v\n", item.Extension.Name, filter.Source()) + return fmt.Sprintf("🔥 Expected\n\t%v\nNOT to match glob\n\t%v\n", + item.Extension.Name, gbFilter.Source(), + ) } // === MatchCurrentExtendedGlobFilter === // type IsCurrentExtendedGlobMatchMatcher struct { - filter interface{} + egbFilter interface{} } func MatchCurrentExtendedFilter(expected interface{}) GomegaMatcher { return &IsCurrentExtendedGlobMatchMatcher{ - filter: expected, + egbFilter: expected, } } @@ -109,29 +117,29 @@ func (m *IsCurrentExtendedGlobMatchMatcher) Match(actual interface{}) (bool, err return false, fmt.Errorf("matcher expected a *TraverseItem (%T)", item) } - filter, filterOk := m.filter.(*refine.ExtendedGlobFilter) + egbFilter, filterOk := m.egbFilter.(*filtering.ExtendedGlob) if !filterOk { - return false, fmt.Errorf("matcher expected a *IncaseFilter (%T)", filter) + return false, fmt.Errorf("matcher expected a *IncaseFilter (%T)", egbFilter) } - return filter.IsMatch(item), nil + return egbFilter.IsMatch(item), nil } func (m *IsCurrentExtendedGlobMatchMatcher) FailureMessage(actual interface{}) string { item, _ := actual.(*core.Node) - filter, _ := m.filter.(*refine.ExtendedGlobFilter) + egbFilter, _ := m.egbFilter.(*filtering.ExtendedGlob) return fmt.Sprintf("🔥 Expected\n\t%v\nto match incase\n\t%v\n", - item.Extension.Name, filter.Source(), + item.Extension.Name, egbFilter.Source(), ) } func (m *IsCurrentExtendedGlobMatchMatcher) NegatedFailureMessage(actual interface{}) string { item, _ := actual.(*core.Node) - filter, _ := m.filter.(*refine.ExtendedGlobFilter) + egbFilter, _ := m.egbFilter.(*filtering.ExtendedGlob) return fmt.Sprintf("🔥 Expected\n\t%v\nNOT to match incase\n\t%v\n", - item.Extension.Name, filter.Source(), + item.Extension.Name, egbFilter.Source(), ) } @@ -139,12 +147,12 @@ func (m *IsCurrentExtendedGlobMatchMatcher) NegatedFailureMessage(actual interfa // type IsCurrentCustomMatchMatcher struct { - filter interface{} + tvFilter interface{} } func MatchCurrentCustomFilter(expected interface{}) GomegaMatcher { return &IsCurrentCustomMatchMatcher{ - filter: expected, + tvFilter: expected, } } @@ -154,28 +162,28 @@ func (m *IsCurrentCustomMatchMatcher) Match(actual interface{}) (bool, error) { return false, fmt.Errorf("matcher expected a *TraverseItem (%T)", item) } - filter, filterOk := m.filter.(core.TraverseFilter) + tvFilter, filterOk := m.tvFilter.(core.TraverseFilter) if !filterOk { - return false, fmt.Errorf("matcher expected a core.TraverseFilter (%T)", filter) + return false, fmt.Errorf("matcher expected a core.TraverseFilter (%T)", tvFilter) } - return filter.IsMatch(item), nil + return tvFilter.IsMatch(item), nil } func (m *IsCurrentCustomMatchMatcher) FailureMessage(actual interface{}) string { item, _ := actual.(*core.Node) - filter, _ := m.filter.(core.TraverseFilter) + tvFilter, _ := m.tvFilter.(core.TraverseFilter) return fmt.Sprintf("🔥 Expected\n\t%v\nto match custom filter\n\t%v\n", - item.Extension.Name, filter.Source(), + item.Extension.Name, tvFilter.Source(), ) } func (m *IsCurrentCustomMatchMatcher) NegatedFailureMessage(actual interface{}) string { item, _ := actual.(*core.Node) - filter, _ := m.filter.(core.TraverseFilter) + tvFilter, _ := m.tvFilter.(core.TraverseFilter) return fmt.Sprintf("🔥 Expected\n\t%v\nNOT to match custom filter\n\t%v\n", - item.Extension.Name, filter.Source(), + item.Extension.Name, tvFilter.Source(), ) } diff --git a/internal/kernel/kernel-suite_test.go b/internal/kernel/kernel-suite_test.go index 516d002..c75839b 100644 --- a/internal/kernel/kernel-suite_test.go +++ b/internal/kernel/kernel-suite_test.go @@ -13,7 +13,7 @@ import ( "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/cycle" "github.com/snivilised/traverse/enums" - "github.com/snivilised/traverse/internal/feat/refine" + "github.com/snivilised/traverse/internal/feat/filter" "github.com/snivilised/traverse/internal/helpers" "github.com/snivilised/traverse/internal/third/lo" "github.com/snivilised/traverse/pref" @@ -328,9 +328,9 @@ func assertMetrics(entry *naviTE, to *testOptions) { // customSamplingFilter is a custom sampling filter that just happens // to use a glob as part of its implementation. The client can of course -// define their own custom implementation using refine.SampleFilter. +// define their own custom implementation using filter.SampleFilter. type customSamplingFilter struct { - refine.SampleFilter + filter.SampleFilter description string pattern string } diff --git a/internal/kernel/navigator-filter-regex_test.go b/internal/kernel/navigator-filter-regex_test.go index c0c183e..fb0099c 100644 --- a/internal/kernel/navigator-filter-regex_test.go +++ b/internal/kernel/navigator-filter-regex_test.go @@ -17,7 +17,7 @@ import ( "github.com/snivilised/traverse/pref" ) -var _ = Describe("NavigatorFilterRegex", Ordered, func() { +var _ = Describe("filter", Ordered, func() { var ( vfs fstest.MapFS root string @@ -25,7 +25,7 @@ var _ = Describe("NavigatorFilterRegex", Ordered, func() { BeforeAll(func() { const ( - verbose = true + verbose = false ) vfs, root = helpers.Musico(verbose, @@ -39,7 +39,7 @@ var _ = Describe("NavigatorFilterRegex", Ordered, func() { services.Reset() }) - DescribeTable("regex-filter", + DescribeTable("regex", func(ctx SpecContext, entry *filterTE) { var ( traverseFilter core.TraverseFilter diff --git a/traverse-api.go b/traverse-api.go index 9ace991..bcf62da 100644 --- a/traverse-api.go +++ b/traverse-api.go @@ -5,7 +5,7 @@ import ( "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" - "github.com/snivilised/traverse/internal/feat/refine" + "github.com/snivilised/traverse/internal/feat/filter" "github.com/snivilised/traverse/nfs" "github.com/snivilised/traverse/pref" ) @@ -53,8 +53,8 @@ type ( Subscription = enums.Subscription ResumeStrategy = enums.ResumeStrategy - // 🌀 refine - BaseSampleFilter = refine.SampleFilter + // 🌀 filter + BaseSampleFilter = filter.SampleFilter // 🌀 nfs FileSystems = nfs.FileSystems @@ -87,8 +87,8 @@ var ( NewNativeFS = nfs.NewNativeFS NewQueryStatusFS = nfs.NewQueryStatusFS - // 🌀 refine - NewSampleFilter = refine.NewSampleFilter + // 🌀 filter + NewSampleFilter = filter.NewSampleFilter // 🌀 pref IfOption = pref.IfOption @@ -139,9 +139,9 @@ var ( // // 🔆 feature layer // resume: ["pref"] -// sampling: ["refine"] -// hiber: ["refine", "services"] -// refine: [] +// sampling: ["filter"] +// hiber: ["filter", "services"] +// filter: [] // // 🔆 central layer // kernel: []