Skip to content

Commit

Permalink
feat(pref): add more with operators (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
plastikfan committed Sep 12, 2024
1 parent 83f023c commit 3ee9172
Show file tree
Hide file tree
Showing 16 changed files with 449 additions and 79 deletions.
1 change: 1 addition & 0 deletions core/hibernate.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type (
InclusiveSleep bool
}

// HibernateOptions
HibernateOptions struct {
// WakeAt defines a filter for hibernation wake condition
WakeAt *FilterDef
Expand Down
2 changes: 1 addition & 1 deletion director-resume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ var _ = Describe("Director(Resume)", Ordered, func() {
From: RestorePath,
Strategy: tv.ResumeStrategySpawn,
},
tv.WithSampling(&pref.SamplingOptions{
tv.WithSamplingOptions(&pref.SamplingOptions{
NoOf: pref.EntryQuantities{
Files: files,
Folders: folders,
Expand Down
4 changes: 2 additions & 2 deletions internal/feat/sampling/navigator-sample_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ var _ = Describe("feature", Ordered, func() {
return FS
},
},
tv.WithSampling(&pref.SamplingOptions{
tv.WithSamplingOptions(&pref.SamplingOptions{
SampleType: enums.SampleTypeSlice,
NoOf: pref.EntryQuantities{
Files: 2,
Expand Down Expand Up @@ -134,7 +134,7 @@ var _ = Describe("feature", Ordered, func() {
return FS
},
},
tv.WithSampling(&pref.SamplingOptions{
tv.WithSamplingOptions(&pref.SamplingOptions{
SampleType: entry.SampleType,
SampleInReverse: entry.Reverse,
NoOf: pref.EntryQuantities{
Expand Down
3 changes: 3 additions & 0 deletions nfs/file-systems.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type nativeFS struct {
fsys fs.FS
}

// NewNativeFS creates a native file system.
func NewNativeFS(path string) fs.ReadDirFS {
return &nativeFS{
fsys: os.DirFS(path),
Expand All @@ -27,6 +28,8 @@ type queryStatusFS struct {
fsys fs.FS
}

// NewQueryStatusFS defines a file system that has a Stat
// method to determine the existence of a path.
func NewQueryStatusFS(fsys fs.FS) fs.StatFS {
return &queryStatusFS{
fsys: fsys,
Expand Down
19 changes: 0 additions & 19 deletions pref/binder.go

This file was deleted.

15 changes: 14 additions & 1 deletion pref/defects.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ type (

Rescuer func()

// FaultHandler
// FaultHandler is called to handle an error that occurs when Stating
// the root folder. When an error occurs, traversal terminates
// immediately. The handler specified allows custom functionality
// when an error occurs here.
FaultHandler interface {
Accept(fault *NavigationFault) error
}
Expand All @@ -42,6 +45,7 @@ type (
err error,
) (enums.SkipTraversal, error)

// DefectOptions
DefectOptions struct {
Fault FaultHandler
Panic PanicHandler
Expand All @@ -61,6 +65,10 @@ func (fn Asker) Ask(current *core.Node, contents core.DirectoryContents, err err
return fn(current, contents, err)
}

// WithFaultHandler defines a custom handler to handle an error that occurs
// when Stating the root folder. When an error occurs, traversal terminates
// immediately. The handler specified allows custom functionality to be invoked
// when an error occurs here.
func WithFaultHandler(handler FaultHandler) Option {
return func(o *Options) error {
o.Defects.Fault = handler
Expand All @@ -69,6 +77,7 @@ func WithFaultHandler(handler FaultHandler) Option {
}
}

// WithPanicHandler defines a custom handler to handle a panic.
func WithPanicHandler(handler PanicHandler) Option {
return func(o *Options) error {
o.Defects.Panic = handler
Expand All @@ -77,6 +86,10 @@ func WithPanicHandler(handler PanicHandler) Option {
}
}

// WithSkipHandler defines a handler that will be invoked if the
// client callback returns an error during traversal. The client
// can control if traversal is either terminated early (fs.SkipAll)
// or the remaining items in a directory are skipped (fs.SkipDir).
func WithSkipHandler(handler SkipHandler) Option {
return func(o *Options) error {
o.Defects.Skip = handler
Expand Down
10 changes: 10 additions & 0 deletions pref/options-concurrency.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ import (
"runtime"
)

// ConcurrencyOptions specifies options used for current traversal sessions
type ConcurrencyOptions struct {
// NoW specifies the number of go-routines to use in the worker
// pool used for concurrent traversal sessions requested by using
// the Run function.
NoW uint
}

// WithCPU configures the worker pool used for concurrent traversal sessions
// in the Run function to utilise a number of go-routines equal to the available
// CPU count, optimising performance based on the system's processing capabilities.
func WithCPU() Option {
return func(o *Options) error {
o.Concurrency.NoW = uint(runtime.NumCPU())
Expand All @@ -16,6 +23,9 @@ func WithCPU() Option {
}
}

// WithNoW sets the number of go-routines to use in the worker
// pool used for concurrent traversal sessions requested by using
// the Run function.
func WithNoW(now uint) Option {
return func(o *Options) error {
o.Concurrency.NoW = now
Expand Down
3 changes: 3 additions & 0 deletions pref/options-filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type (
}
)

// WithFilter used to determine which file system nodes (files or folders)
// the client defined handler is invoked for. Note that the filter does not
// determine navigation, it only determines wether the callback is invoked.
func WithFilter(filter *FilterOptions) Option {
return func(o *Options) error {
o.Filter = *filter
Expand Down
12 changes: 12 additions & 0 deletions pref/options-hibernate.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"github.com/snivilised/traverse/core"
)

// WithHibernationBehaviourExclusiveWake activates hibernation
// with a wake condition. The wake condition should be defined
// using WithHibernationFilterWake.
func WithHibernationBehaviourExclusiveWake() Option {
return func(o *Options) error {
o.Hibernate.Behaviour.InclusiveWake = false
Expand All @@ -12,13 +15,18 @@ func WithHibernationBehaviourExclusiveWake() Option {
}
}

// WithHibernationBehaviourInclusiveSleep activates hibernation
// with a sleep condition. The sleep condition should be defined
// using WithHibernationFilterSleep.
func WithHibernationBehaviourInclusiveSleep() Option {
return func(o *Options) error {
o.Hibernate.Behaviour.InclusiveSleep = true
return nil
}
}

// WithHibernationFilterWake defines the wake condition
// for hibernation based traversal sessions.
func WithHibernationFilterWake(wake *core.FilterDef) Option {
return func(o *Options) error {
o.Hibernate.WakeAt = wake
Expand All @@ -27,6 +35,8 @@ func WithHibernationFilterWake(wake *core.FilterDef) Option {
}
}

// WithHibernationFilterSleep defines the sleep condition
// for hibernation based traversal sessions.
func WithHibernationFilterSleep(sleep *core.FilterDef) Option {
return func(o *Options) error {
o.Hibernate.SleepAt = sleep
Expand All @@ -35,6 +45,8 @@ func WithHibernationFilterSleep(sleep *core.FilterDef) Option {
}
}

// WithHibernationOptions defines options for a hibernation traversal
// session.
func WithHibernationOptions(ho *core.HibernateOptions) Option {
return func(o *Options) error {
o.Hibernate = *ho
Expand Down
36 changes: 24 additions & 12 deletions pref/options-hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,61 @@ import (
"github.com/snivilised/traverse/core"
)

func WithHookQueryStatus(hook core.QueryStatusHook) Option {
// WithHookCaseSensitiveSort specifies that a folder's contents
// should be sorted with case sensitivity.
func WithHookCaseSensitiveSort() Option {
return func(o *Options) error {
o.Hooks.QueryStatus.Tap(hook)
o.Hooks.Sort.Tap(CaseSensitiveSortHook)

return nil
}
}

func WithHookReadDirectory(hook core.ReadDirectoryHook) Option {
// WithHookFileSubPath defines an custom hook to override the
// default behaviour for obtaining the sub-path of a file.
func WithHookFileSubPath(hook core.SubPathHook) Option {
return func(o *Options) error {
o.Hooks.ReadDirectory.Tap(hook)
o.Hooks.FileSubPath.Tap(hook)

return nil
}
}

func WithHookCaseSensitiveSort() Option {
// WithHookFolderSubPath defines an custom hook to override the
// default behaviour for obtaining the sub-path of a folder.
func WithHookFolderSubPath(hook core.SubPathHook) Option {
return func(o *Options) error {
o.Hooks.Sort.Tap(CaseSensitiveSortHook)
o.Hooks.FolderSubPath.Tap(hook)

return nil
}
}

func WithHookSort(hook core.SortHook) Option {
// WithHookQueryStatus defines an custom hook to override the
// default behaviour for Stating a folder.
func WithHookQueryStatus(hook core.QueryStatusHook) Option {
return func(o *Options) error {
o.Hooks.Sort.Tap(hook)
o.Hooks.QueryStatus.Tap(hook)

return nil
}
}

func WithHookFileSubPath(hook core.SubPathHook) Option {
// WithHookReadDirectory defines an custom hook to override the
// default behaviour for reading a folder's contents.
func WithHookReadDirectory(hook core.ReadDirectoryHook) Option {
return func(o *Options) error {
o.Hooks.FileSubPath.Tap(hook)
o.Hooks.ReadDirectory.Tap(hook)

return nil
}
}

func WithHookFolderSubPath(hook core.SubPathHook) Option {
// WithHookSort defines an custom hook to override the
// default behaviour for sorting a folder's contents.
func WithHookSort(hook core.SortHook) Option {
return func(o *Options) error {
o.Hooks.FolderSubPath.Tap(hook)
o.Hooks.Sort.Tap(hook)

return nil
}
Expand Down
1 change: 1 addition & 0 deletions pref/options-log.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type (
}
)

// WithLogger defines a structure logger
func WithLogger(logger *slog.Logger) Option {
return func(o *Options) error {
o.Monitor.Log = logger
Expand Down
6 changes: 6 additions & 0 deletions pref/options-navigation-behaviours.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type (
}
)

// WithNavigationBehaviours defines all navigation behaviours
func WithNavigationBehaviours(nb *NavigationBehaviours) Option {
return func(o *Options) error {
o.Behaviours = *nb
Expand All @@ -62,6 +63,7 @@ func WithNavigationBehaviours(nb *NavigationBehaviours) Option {
}
}

// WithSubPathBehaviour defines all sub-path behaviours.
func WithSubPathBehaviour(sb *SubPathBehaviour) Option {
return func(o *Options) error {
o.Behaviours.SubPath = *sb
Expand All @@ -70,6 +72,7 @@ func WithSubPathBehaviour(sb *SubPathBehaviour) Option {
}
}

// WithSortBehaviour enabling setting of all sorting behaviours.
func WithSortBehaviour(sb *SortBehaviour) Option {
return func(o *Options) error {
o.Behaviours.Sort = *sb
Expand All @@ -78,6 +81,8 @@ func WithSortBehaviour(sb *SortBehaviour) Option {
}
}

// WithDepth sets the maximum number of folders deep the navigator
// will traverse to.
func WithDepth(depth uint) Option {
return func(o *Options) error {
o.Behaviours.Cascade.Depth = depth
Expand All @@ -86,6 +91,7 @@ func WithDepth(depth uint) Option {
}
}

// WithNoRecurse sets the navigator to not descend sub-directories.
func WithNoRecurse() Option {
return func(o *Options) error {
o.Behaviours.Cascade.NoRecurse = true
Expand Down
25 changes: 14 additions & 11 deletions pref/options-sampling.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type (
Folders uint
}

// SamplingIterationOptions
SamplingIterationOptions struct {
// Each enables customisation of the sampling functionality, instead of using
// the defined filter. A directory's contents is sampled according to this
Expand Down Expand Up @@ -73,23 +74,25 @@ type (
Counts EntryQuantities
Enough EnoughAlready
}

// SamplerOptions struct {
// // Iteration allows the client to customise how a directory's contents are sampled.
// // The default way to sample is either by slicing the directory's contents or
// // by using the filter to select either the first/last n entries (using the
// // SamplingOptions). If the client requires an alternative way of creating a
// // sample, eg to take all files greater than a certain size, then this
// // can be achieved by specifying Each and While inside Iteration.
// Iteration SamplingIterationOptions
// }
)

func (o SamplingOptions) IsSamplingActive() bool {
return o.SampleType != enums.SampleTypeUndefined
}

func WithSampling(so *SamplingOptions) Option {
// WithSamplingOptions specifies the sampling options.
// SampleType: the type of sampling to use
// SampleInReverse: determines the direction of iteration for the sampling
// operation
// NoOf: specifies number of items required in each sample (only applies
// when not using Custom iterator options)
// Iteration: allows the client to customise how a directory's contents are sampled.
// The default way to sample is either by slicing the directory's contents or
// by using the filter to select either the first/last n entries (using the
// SamplingOptions). If the client requires an alternative way of creating a
// sample, eg to take all files greater than a certain size, then this
// can be achieved by specifying Each and While inside Iteration.
func WithSamplingOptions(so *SamplingOptions) Option {
return func(o *Options) error {
o.Sampling = *so

Expand Down
15 changes: 15 additions & 0 deletions pref/pref-suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,24 @@ import (

. "github.com/onsi/ginkgo/v2" //nolint:revive // ok
. "github.com/onsi/gomega" //nolint:revive // ok
"github.com/snivilised/traverse/core"
"github.com/snivilised/traverse/enums"
"github.com/snivilised/traverse/pref"
)

func TestPref(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Pref Suite")
}

type (
testFaultHandler struct{}
testPanicHandler struct{}
testSkipHandler struct{}
)

func (*testFaultHandler) Accept(*pref.NavigationFault) error { return nil }
func (*testPanicHandler) Rescue() {}
func (*testSkipHandler) Ask(*core.Node, core.DirectoryContents, error) (enums.SkipTraversal, error) {
return enums.SkipAllTraversal, nil
}
Loading

0 comments on commit 3ee9172

Please sign in to comment.