in internal/s11n/match.go [40:106]
func matchPath(ch chan<- *yaml.Node, n *yaml.Node, path []string) {
if n.Kind == yaml.DocumentNode {
for _, doc := range n.Content {
matchPath(ch, doc, path)
}
return
}
if len(path) == 0 {
ch <- n
return
}
head, tail := path[0], path[1:]
query := make([]string, 0)
// Deal with recursive descent
if head == "**" {
matchPath(ch, n, tail)
if n.Kind == yaml.MappingNode {
for i := 0; i < len(n.Content); i += 2 {
matchPath(ch, n.Content[i+1], path)
}
} else if n.Kind == yaml.SequenceNode {
for _, child := range n.Content {
matchPath(ch, child, path)
}
}
}
// Parse out any query
parts := strings.Split(head, "|")
if len(parts) == 2 {
head = parts[0]
query = parts[1:]
}
if n.Kind == yaml.MappingNode {
for i := 0; i < len(n.Content); i += 2 {
key := n.Content[i]
if head == "*" || key.Value == head {
value := n.Content[i+1]
if filter(value, query) {
matchPath(ch, value, tail)
}
}
}
} else if n.Kind == yaml.SequenceNode {
if head == "*" {
for _, child := range n.Content {
if filter(child, query) {
matchPath(ch, child, tail)
}
}
} else {
i, err := strconv.Atoi(head)
if err == nil && i < len(n.Content) {
value := n.Content[i]
if filter(value, query) {
matchPath(ch, value, tail)
}
}
}
}
}