Skip to content

Commit

Permalink
feat(opts): marshal options (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
plastikfan committed Oct 1, 2024
1 parent f743ed9 commit 1cb60d5
Show file tree
Hide file tree
Showing 19 changed files with 1,088 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ report.json
coverage.html

.task/
test/json/marshal/

i18n/out/en-US/active.en-GB.json

Expand Down
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"dogsled",
"dotenv",
"dupl",
"ejson",
"ents",
"Ephidrina",
"errcheck",
Expand Down Expand Up @@ -59,7 +60,9 @@
"icase",
"ineffassign",
"Innerworld",
"jdef",
"jibberjabber",
"jroot",
"Kontroller",
"leaktest",
"linecomment",
Expand Down Expand Up @@ -113,6 +116,7 @@
"typecheck",
"unconvert",
"unlambda",
"Unmarshall",
"unparam",
"usys",
"vals",
Expand Down
4 changes: 4 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ tasks:
cmds:
- go test ./pref

tpf:
cmds:
- go test ./internal/persist

tt:
cmds:
- go test
Expand Down
2 changes: 1 addition & 1 deletion director.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func Prime(using *pref.Using, settings ...pref.Option) *Builders {
ve := using.Validate()

if using.O != nil {
return using.O, opts.GetWith(using.O), ve
return using.O, opts.Push(using.O), ve
}

o, binder, err := ext.options(settings...)
Expand Down
2 changes: 1 addition & 1 deletion internal/opts/get.go → internal/opts/get-push.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func apply(o *pref.Options, settings ...pref.Option) (err error) {
return err
}

func GetWith(o *pref.Options) *Binder {
func Push(o *pref.Options) *Binder {
binder := NewBinder()
o.Events.Bind(&binder.Controls)

Expand Down
15 changes: 15 additions & 0 deletions internal/opts/json/concurrency-options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package json

// TODO: can't have package name that is json as that clashes
// with the one in standard library at encoding/json, so need
// to rename; perhaps to js.

type (
// ConcurrencyOptions specifies options used for current traversal sessions
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 `json:"no-of-workers"`
}
)
94 changes: 94 additions & 0 deletions internal/opts/json/filter-options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package json

import (
"github.com/snivilised/traverse/enums"
)

type (
PolyFilterDef struct {
File FilterDef
Folder FilterDef
}

FilterDef struct {
// Type specifies the type of filter (mandatory)
Type enums.FilterType `json:"filter-type"`

// Description describes filter (optional)
Description string `json:"filter-description"`

// Pattern filter definition (mandatory)
Pattern string `json:"pattern"`

// Scope which file system entries this filter applies to (defaults
// to ScopeAllEn)
Scope enums.FilterScope `json:"filter-scope"`

// Negate, reverses the applicability of the filter (Defaults to false)
Negate bool `json:"negate"`

// IfNotApplicable, when the filter does not apply to a directory entry,
// this value determines whether the callback is invoked for this entry
// or not (defaults to true).
IfNotApplicable enums.TriStateBool `json:"if-not-applicable"`

// Poly allows for the definition of a PolyFilter which contains separate
// filters that target files and folders separately. If present, then
// all other fields are redundant, since the filter definitions inside
// Poly should be referred to instead.
Poly *PolyFilterDef
}

ChildFilterDef struct {
// Type specifies the type of filter (mandatory)
Type enums.FilterType `json:"child-filter-type"`

// Description describes filter (optional)
Description string `json:"child-filter-description"`

// Pattern filter definition (mandatory)
Pattern string `json:"child-pattern"`

// Negate, reverses the applicability of the filter (Defaults to false)
Negate bool `json:"negate"`
}

SampleFilterDef struct {
// Type specifies the type of filter (mandatory)
Type enums.FilterType `json:"sample-filter-type"`

// Description describes filter (optional)
Description string `json:"sample-description"`

// Pattern filter definition (mandatory except if using Custom)
Pattern string `json:"sample-filter"`

// Scope which file system entries this filter applies to;
// for sampling, only ScopeFile and ScopeFolder are valid.
Scope enums.FilterScope `json:"sample-filter-scope"`

// Negate, reverses the applicability of the filter (Defaults to false)
Negate bool `json:"negate"`

// Poly allows for the definition of a PolyFilter which contains separate
// filters that target files and folders separately. If present, then
// all other fields are redundant, since the filter definitions inside
// Poly should be referred to instead.
Poly *PolyFilterDef
}

FilterOptions struct {
// Node filter definitions that applies to the current file system node
//
Node *FilterDef

// Child denotes the Child filter that is applied to the files which
// are direct descendants of the current directory node being visited.
//
Child *ChildFilterDef

// Sample is the filter used for sampling
//
Sample *SampleFilterDef
}
)
34 changes: 34 additions & 0 deletions internal/opts/json/hibernate-options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package json

import "fmt"

type (
// HibernationBehaviour
HibernationBehaviour struct {
// InclusiveWake when wake occurs, permit client callback to
// be invoked for the current node. Inclusive, true by default
InclusiveWake bool `json:"hibernate-inclusive-wake"`

// InclusiveSleep when sleep occurs, permit client callback to
// be invoked for the current node. Exclusive, false by default.
InclusiveSleep bool `json:"hibernate-inclusive-sleep"`
}

// HibernateOptions
HibernateOptions struct {
// WakeAt defines a filter for hibernation wake condition
WakeAt *FilterDef

// SleepAt defines a filter for hibernation sleep condition
SleepAt *FilterDef

// Behaviour contains hibernation behavioural aspects
Behaviour HibernationBehaviour
}
)

func (b *HibernationBehaviour) String() string {
return fmt.Sprintf("[HibernationBehaviour] inclusive wake: %v, inclusive sleep: %v",
b.InclusiveWake, b.InclusiveSleep,
)
}
47 changes: 47 additions & 0 deletions internal/opts/json/navigation-behaviours.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package json

type (
SubPathBehaviour struct {
KeepTrailingSep bool
}

SortBehaviour struct {
// case sensitive traversal order
//
IsCaseSensitive bool

// SortFilesFirst defines whether a folder's files or directories
// should be navigated first.
//
SortFilesFirst bool
}

CascadeBehaviour struct {
// Depth sets a maximum traversal depth
//
Depth uint

// NoRecurse is an alternative to using Depth, but limits the traversal
// to just the path specified by the user. Since the raison d'etre
// of the navigator is to recursively process a directory tree, using
// NoRecurse would appear to be contrary to its natural behaviour. However
// there are clear usage scenarios where a client needs to process
// only the files in a specified directory.
//
NoRecurse bool
}

NavigationBehaviours struct {
// SubPath, behaviours relating to handling of sub-path calculation
//
SubPath SubPathBehaviour

// Sort, behaviours relating to sorting of a folder's directory entries.
//
Sort SortBehaviour

// Cascade controls how deep to navigate
//
Cascade CascadeBehaviour
}
)
22 changes: 22 additions & 0 deletions internal/opts/json/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package json

type (
// Options defines the JSON persist format for options.
Options struct {
// Behaviours collection of behaviours that adjust the way navigation occurs,
// that can be tweaked by the client.
Behaviours NavigationBehaviours

// Sampling options
Sampling SamplingOptions

// Filter
Filter FilterOptions

// Hibernation
Hibernate HibernateOptions

// Concurrency contains options relating concurrency
Concurrency ConcurrencyOptions
}
)
28 changes: 28 additions & 0 deletions internal/opts/json/sampling-options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package json

import (
"github.com/snivilised/traverse/enums"
)

type (
// EntryQuantities contains specification of no of files and folders
// used in various contexts, but primarily sampling.
EntryQuantities struct {
Files uint `json:"no-of-files"`
Folders uint `json:"no-of-folders"`
}

// SamplingOptions
SamplingOptions struct {
// SampleType the type of sampling to use
SampleType enums.SampleType `json:"sample-type"`

// SampleInReverse determines the direction of iteration for the sampling
// operation
SampleInReverse bool `json:"sample-in-reverse"`

// NoOf specifies number of items required in each sample (only applies
// when not using Custom iterator options)
NoOf EntryQuantities
}
)
27 changes: 27 additions & 0 deletions internal/persist/convert-json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package persist_test

import (
. "github.com/onsi/ginkgo/v2" //nolint:revive // ok
. "github.com/onsi/gomega" //nolint:revive // ok
"github.com/snivilised/traverse/internal/opts"
"github.com/snivilised/traverse/internal/persist"
"github.com/snivilised/traverse/pref"
)

var _ = Describe("Convert JSON", func() {
Context("ToJSON", func() {
Context("given: source Options instance", func() {
It("should: convert to JSON", func() {
o, _, err := opts.Get(
pref.WithDepth(4),
)
Expect(err).To(Succeed())
jo := persist.ToJSON(o)
Expect(jo).ToNot(BeNil())
equal, err := persist.Equal(o, jo)
Expect(err).To(Succeed())
Expect(equal).To(BeTrue())
})
})
})
})
Loading

0 comments on commit 1cb60d5

Please sign in to comment.