mirror of
https://github.com/TomWright/dasel.git
synced 2022-05-22 02:32:45 +03:00
128 lines
2.5 KiB
Go
128 lines
2.5 KiB
Go
package dasel
|
|
|
|
import (
|
|
"errors"
|
|
)
|
|
|
|
// ErrDynamicSelectorBracketMismatch is returned when the number of opening brackets doesn't equal that
|
|
// of the closing brackets.
|
|
var ErrDynamicSelectorBracketMismatch = errors.New("dynamic selector bracket mismatch")
|
|
|
|
// ExtractNextSelector returns the next selector from the given input.
|
|
func ExtractNextSelector(input string) (string, int) {
|
|
escapedIndex := -1
|
|
res := ""
|
|
i := 0
|
|
read := 0
|
|
for k, v := range input {
|
|
curRuneStr := string(v)
|
|
curRuneLength := len(curRuneStr)
|
|
if escapedIndex == k-1 && k != 0 {
|
|
// last character was escape character
|
|
res += curRuneStr
|
|
read += curRuneLength
|
|
continue
|
|
}
|
|
|
|
if v == '(' || v == '[' {
|
|
i++
|
|
} else if v == ')' || v == ']' {
|
|
i--
|
|
}
|
|
|
|
if v == '\\' {
|
|
escapedIndex = k
|
|
read += curRuneLength
|
|
continue
|
|
}
|
|
|
|
if i == 0 && v == '.' && k != 0 {
|
|
break
|
|
}
|
|
res += curRuneStr
|
|
read += curRuneLength
|
|
}
|
|
return res, read
|
|
}
|
|
|
|
// DynamicSelectorToGroups takes a dynamic selector and splits it into groups.
|
|
func DynamicSelectorToGroups(selector string) ([]string, error) {
|
|
i := 0
|
|
tmp := ""
|
|
res := make([]string, 0)
|
|
for k, v := range selector {
|
|
if v == '(' {
|
|
if i > 0 {
|
|
tmp += string(v)
|
|
} else {
|
|
tmp = ""
|
|
}
|
|
i++
|
|
} else if v == ')' {
|
|
i--
|
|
if i == 0 {
|
|
res = append(res, tmp)
|
|
tmp = ""
|
|
} else {
|
|
tmp += string(v)
|
|
}
|
|
} else if v == '.' && i == 0 && k != 0 {
|
|
return res, nil
|
|
} else {
|
|
tmp += string(v)
|
|
}
|
|
}
|
|
if i != 0 {
|
|
return nil, ErrDynamicSelectorBracketMismatch
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
// DynamicSelectorParts contains the parts for a dynamic selector.
|
|
type DynamicSelectorParts struct {
|
|
Key string
|
|
Comparison string
|
|
Value string
|
|
}
|
|
|
|
// FindDynamicSelectorParts extracts the parts from the dynamic selector given.
|
|
func FindDynamicSelectorParts(selector string) DynamicSelectorParts {
|
|
i := 0
|
|
parts := DynamicSelectorParts{}
|
|
for _, v := range selector {
|
|
switch {
|
|
|
|
// Start of a group
|
|
case v == '(':
|
|
if parts.Comparison == "" {
|
|
parts.Key += string(v)
|
|
} else {
|
|
parts.Value += string(v)
|
|
}
|
|
i++
|
|
|
|
// End of a group
|
|
case v == ')':
|
|
i--
|
|
if parts.Comparison == "" {
|
|
parts.Key += string(v)
|
|
} else {
|
|
parts.Value += string(v)
|
|
}
|
|
|
|
// Matches a comparison character
|
|
case i == 0 && (v == '<' || v == '>' || v == '=' || v == '!'):
|
|
parts.Comparison += string(v)
|
|
|
|
// Add to key or value based on comparison existence
|
|
default:
|
|
if parts.Comparison == "" {
|
|
parts.Key += string(v)
|
|
} else {
|
|
parts.Value += string(v)
|
|
}
|
|
}
|
|
}
|
|
return parts
|
|
}
|