1
// Copyright Istio Authors
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
23
// pathSeparator is the separator between path elements.
25
// escapedPathSeparator is what to use when the path shouldn't separate
26
escapedPathSeparator = "\\" + pathSeparator
29
// Path is a path in slice form.
32
// FromString converts a string path of form a.b.c to a string slice representation.
33
func FromString(path string) Path {
34
path = filepath.Clean(path)
35
path = strings.TrimPrefix(path, pathSeparator)
36
path = strings.TrimSuffix(path, pathSeparator)
37
pv := splitEscaped(path, []rune(pathSeparator)[0])
39
for _, str := range pv {
41
str = strings.ReplaceAll(str, escapedPathSeparator, pathSeparator)
42
// Is str of the form node[expr], convert to "node", "[expr]"?
43
nBracket := strings.IndexRune(str, '[')
45
r = append(r, str[:nBracket], str[nBracket:])
47
// str is "[expr]" or "node"
55
// String converts a string slice path representation of form ["a", "b", "c"] to a string representation like "a.b.c".
56
func (p Path) String() string {
57
return strings.Join(p, pathSeparator)
60
// splitEscaped splits a string using the rune r as a separator. It does not split on r if it's prefixed by \.
61
func splitEscaped(s string, r rune) []string {
69
if c == r && (i == 0 || (i > 0 && prev != '\\')) {
70
out = append(out, s[prevIdx:i])
75
out = append(out, s[prevIdx:])