2019-12-30 17:08:50 -08:00
|
|
|
package anchor
|
2019-06-13 17:20:00 +03:00
|
|
|
|
|
|
|
import (
|
2023-01-30 17:47:19 +05:30
|
|
|
"regexp"
|
|
|
|
"strings"
|
2019-06-13 17:20:00 +03:00
|
|
|
)
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
type AnchorType string
|
2019-09-25 15:12:33 -07:00
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
const (
|
|
|
|
Condition AnchorType = ""
|
|
|
|
Global AnchorType = "<"
|
|
|
|
Negation AnchorType = "X"
|
|
|
|
AddIfNotPresent AnchorType = "+"
|
|
|
|
Equality AnchorType = "="
|
|
|
|
Existence AnchorType = "^"
|
|
|
|
)
|
2019-12-30 17:08:50 -08:00
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
var regex = regexp.MustCompile(`^(?P<modifier>[+<=X^])?\((?P<key>.+)\)$`)
|
2019-09-25 15:12:33 -07:00
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// Anchor interface
|
|
|
|
type Anchor interface {
|
|
|
|
// Type returns the anchor type
|
|
|
|
Type() AnchorType
|
|
|
|
// Key returns the anchor key
|
|
|
|
Key() string
|
|
|
|
// String returns the anchor string
|
|
|
|
String() string
|
2019-10-10 16:59:08 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
type anchor struct {
|
|
|
|
modifier AnchorType
|
|
|
|
key string
|
2019-10-10 16:59:08 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// Parse parses a string, returns nil if not an anchor
|
|
|
|
func Parse(str string) Anchor {
|
|
|
|
str = strings.TrimSpace(str)
|
|
|
|
values := regex.FindStringSubmatch(str)
|
|
|
|
if len(values) == 0 {
|
|
|
|
return nil
|
2019-10-10 16:59:08 -07:00
|
|
|
}
|
2023-01-30 17:47:19 +05:30
|
|
|
return New(AnchorType(values[1]), values[2])
|
2019-10-10 16:59:08 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// New creates an anchor
|
|
|
|
func New(modifier AnchorType, key string) Anchor {
|
|
|
|
if key == "" {
|
|
|
|
return nil
|
2019-10-01 12:35:14 -07:00
|
|
|
}
|
2023-01-30 17:47:19 +05:30
|
|
|
return anchor{
|
|
|
|
modifier: modifier,
|
|
|
|
key: key,
|
2019-10-01 12:35:14 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// String returns the anchor string.
|
|
|
|
// Will return an empty string if key is empty.
|
|
|
|
func String(modifier AnchorType, key string) string {
|
|
|
|
if key == "" {
|
|
|
|
return ""
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
2023-01-30 17:47:19 +05:30
|
|
|
return string(modifier) + "(" + key + ")"
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
func (a anchor) Type() AnchorType {
|
|
|
|
return a.modifier
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
func (a anchor) Key() string {
|
|
|
|
return a.key
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
func (a anchor) String() string {
|
|
|
|
return String(a.modifier, a.key)
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// IsOneOf returns checks if anchor is one of the given types
|
|
|
|
func IsOneOf(a Anchor, types ...AnchorType) bool {
|
|
|
|
if a != nil {
|
|
|
|
for _, t := range types {
|
|
|
|
if t == a.Type() {
|
|
|
|
return true
|
|
|
|
}
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
2021-09-13 18:59:28 +03:00
|
|
|
}
|
2023-01-30 17:47:19 +05:30
|
|
|
return false
|
2021-09-13 18:59:28 +03:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// ContainsCondition returns true if anchor is either condition anchor or global condition anchor
|
|
|
|
func ContainsCondition(a Anchor) bool {
|
|
|
|
return IsOneOf(a, Condition, Global)
|
2021-09-13 18:59:28 +03:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// IsCondition checks for condition anchor
|
|
|
|
func IsCondition(a Anchor) bool {
|
|
|
|
return IsOneOf(a, Condition)
|
2021-09-13 18:59:28 +03:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// IsGlobal checks for global condition anchor
|
|
|
|
func IsGlobal(a Anchor) bool {
|
|
|
|
return IsOneOf(a, Global)
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// IsNegation checks for negation anchor
|
|
|
|
func IsNegation(a Anchor) bool {
|
|
|
|
return IsOneOf(a, Negation)
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// IsAddIfNotPresent checks for addition anchor
|
|
|
|
func IsAddIfNotPresent(a Anchor) bool {
|
|
|
|
return IsOneOf(a, AddIfNotPresent)
|
2019-09-25 15:12:33 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// IsEquality checks for equality anchor
|
|
|
|
func IsEquality(a Anchor) bool {
|
|
|
|
return IsOneOf(a, Equality)
|
2019-09-25 21:01:45 -07:00
|
|
|
}
|
|
|
|
|
2023-01-30 17:47:19 +05:30
|
|
|
// IsExistence checks for existence anchor
|
|
|
|
func IsExistence(a Anchor) bool {
|
|
|
|
return IsOneOf(a, Existence)
|
2019-06-13 17:20:00 +03:00
|
|
|
}
|