From: Dan Fuhry Date: Thu, 6 Nov 2025 12:04:53 +0000 (-0500) Subject: utils/stringmatch: add Sub method; utils/hashset: add Equal method X-Git-Url: https://go.fuhry.dev/?a=commitdiff_plain;h=553fbee598adedccfbad55a5999169a38037b60f;p=runtime.git utils/stringmatch: add Sub method; utils/hashset: add Equal method --- diff --git a/constants/constants.go b/constants/constants.go index 9728045..dfced59 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -20,4 +20,6 @@ var ( RootCAName = OrgName + " Root" IntCAName = OrgName + " Intermediate mTLS" DeviceTrustTokenName = OrgName + " Device Trust" + + Version = "0.0.0+unset" ) diff --git a/utils/hashset/hashset.go b/utils/hashset/hashset.go index 40cfd8b..d724727 100644 --- a/utils/hashset/hashset.go +++ b/utils/hashset/hashset.go @@ -178,3 +178,26 @@ func (hs *HashSet[TKey]) Dup() *HashSet[TKey] { func (hs *HashSet[TKey]) dup() *HashSet[TKey] { return FromSlice(hs.AsSlice()) } + +func (hs *HashSet[TKey]) Equal(other *HashSet[TKey]) bool { + hs.lock.Lock() + other.lock.Lock() + defer hs.lock.Unlock() + defer other.lock.Unlock() + + return hs.equal(other) +} + +func (hs *HashSet[TKey]) equal(other *HashSet[TKey]) bool { + if len(hs.data) != len(other.data) { + return false + } + + for k := range hs.data { + if _, ok := other.data[k]; !ok { + return false + } + } + + return true +} diff --git a/utils/stringmatch/matchers.go b/utils/stringmatch/matchers.go index a46892c..19f475c 100644 --- a/utils/stringmatch/matchers.go +++ b/utils/stringmatch/matchers.go @@ -11,6 +11,7 @@ import ( type StringMatcher interface { Match(input string) bool String() string + Sub(vars map[string]string) StringMatcher } type Prefix string @@ -21,6 +22,19 @@ type Regexp string type Any struct{} type Never struct{} +type MatchableString interface { + ~string + StringMatcher +} + +func sub[T MatchableString](inp T, vars map[string]string) StringMatcher { + out := string(inp) + for name, value := range vars { + out = strings.ReplaceAll(out, "{{"+name+"}}", value) + } + return T(out) +} + func (s Prefix) Match(input string) bool { return strings.HasPrefix(input, string(s)) } @@ -29,6 +43,10 @@ func (s Prefix) String() string { return fmt.Sprintf("%T(%s)", s, string(s)) } +func (s Prefix) Sub(vars map[string]string) StringMatcher { + return sub(s, vars) +} + func (s Suffix) Match(input string) bool { return strings.HasSuffix(input, string(s)) } @@ -37,6 +55,10 @@ func (s Suffix) String() string { return fmt.Sprintf("%T(%s)", s, string(s)) } +func (s Suffix) Sub(vars map[string]string) StringMatcher { + return sub(s, vars) +} + func (s Exact) Match(input string) bool { return input == string(s) } @@ -45,6 +67,10 @@ func (s Exact) String() string { return fmt.Sprintf("%T(%s)", s, string(s)) } +func (s Exact) Sub(vars map[string]string) StringMatcher { + return sub(s, vars) +} + func (s Contains) Match(input string) bool { return strings.Contains(input, string(s)) } @@ -53,6 +79,10 @@ func (s Contains) String() string { return fmt.Sprintf("%T(%s)", s, string(s)) } +func (s Contains) Sub(vars map[string]string) StringMatcher { + return sub(s, vars) +} + func (s Regexp) Match(input string) bool { re := regexp.MustCompile(string(s)) return re.MatchString(input) @@ -62,6 +92,10 @@ func (s Regexp) String() string { return fmt.Sprintf("%T(%s)", s, string(s)) } +func (s Regexp) Sub(vars map[string]string) StringMatcher { + return sub(s, vars) +} + func (s Any) String() string { return fmt.Sprintf("%T", s) } @@ -70,6 +104,10 @@ func (s Any) Match(string) bool { return true } +func (s Any) Sub(vars map[string]string) StringMatcher { + return s +} + func (s Never) Match(string) bool { return false } @@ -78,6 +116,10 @@ func (s Never) String() string { return fmt.Sprintf("%T", s) } +func (s Never) Sub(vars map[string]string) StringMatcher { + return s +} + type andMatcher struct { matchers []StringMatcher } @@ -100,6 +142,14 @@ func (mm *andMatcher) String() string { return fmt.Sprintf("And(%s)", strings.Join(matcherStrs, " & ")) } +func (mm *andMatcher) Sub(vars map[string]string) StringMatcher { + dup := &andMatcher{} + for _, m := range mm.matchers { + dup.matchers = append(dup.matchers, m.Sub(vars)) + } + return dup +} + func And(matchers ...StringMatcher) StringMatcher { return &andMatcher{ matchers: matchers, @@ -128,6 +178,14 @@ func (mm *orMatcher) String() string { return fmt.Sprintf("Or(%s)", strings.Join(matcherStrs, " & ")) } +func (mm *orMatcher) Sub(vars map[string]string) StringMatcher { + dup := &andMatcher{} + for _, m := range mm.matchers { + dup.matchers = append(dup.matchers, m.Sub(vars)) + } + return dup +} + func Or(matchers ...StringMatcher) StringMatcher { return &orMatcher{ matchers: matchers,