Documentation
¶
Index ¶
- func NewMultipleToSingleMergeHandler(opts ...MultipleMergeKeyOpt) *multipleToSingleMergeHandler
- func OnVisitAliasNode(path string, fn FnVisitKeyValueNode) conditionalHandlerOpt
- func OnVisitDocumentNode(fn FnVisitValueNode) conditionalHandlerOpt
- func OnVisitMappingNode(path string, fn FnVisitKeyValueNode) conditionalHandlerOpt
- func OnVisitScalarNode(path string, fn FnVisitKeyValueNode) conditionalHandlerOpt
- func OnVisitSequenceNode(path string, fn FnVisitKeyValueNode) conditionalHandlerOpt
- func WithPathMatcher(ctx context.Context, matcher *PathMatcher) context.Context
- type ConditionalHandler
- func (c *ConditionalHandler) VisitAliasNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
- func (c *ConditionalHandler) VisitDocumentNode(ctx context.Context, key *yaml.Node) error
- func (c *ConditionalHandler) VisitMappingNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
- func (c *ConditionalHandler) VisitScalarNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
- func (c *ConditionalHandler) VisitSequenceNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
- type FnConditional
- type FnOptions
- type FnVisitKeyValueNode
- type FnVisitValueNode
- type MultipleMergeKeyOpt
- type PathMatcher
- type Visitor
- type VisitsAliasNode
- type VisitsDocumentNode
- type VisitsMappingNode
- type VisitsScalarNode
- type VisitsSequenceNode
- type VisitsYaml
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewMultipleToSingleMergeHandler ¶ added in v0.2.2
func NewMultipleToSingleMergeHandler(opts ...MultipleMergeKeyOpt) *multipleToSingleMergeHandler
NewMultipleToSingleMergeHandler aims to address a common situation in which the YAML specification does not allow multiple merge keys under a given node, while many parsers and libraries allow it. This is defined in yaml.v3 issue 624. When consuming such a document with yaml.v3 into a tag-based struct, parsing will fail. Passing a node through this handler will allow this scenario to succeed.
Example ¶
package main
import (
"context"
"os"
"github.com/jimschubert/yay"
"go.yaml.in/yaml/v3"
)
func main() {
input := `---
input:
first: &first-ref
a: A
msg: goodbye, world
second: &second-ref
b: B
msg: hello, world
config:
actual:
<<: *first-ref
<<: *second-ref
c: C
`
document := &yaml.Node{}
_ = yaml.Unmarshal([]byte(input), document)
handler := yay.NewMultipleToSingleMergeHandler()
visitor, _ := yay.NewVisitor(handler)
_ = visitor.Visit(context.TODO(), document)
enc := yaml.NewEncoder(os.Stdout)
enc.SetIndent(1)
_ = enc.Encode(document)
}
Output: input: first: &first-ref a: A msg: goodbye, world second: &second-ref b: B msg: hello, world config: actual: !!merge <<: [*second-ref, *first-ref] c: C
func OnVisitAliasNode ¶
func OnVisitAliasNode(path string, fn FnVisitKeyValueNode) conditionalHandlerOpt
func OnVisitDocumentNode ¶
func OnVisitDocumentNode(fn FnVisitValueNode) conditionalHandlerOpt
func OnVisitMappingNode ¶
func OnVisitMappingNode(path string, fn FnVisitKeyValueNode) conditionalHandlerOpt
func OnVisitScalarNode ¶
func OnVisitScalarNode(path string, fn FnVisitKeyValueNode) conditionalHandlerOpt
func OnVisitSequenceNode ¶
func OnVisitSequenceNode(path string, fn FnVisitKeyValueNode) conditionalHandlerOpt
func WithPathMatcher ¶
func WithPathMatcher(ctx context.Context, matcher *PathMatcher) context.Context
WithPathMatcher derives from the parent context a new context containing the provided PathMatcher
Types ¶
type ConditionalHandler ¶
type ConditionalHandler struct {
// contains filtered or unexported fields
}
ConditionalHandler allows the user to create handler functions which are conditional on a yamlpath selector syntax.
func NewConditionalHandler ¶
func NewConditionalHandler(opts ...conditionalHandlerOpt) (*ConditionalHandler, error)
NewConditionalHandler creates a new ConditionalHandler, allowing the user to provide 1..n handler functions with yamlpath preconditions.
Example (Mapping_selectors) ¶
package main
import (
"context"
"fmt"
"github.com/jimschubert/yay"
"go.yaml.in/yaml/v3"
)
func main() {
input := `---
store:
book:
- author: Ernest Hemingway
title: The Old Man and the Sea
- author: Fyodor Mikhailovich Dostoevsky
title: Crime and Punishment
- author: Jane Austen
title: Sense and Sensibility
- author: Kurt Vonnegut Jr.
title: Slaughterhouse-Five
- author: J. R. R. Tolkien
title: The Lord of the Rings`
document := &yaml.Node{}
_ = yaml.Unmarshal([]byte(input), document)
count := 0
handler, _ := yay.NewConditionalHandler(
yay.OnVisitMappingNode("$.store.book[?(@.title=~/^S.*$/)]",
func(ctx context.Context, key *yaml.Node, value *yaml.Node) error {
// note: key is nil here because each map value is an item in a sequence
fmt.Printf("processed item at index %d\n", count)
count += 1
return nil
}))
visitor, _ := yay.NewVisitor(handler)
_ = visitor.Visit(context.TODO(), document)
}
Output: processed item at index 0 processed item at index 1
Example (Scalars_selectors) ¶
package main
import (
"context"
"fmt"
"github.com/jimschubert/yay"
"go.yaml.in/yaml/v3"
)
func main() {
input := `---
store:
book:
- author: Ernest Hemingway
title: The Old Man and the Sea
- author: Fyodor Mikhailovich Dostoevsky
title: Crime and Punishment
- author: Jane Austen
title: Sense and Sensibility
- author: Kurt Vonnegut Jr.
title: Slaughterhouse-Five
- author: J. R. R. Tolkien
title: The Lord of the Rings`
document := &yaml.Node{}
_ = yaml.Unmarshal([]byte(input), document)
handler, _ := yay.NewConditionalHandler(
yay.OnVisitScalarNode("$.store.book[?(@.title=~/^S.*$/)].title",
func(ctx context.Context, key *yaml.Node, value *yaml.Node) error {
fmt.Printf("processed item: key=%s, value=%q\n", key.Value, value.Value)
return nil
}))
visitor, _ := yay.NewVisitor(handler)
_ = visitor.Visit(context.TODO(), document)
}
Output: processed item: key=title, value="Sense and Sensibility" processed item: key=title, value="Slaughterhouse-Five"
func (*ConditionalHandler) VisitAliasNode ¶
func (c *ConditionalHandler) VisitAliasNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
VisitAliasNode satisfies VisitsAliasNode such that a visitor always invokes this method, which defers to the handler passed by the user
func (*ConditionalHandler) VisitDocumentNode ¶
VisitDocumentNode satisfies VisitsDocumentNode such that a visitor always invokes this method, which defers to the handler passed by the user
func (*ConditionalHandler) VisitMappingNode ¶
func (c *ConditionalHandler) VisitMappingNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
VisitMappingNode satisfies VisitsMappingNode such that a visitor always invokes this method, which defers to the handler passed by the user
func (*ConditionalHandler) VisitScalarNode ¶
func (c *ConditionalHandler) VisitScalarNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
VisitScalarNode satisfies VisitsScalarNode such that a visitor always invokes this method, which defers to the handler passed by the user
func (*ConditionalHandler) VisitSequenceNode ¶
func (c *ConditionalHandler) VisitSequenceNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
VisitSequenceNode satisfies VisitsSequenceNode such that a visitor always invokes this method, which defers to the handler passed by the user
type FnConditional ¶
type FnConditional func(path string, fn FnVisitKeyValueNode) FnVisitKeyValueNode
type FnOptions ¶ added in v0.3.0
type FnOptions func(o *opts)
FnOptions is a function chain of options to apply conditionally to a Visitor
func NewOptions ¶ added in v0.3.0
func NewOptions() FnOptions
NewOptions creates a new options functional builder with discoverable functions that don't pollute the yay package
func (FnOptions) WithSkipDocumentCheck ¶ added in v0.3.0
WithSkipDocumentCheck allows the user to configure a Visitor to skip the requirement that a top-level node must be a yaml.DocumentNode. This allows creating and invoking visitors against manually constructed nodes.
type FnVisitKeyValueNode ¶
type MultipleMergeKeyOpt ¶ added in v0.3.1
type MultipleMergeKeyOpt func(handler *multipleToSingleMergeHandler)
MultipleMergeKeyOpt is an option for NewMultipleToSingleMergeHandler.
func WithRetainMergeKeyOrder ¶ added in v0.3.1
func WithRetainMergeKeyOrder() MultipleMergeKeyOpt
WithRetainMergeKeyOrder is an option for NewMultipleToSingleMergeHandler which changes the behavior of merging keys to retain the original order.
By default, NewMultipleToSingleMergeHandler will reverse the order of the merge keys, allowing for keys to be overridden according to the specification for merge keys as defined in the YAML specification. Since multiple merge keys are not defined by the specification, some parsers and libraries may not follow the same behaviors.
This option will change the behavior to retain the original order of the multiple merge keys.
Example ¶
package main
import (
"context"
"os"
"github.com/jimschubert/yay"
"go.yaml.in/yaml/v3"
)
func main() {
input := `---
input:
first: &first-ref
a: A
msg: goodbye, world
second: &second-ref
b: B
msg: hello, world
config:
actual:
<<: *first-ref
<<: *second-ref
c: C
`
document := &yaml.Node{}
_ = yaml.Unmarshal([]byte(input), document)
handler := yay.NewMultipleToSingleMergeHandler(
yay.WithRetainMergeKeyOrder(),
)
visitor, _ := yay.NewVisitor(handler)
_ = visitor.Visit(context.TODO(), document)
enc := yaml.NewEncoder(os.Stdout)
enc.SetIndent(1)
_ = enc.Encode(document)
}
Output: input: first: &first-ref a: A msg: goodbye, world second: &second-ref b: B msg: hello, world config: actual: !!merge <<: [*first-ref, *second-ref] c: C
type PathMatcher ¶
type PathMatcher struct {
// contains filtered or unexported fields
}
PathMatcher collects information internally to wrap yamlpath.Path for optimized key/value matching during iteration. A user-facing PathMatcher.Match can be invoked on a node's children to determine if they also match the condition.
func PathMatcherFor ¶
func PathMatcherFor(ctx context.Context, path string) (*PathMatcher, error)
PathMatcherFor retrieves the PathMatcher for the given path on this context, or creates a new one if it differs.
type Visitor ¶
Visitor defines behaviors related to recursively visiting a yaml.Node
func NewVisitor ¶
NewVisitor constructs a new Visitor which handles yaml.Node processing defined by handler. The handler must satisfy one or more of the visitor interfaces. See:
- VisitsYaml
- VisitsDocumentNode
- VisitsSequenceNode
- VisitsMappingNode
- VisitsScalarNode
- VisitsAliasNode
func NewVisitorWithOptions ¶ added in v0.3.0
NewVisitorWithOptions allows constructing a visitor with options addressing edge case scenarios. It constructs a new Visitor which handles yaml.Node processing defined by handler. The handler must satisfy one or more of the visitor interfaces. See:
- VisitsYaml
- VisitsDocumentNode
- VisitsSequenceNode
- VisitsMappingNode
- VisitsScalarNode
- VisitsAliasNode
type VisitsAliasNode ¶
type VisitsAliasNode interface {
VisitAliasNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
}
VisitsAliasNode defines behaviors for visitors which want to handle alias nodes
type VisitsDocumentNode ¶
VisitsDocumentNode defines behaviors for visitors which want to handle document nodes
type VisitsMappingNode ¶
type VisitsMappingNode interface {
VisitMappingNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
}
VisitsMappingNode defines behaviors for visitors which want to handle mapping nodes
type VisitsScalarNode ¶
type VisitsScalarNode interface {
VisitScalarNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
}
VisitsScalarNode defines behaviors for visitors which want to handle scalar nodes
type VisitsSequenceNode ¶
type VisitsSequenceNode interface {
VisitSequenceNode(ctx context.Context, key *yaml.Node, value *yaml.Node) error
}
VisitsSequenceNode defines behaviors for visitors which want to handle sequence nodes
type VisitsYaml ¶
type VisitsYaml interface {
VisitsDocumentNode
VisitsSequenceNode
VisitsMappingNode
VisitsScalarNode
VisitsAliasNode
}
VisitsYaml defines all behaviors for YAML visitors