File: yamlpath.go

package info (click to toggle)
golang-github-caspr-io-yamlpath 0.0~git20200722.502e8d1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 116 kB
  • sloc: makefile: 11
file content (110 lines) | stat: -rw-r--r-- 2,809 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package yamlpath

import (
	"strings"

	"github.com/caspr-io/yamlpath/segments"
)

// https://pypi.org/project/yamlpath/#supported-yaml-path-segments

// YamlPath traverses the yaml document to and returns the retrieved value
func YamlPath(yaml map[string]interface{}, path string) (interface{}, error) {
	splitPath, err := segments.ParseSegment(path)
	if err != nil {
		return nil, PathError(path, err)
	}
	// fmt.Printf("%v, %d", splitPath, len(splitPath))

	var value interface{} = yaml

	for _, pathPart := range splitPath {
		returned, err := segments.NavigateYaml(value, pathPart)
		if err != nil {
			return nil, PathError(path, err)
		}

		value = returned
	}

	return value, nil
}

// func navigateYaml(yaml interface{}, part string) (interface{}, error) {
// 	switch y := yaml.(type) {
// 	case map[string]interface{}:
// 		return navigateMap(y, part)
// 	case []interface{}:
// 		return navigateArray(y, part)
// 	default:
// 		return nil, fmt.Errorf("no support yet for %v", yaml)
// 	}
// }

// func navigateArray(l []interface{}, part string) (interface{}, error) {
// switch {
// case regexps[ExplicitIndexPart].MatchString(part):
// 	i, err := strconv.Atoi(part[1 : len(part)-1])
// 	if err != nil {
// 		return nil, err
// 	}

// 	if i < len(l) {
// 		return l[i], nil
// 	}

// 	return nil, fmt.Errorf("out of bounds '%d' for array of length '%d'", i, len(l))
// case regexps[SlicePart].MatchString(part):
// case regexps[ImplicitIndexPart].MatchString(part):
// 	i, err := strconv.Atoi(part)
// 	if err != nil {
// 		return nil, fmt.Errorf("part '%s' is not an index into an array. %w", part, err)
// 	}

// 	return l[i], nil
// case regexps[KeyPart].MatchString(part):
// case regexps[ValueSearchPart].MatchString(part):
// 	toFind := part[3 : len(part)-1]
// 	operator := part[2]

// 	for _, i := range l {
// 		switch s := i.(type) {
// 		case string:
// 			if valueMatches(s, toFind, operator) {
// 				return s, nil
// 			}

// 			continue
// 		default:
// 			return nil, fmt.Errorf("could not search for value '%s' as list does not contain strings", part)
// 		}
// 	}

// 	return nil, fmt.Errorf("could not find match for search part '%s'", part)
// default:
// 	return nil, fmt.Errorf("part '%s' not supported for array", part)
// }
// }

func valueMatches(s string, find string, operator byte) bool {
	switch operator {
	case '^':
		return strings.HasPrefix(s, find)
	case '$':
		return strings.HasSuffix(s, find)
	case '%':
		return strings.Contains(s, find)
	default:
		return false
	}
}

// func navigateMap(m map[string]interface{}, part string) (interface{}, error) {
// 	switch {
// 	case regexps[KeySearchPart].MatchString(part):
// 		key := part[3 : len(part)-1]
// 		return m[key], nil
// 	default:
// 		return nil, fmt.Errorf("no support for part '%s'", part)
// 	}
// }