Documentation
¶
Overview ¶
Package jsonmatch provides support for extracting values, mutating or deleting data using the jsonpath2 syntax.
Index ¶
- type ArrayRef
- func (r *ArrayRef) Delete() error
- func (r *ArrayRef) Depth() int
- func (r *ArrayRef) EstimateSize() int
- func (r *ArrayRef) GetPath() string
- func (r *ArrayRef) IsEmpty() bool
- func (r *ArrayRef) Merge(ref Ref) (Ref, bool)
- func (r *ArrayRef) Mutate(mutator MutatorFunc) error
- func (r *ArrayRef) MutateRegions(mutator MutateRegionsFunc) error
- func (r *ArrayRef) Set(value interface{}) error
- func (r *ArrayRef) Union(refs ...Ref) Ref
- func (r *ArrayRef) Values() []interface{}
- func (r *ArrayRef) Vars() []*VarRef
- type Expression
- type ForEachIndexFunc
- type LatentMapRef
- func (r *LatentMapRef) AddKey(key string)
- func (r *LatentMapRef) Delete() error
- func (r *LatentMapRef) Depth() int
- func (r *LatentMapRef) EstimateSize() int
- func (r *LatentMapRef) IsEmpty() bool
- func (r *LatentMapRef) Merge(ref Ref) (Ref, bool)
- func (r *LatentMapRef) Mutate(mutator MutatorFunc) error
- func (r *LatentMapRef) Set(value interface{}) error
- func (r *LatentMapRef) SetWithMatchedType(value interface{}) error
- func (r *LatentMapRef) Union(refs ...Ref) Ref
- func (r *LatentMapRef) Values() []interface{}
- func (r *LatentMapRef) Vars() []*VarRef
- type LiteralRef
- func (r *LiteralRef) CanonicalValue() interface{}
- func (r *LiteralRef) Delete() error
- func (r *LiteralRef) Depth() int
- func (r *LiteralRef) EstimateSize() int
- func (r *LiteralRef) IsEmpty() bool
- func (r *LiteralRef) Merge(ref Ref) (Ref, bool)
- func (r *LiteralRef) Mutate(mutator MutatorFunc) error
- func (r *LiteralRef) Set(value interface{}) error
- func (r *LiteralRef) SetWithMatchedType(value interface{}) error
- func (r *LiteralRef) Union(refs ...Ref) Ref
- func (r *LiteralRef) Value() interface{}
- func (r *LiteralRef) Values() []interface{}
- func (r *LiteralRef) Vars() []*VarRef
- type MapRef
- func (r *MapRef) Delete() error
- func (r *MapRef) Depth() int
- func (r *MapRef) EstimateSize() int
- func (r *MapRef) GetLatentMapRef() *LatentMapRef
- func (r *MapRef) GetPath() string
- func (r *MapRef) IsEmpty() bool
- func (r *MapRef) Merge(ref Ref) (Ref, bool)
- func (r *MapRef) Mutate(mutator MutatorFunc) error
- func (r *MapRef) Set(value interface{}) error
- func (r *MapRef) Union(refs ...Ref) Ref
- func (r *MapRef) Values() []interface{}
- func (r *MapRef) Vars() []*VarRef
- type MatchSet
- func (e *MatchSet) Delete() (interface{}, error)
- func (e *MatchSet) Mutate(mutator MutatorFunc) (interface{}, error)
- func (e *MatchSet) MutateRegions(mutator MutateRegionsFunc) (interface{}, error)
- func (e *MatchSet) Set(value interface{}) (interface{}, error)
- func (e *MatchSet) Values() []interface{}
- type MutateRegionsFunc
- type MutatorFunc
- type ParseError
- type Parser
- type PathedRef
- type Ref
- type Region
- func (r Region) Adjacent(other Region) bool
- func (r Region) Clone() Region
- func (r Region) ContainsIndex(index int) bool
- func (r Region) ContainsRegion(other Region) bool
- func (r Region) Cut(other Region) Region
- func (r Region) Empty() bool
- func (r Region) Equal(other Region) bool
- func (r Region) Grow(count int) Region
- func (r Region) Intersect(other Region) Regions
- func (r Region) IsAfter(index int) bool
- func (r Region) IsBefore(index int) bool
- func (r Region) Join(other Region) Region
- func (r Region) Len() int
- func (r Region) Overlap(other Region) bool
- func (r Region) OverlapOrAdjacent(other Region) bool
- func (r Region) Shift(diff int) Region
- func (r Region) Shrink(count int) Region
- type Regions
- func (rs Regions) Check() bool
- func (rs Regions) CheckSorted() bool
- func (rs Regions) Clean() Regions
- func (rs Regions) Compact() Regions
- func (rs Regions) ContainsIndex(i int) bool
- func (rs Regions) Cut(other Region) Regions
- func (rs Regions) ExtractItems(source []interface{}) [][]interface{}
- func (rs Regions) ForEachIndex(callback ForEachIndexFunc) error
- func (rs Regions) IndiciesCount() int
- func (rs Regions) InsertAt(other Region) Regions
- func (rs Regions) Intersect(other Regions) Regions
- func (rs Regions) Len() int
- func (rs Regions) Less(i, j int) bool
- func (rs Regions) MergeItems(source []interface{}, replace [][]interface{}) ([]interface{}, Regions)
- func (rs Regions) Simplify() Regions
- func (rs Regions) Sort() Regions
- func (rs Regions) Swap(i, j int)
- func (rs Regions) ToIndicies() []int
- func (rs Regions) ToSliceSelector() string
- func (rs Regions) Union(otherRegions Regions) Regions
- type Scanner
- type Token
- type UnionRef
- func (r *UnionRef) Delete() error
- func (r *UnionRef) Depth() int
- func (r *UnionRef) EstimateSize() int
- func (r *UnionRef) IsEmpty() bool
- func (r *UnionRef) Len() int
- func (r *UnionRef) Less(i, j int) bool
- func (r *UnionRef) Merge(ref Ref) (Ref, bool)
- func (r *UnionRef) Mutate(mutator MutatorFunc) error
- func (r *UnionRef) Set(value interface{}) error
- func (r *UnionRef) Swap(i, j int)
- func (r *UnionRef) Union(refs ...Ref) Ref
- func (r *UnionRef) Values() []interface{}
- func (r *UnionRef) Vars() []*VarRef
- type VarGetter
- type VarRef
- func (r *VarRef) CanonicalValue() interface{}
- func (r *VarRef) Delete() error
- func (r *VarRef) Depth() int
- func (r *VarRef) EstimateSize() int
- func (r *VarRef) GetPath() string
- func (r *VarRef) Index() int
- func (r *VarRef) IsContainer() bool
- func (r *VarRef) IsEmpty() bool
- func (r *VarRef) IsMap() bool
- func (r *VarRef) IsSlice() bool
- func (r *VarRef) Key() string
- func (r *VarRef) Merge(ref Ref) (Ref, bool)
- func (r *VarRef) Mutate(mutator MutatorFunc) error
- func (r *VarRef) Set(value interface{}) error
- func (r *VarRef) SetWithMatchedType(value interface{}) error
- func (r *VarRef) TypeKind() reflect.Kind
- func (r *VarRef) Union(refs ...Ref) Ref
- func (r *VarRef) Value() interface{}
- func (r *VarRef) Values() []interface{}
- func (r *VarRef) Vars() []*VarRef
- type VarSetter
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArrayRef ¶
type ArrayRef struct {
// contains filtered or unexported fields
}
ArrayRef is a ref to a subset of a slice
func NewArrayRef ¶
NewArrayRef creates a new ArrayRef
func (*ArrayRef) EstimateSize ¶
EstimateSize implements the Ref.EstimateSize method
func (*ArrayRef) Mutate ¶
func (r *ArrayRef) Mutate(mutator MutatorFunc) error
Mutate implements the Ref.Mutate method
func (*ArrayRef) MutateRegions ¶
func (r *ArrayRef) MutateRegions(mutator MutateRegionsFunc) error
MutateRegions lets you mutate the parts of an array as a whole. The mutator gets an array of arrays corresponding to all contiguous items selected. It returns an array of arrays where each sub array will be substituted for each corresponding region in the source. The length of each region may change as required and the length of the result will be adjusted accordingly. Also the selected indicies of the ArrayRef are updated to reflect the new positions so this method may be combined with other mutations afterwards.
type Expression ¶
type Expression struct {
// contains filtered or unexported fields
}
Expression represents a compiled JSONpath epxression
func MustParse ¶
func MustParse(src string) *Expression
MustParse parses a JSONPath expression, and panics on failure.
func Parse ¶
func Parse(src string) (*Expression, error)
Parse the provided string returning its compiled representation
func (*Expression) MarshalJSON ¶
func (n *Expression) MarshalJSON() ([]byte, error)
func (*Expression) Match ¶
func (expr *Expression) Match(data interface{}) (*MatchSet, error)
Match runs the jsonmatch query on the data and returns a MatchSet referencing all matches
type ForEachIndexFunc ¶
ForEachIndexFunc is the type of the callback provided to ForEachIndex. The callback must return true as long as it wants the process to continue. If an error is returned, ForEachIndex returns with the error. When there are no more indicies, the process is of course terminated regardless.
type LatentMapRef ¶
type LatentMapRef struct {
// contains filtered or unexported fields
}
LatentMapRef is a reference to a keypath in a map that do not exist yet Given an object like {a: {}} and you match using the jsonmatch "a.b.c", the void map ref will refer to `a.b` as the root, (since b is a key) in a map that exists, but `c` has nowhere to go so a void map ref is formed in case the client wants to set that value. In that case the necessary maps will be created to realize the path. Every root ref in a VoidMapRef must be a MapRef. The LatentMapRef will report referring to absolutely no values, so cannot be mutated, only Set.
func NewLatentMapRef ¶
func NewLatentMapRef(rootRef Ref, keyPath []string) *LatentMapRef
NewLatentMapRef returns a new *LatentMapRef
func (*LatentMapRef) AddKey ¶
func (r *LatentMapRef) AddKey(key string)
AddKey adds a key to the keypath of the LatentMapRef
func (*LatentMapRef) Delete ¶
func (r *LatentMapRef) Delete() error
Delete is a noop for LatentMapRef
func (*LatentMapRef) Depth ¶
func (r *LatentMapRef) Depth() int
Depth returns the depth of the variable. Since a Set for this should always execute first, it pretends to be veeery deep.
func (*LatentMapRef) EstimateSize ¶
func (r *LatentMapRef) EstimateSize() int
EstimateSize is always 0 for LatentMapRefs
func (*LatentMapRef) IsEmpty ¶
func (r *LatentMapRef) IsEmpty() bool
IsEmpty is always true for a LatentMapRef
func (*LatentMapRef) Merge ¶
func (r *LatentMapRef) Merge(ref Ref) (Ref, bool)
Merge only merges with itself
func (*LatentMapRef) Mutate ¶
func (r *LatentMapRef) Mutate(mutator MutatorFunc) error
Mutate mutates values that by definition is non existant. The mutator will recieve the initial value nil
func (*LatentMapRef) Set ¶
func (r *LatentMapRef) Set(value interface{}) error
Set sets the value of the contained variable
func (*LatentMapRef) SetWithMatchedType ¶
func (r *LatentMapRef) SetWithMatchedType(value interface{}) error
SetWithMatchedType updates the value, but attempts to avoid changing the underlying type if the new value is one of the canonical types
func (*LatentMapRef) Values ¶
func (r *LatentMapRef) Values() []interface{}
Values gets the value wrapped in an array for compatibility
func (*LatentMapRef) Vars ¶
func (r *LatentMapRef) Vars() []*VarRef
Vars gets this VarRef wrapped in an array for your iteration convenience
type LiteralRef ¶
type LiteralRef struct {
// contains filtered or unexported fields
}
LiteralRef is not a Ref at all, but just a container for a literal value
func (*LiteralRef) CanonicalValue ¶
func (r *LiteralRef) CanonicalValue() interface{}
CanonicalValue gets the current value of the variable converted to canonical type
func (*LiteralRef) EstimateSize ¶
func (r *LiteralRef) EstimateSize() int
EstimateSize is always 1 for VarRefs
func (*LiteralRef) Merge ¶
func (r *LiteralRef) Merge(ref Ref) (Ref, bool)
Merge only "merges" two identical VarRefs
func (*LiteralRef) Set ¶
func (r *LiteralRef) Set(value interface{}) error
Set sets the value of the contained variable
func (*LiteralRef) SetWithMatchedType ¶
func (r *LiteralRef) SetWithMatchedType(value interface{}) error
SetWithMatchedType updates the value, but attempts to avoid changing the underlying type if the new value is one of the canonical types
func (*LiteralRef) Union ¶
func (r *LiteralRef) Union(refs ...Ref) Ref
Union creates a union with the VarRef
func (*LiteralRef) Value ¶
func (r *LiteralRef) Value() interface{}
Value gets the current value of the variable in original underlying type
func (*LiteralRef) Values ¶
func (r *LiteralRef) Values() []interface{}
Values gets the value wrapped in an array for compatibility
func (*LiteralRef) Vars ¶
func (r *LiteralRef) Vars() []*VarRef
Vars gets this VarRef wrapped in an array for your iteration convenience
type MapRef ¶
type MapRef struct {
// contains filtered or unexported fields
}
MapRef is a ref to a subset of a map type where the keys are strings
func (*MapRef) EstimateSize ¶
EstimateSize implements the Ref.EstimateSize method
func (*MapRef) GetLatentMapRef ¶
func (r *MapRef) GetLatentMapRef() *LatentMapRef
GetLatentMapRef generates a latent map ref for any keys that are missing or not Maps in the underlying value. If no such values, nil is returned
func (*MapRef) Mutate ¶
func (r *MapRef) Mutate(mutator MutatorFunc) error
Mutate implements the Ref.Mutate method
type MatchSet ¶
type MatchSet struct {
// contains filtered or unexported fields
}
MatchSet represents one jsonmatch extract and provides functions for mutating or extracting the matched values. Setting selected values can be done until you have performed a mutation. You can only perform exactly one mutation.
func (*MatchSet) Mutate ¶
func (e *MatchSet) Mutate(mutator MutatorFunc) (interface{}, error)
Mutate passes all selected values through the mutator and updates them in the underlying value
func (*MatchSet) MutateRegions ¶
func (e *MatchSet) MutateRegions(mutator MutateRegionsFunc) (interface{}, error)
MutateRegions mutates the elements of each selected array as single operations. The original valuas are provided as an array of arrays, and returns an array of arrays of the same shape. Each sub-array is substituted for its corresponding original, and it is okay if the length of these sub arrays differ. The result is grown or shrunk accordingly. Main use case is to support slice-style operations like append, replace etc. If the method is used on selections that also include non-array members, an error is returned.
type MutateRegionsFunc ¶
MutateRegionsFunc is the signature for the callbacks provided to the ArrayRef.MutateAll methods that allow a selection of an array to be mutated as a whole. The selection is provided as an array of arrays (since selections might not be contiguous). Each sub-array representing a contiguous block of selected items. These may be modified directly by the mutator, or replaced with new ones.
type MutatorFunc ¶
MutatorFunc is the signature for the callbacks provided to the Ref.Mutate methods
type ParseError ¶
ParseError describes an error in the parse and contains the position of the problem along with the message.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser represents a JSONpath parser
type PathedRef ¶
type PathedRef interface {
GetPath() string
}
PathedRef is an interface for refs that have a definitive, resolvable paths, which is effectively Array and Map ref
type Ref ¶
type Ref interface { // Values returns the value of all referenced variables in their original form Values() []interface{} // Vars returns VarRefs for all the referenced variable Vars() []*VarRef // Delete deletes the values from the referenced variables if possible (basically maps and arrays). If // the refs cannot be deleted (structs or primitive variables) theres an error Delete() error // Mutate changes the value of the refs by passing them through a mutator function Mutate(mutator MutatorFunc) error // Set sets the referenced values to the provided value Set(value interface{}) error // Depth returns a depth value for this ref. When applying operations to multiple refs // they are always performed on the refs with the highest depth first. Depth() int // Join this ref with another ref yielding what amounts to a union of the two // refs Union(ref ...Ref) Ref // Merge attempts to combine two refs into // one ref without resorting to the UnionRef. This is used to combine i.e. two // ArrayRefs that refer to the same underlying slice by just merging their // respective indicies. Merge(ref Ref) (Ref, bool) // Returns true if this Ref is not referring to any elements. I.e. after a Delete // operation IsEmpty() bool // Give an estimate of the number of values this Ref points to. Used for sizing // arrays so should err on the high side if it needs to err at all. EstimateSize() int }
A Ref is a reference to a selection of values, typically in a struct, map or an array that allow operations to be performed on said values. Main use case is to represent data that have been matched using jsonmatch specs and then allow a client to perform operations on that subset.
func NewLiteralRef ¶
func NewLiteralRef(value interface{}) Ref
NewLiteralRef returns a new *LiteralRef
type Region ¶
Region represents a region of a slice and support operations that model the behavior of a region of array indicies as an array is being manipulated
func (Region) ContainsIndex ¶
ContainsIndex is true if the index provided is covered by the region
func (Region) ContainsRegion ¶
ContainsRegion returns true if the reciever covers the entire other region (or more)
func (Region) Cut ¶
Cut returns the new position and size of this region as if the provided region was cut from the underlying array.
func (Region) Intersect ¶
Intersect returns the intersection of the two regions. Removing a chunk from the middle of the receiver splits the region, so since this may result in two or no regions at all the result is a region set
func (Region) Join ¶
Join returns a range that cover the entire area of both regions. If the regions are not adjacent, the resulting region will also span the void between them
func (Region) OverlapOrAdjacent ¶
OverlapOrAdjacent is true if the two regions are adjacent or overlapping
type Regions ¶
type Regions []Region
Regions model a set of Regions as in ranges of array indicies and model the movement of these ranges as the underlying array is being manipulated.
func NewRegionForEachIndex ¶
NewRegionForEachIndex takes an array of ints and convert them to a set of regions, having an individual region for each index
func NewRegionsFromIndicies ¶
NewRegionsFromIndicies takes an array of ints and convert them to a set of regions, describing any contiguous series of indicies as single regions
func NewRegionsFromSliceSelector ¶
NewRegionsFromSliceSelector creates a region set from a jsonmatch slice selector (only supporting literal indicies, no matching etc obviously since we don't have any data at this junction)
func (Regions) Check ¶
Check validates that the regions set is fully compliant, meaning its sorted and non-overlapping.
func (Regions) CheckSorted ¶
CheckSorted validates that the regions are sorted
func (Regions) Clean ¶
Clean takes a jumble of unsorted, potentially overlapping set of regions and return a sorted set of non-overlapping regions without joining any regions, meaning we preserve any split-points and zero-length regions in the selection.
func (Regions) ContainsIndex ¶
ContainsIndex checks if any of the regions in the set contains the index
func (Regions) Cut ¶
Cut one region from the other regions. Shrinking or moving down the regions correspondingly. The number of resulting regions is always the same, regions that end up being empty will just get a lengt of 0. Call Compact to have them removed, if you need it.
func (Regions) ExtractItems ¶
func (rs Regions) ExtractItems(source []interface{}) [][]interface{}
ExtractItems extracts the items in the regions and returns them as an array of arrays with one sub-array with the items of each region
func (Regions) ForEachIndex ¶
func (rs Regions) ForEachIndex(callback ForEachIndexFunc) error
ForEachIndex calls the callback for each index in the region set
func (Regions) IndiciesCount ¶
IndiciesCount counts the total number of indicies covered by the regions in this set
func (Regions) InsertAt ¶
InsertAt returns a new region set moving regions as if something was inserted at the specfied region. If the new region is inside an existing region, this region is grown accordingly, all regions after the index is moved up by count indicies. The provided region is not actually inserted into the region set.
func (Regions) MergeItems ¶
func (rs Regions) MergeItems(source []interface{}, replace [][]interface{}) ([]interface{}, Regions)
MergeItems is a companion to ExtractItems that takes the arrays of the replace parameter and replaces them for each region described in rs returning the updated array and regions updated to cover the newly inserted items
func (Regions) ToIndicies ¶
ToIndicies converts a set of regions to individual indicies
func (Regions) ToSliceSelector ¶
ToSliceSelector returns a jsonmatch slice selector for the regions on the form "2:5,7:9" that would fit in a selector as "my.array[2:5,7:9]".
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner scans a jsonmatch expression
type Token ¶
type Token int
Token represents a jsonmatch token
const ( Illegal Token = iota EOF // End of file Whitespace // A contigous squence of whitespace ParenLeft // ( ParenRight // ) BraceLeft // { BraceRight // } BracketLeft // [ BracketRight // ] Dot // . Equals // == GT // > LT // < GTE // >= LTE // <= NEQ // != Not // ! Comma // , Identifier // A valid field DotDot // .. Dollar // $ At // @ Integer // 1234 Float // 123.4 Bool // true or false SingleQuotedString // 'literal string' DoubleQuotedString // "literal string" Asterisk // * QuestionMark // ? Pipe // | Colon // : Exists // virtual operator Slash // / )
func MatchingBrace ¶
MatchingBrace returns the brace matching the provided token, as in '(' returns ')' and '[' returns ']'
type UnionRef ¶
type UnionRef struct {
// contains filtered or unexported fields
}
UnionRef is the union of a collection of refs
func (*UnionRef) EstimateSize ¶
EstimateSize implements the Ref.EstimateSize method
func (*UnionRef) Mutate ¶
func (r *UnionRef) Mutate(mutator MutatorFunc) error
Mutate implements the Ref.Mutate method
type VarRef ¶
type VarRef struct {
// contains filtered or unexported fields
}
VarRef is a reference to a variable with the capacity to replace the contents of said variable
func (*VarRef) CanonicalValue ¶
func (r *VarRef) CanonicalValue() interface{}
CanonicalValue gets the current value of the variable converted to canonical type
func (*VarRef) EstimateSize ¶
EstimateSize is always 1 for VarRefs
func (*VarRef) IsContainer ¶
IsContainer is true if this VarRef wraps a map or slice or array.
func (*VarRef) SetWithMatchedType ¶
SetWithMatchedType updates the value, but attempts to avoid changing the underlying type if the new value is one of the canonical types
func (*VarRef) Value ¶
func (r *VarRef) Value() interface{}
Value gets the current value of the variable in original underlying type