Skip to content

Commit

Permalink
[CHANGE] TagList now has ContainsEqualFold/RemoveEqualsFold to allow …
Browse files Browse the repository at this point in the history
…case-insensitive usages

Signed-off-by: Alberto Ricart <[email protected]>
  • Loading branch information
aricart committed Oct 1, 2024
1 parent 18a60d6 commit e5da714
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 8 deletions.
4 changes: 2 additions & 2 deletions v2/account_claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ type Account struct {
Mappings Mapping `json:"mappings,omitempty"`
Authorization ExternalAuthorization `json:"authorization,omitempty"`
Trace *MsgTrace `json:"trace,omitempty"`
ClusterTraffic ClusterTraffic `json:"cluster_traffic,omitempty"`
ClusterTraffic string `json:"cluster_traffic,omitempty"`
Info
GenericFields
}
Expand Down Expand Up @@ -324,7 +324,7 @@ func (a *Account) Validate(acct *AccountClaims, vr *ValidationResults) {
a.SigningKeys.Validate(vr)
a.Info.Validate(vr)

if err := a.ClusterTraffic.Valid(); err != nil {
if err := ClusterTraffic(a.ClusterTraffic).Valid(); err != nil {
vr.AddError(err.Error())
}
}
Expand Down
49 changes: 43 additions & 6 deletions v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"net"
"net/url"
"reflect"
"sort"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -422,26 +423,46 @@ func (u *StringList) Remove(p ...string) {
}

// TagList is a unique array of lower case strings
// All tag list methods lower case the strings in the arguments
type TagList []string

// Contains returns true if the list contains the tags
// Contains returns true if the list contains the tag
func (u *TagList) Contains(p string) bool {
return u.find(p) != -1
}

// ContainsEqualsFold returns true if the list contain the tag regardless of case
func (u *TagList) ContainsEqualsFold(p string) bool {
return u.findEqualsFold(p) != -1
}

// Equals returns true if the lists are strictly equal
func (u *TagList) Equals(other *TagList) bool {
if len(*u) != len(*other) {
return false
}
for _, v := range *u {
if other.find(v) == -1 {

a := sort.StringSlice(*u)
sort.Sort(a)
b := sort.StringSlice(*other)
sort.Sort(b)

for i, v := range a {
if v != b[i] {
return false
}
}
return true
}

func (u *TagList) findEqualsFold(p string) int {
for idx, t := range *u {
if strings.EqualFold(p, t) {
return idx
}
}
return -1
}

func (u *TagList) find(p string) int {
for idx, t := range *u {
if p == t {
Expand All @@ -451,7 +472,7 @@ func (u *TagList) find(p string) int {
return -1
}

// Add appends 1 or more tags to a list
// Add appends 1 or more tags to a list, case of the arguments is preserved.
func (u *TagList) Add(p ...string) {
for _, v := range p {
v = strings.TrimSpace(v)
Expand All @@ -464,7 +485,7 @@ func (u *TagList) Add(p ...string) {
}
}

// Remove removes 1 or more tags from a list
// Remove removes 1 or more tags from a list, tags must be strictly equal
func (u *TagList) Remove(p ...string) error {
for _, v := range p {
v = strings.TrimSpace(v)
Expand All @@ -479,6 +500,22 @@ func (u *TagList) Remove(p ...string) error {
return nil
}

// RemoveEqualsFold removes 1 or more tags from a list as long as their
// values are equal regardless of fold.
func (u *TagList) RemoveEqualsFold(p ...string) error {
for _, v := range p {
v = strings.TrimSpace(v)
idx := u.findEqualsFold(v)
if idx != -1 {
a := *u
*u = append(a[:idx], a[idx+1:]...)
} else {
return fmt.Errorf("unable to remove tag: %q - not found", v)
}
}
return nil
}

type CIDRList []string

func (c *CIDRList) Contains(p string) bool {
Expand Down
50 changes: 50 additions & 0 deletions v2/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,29 @@ func TestTagList_CasePreservingContains(t *testing.T) {
}
}

func TestTagList_EqualsFoldContains(t *testing.T) {
type test struct {
v string
a TagList
ok bool
}

tests := []test{
{v: "A", a: TagList{}, ok: false},
{v: "A", a: TagList{"a"}, ok: true},
{v: "A", a: TagList{"A"}, ok: true},
{v: "a", a: TagList{"a:hello"}, ok: false},
{v: "a:a", a: TagList{"a:c"}, ok: false},
}

for idx, test := range tests {
found := test.a.ContainsEqualsFold(test.v)
if !found && test.ok {
t.Errorf("[%d] expected to contain %q", idx, test.v)
}
}
}

func TestTagList_Add(t *testing.T) {
type test struct {
v string
Expand Down Expand Up @@ -503,3 +526,30 @@ func TestTagList_Delete(t *testing.T) {
}
}
}

func TestTagList_EqualsFoldDelete(t *testing.T) {
type test struct {
v string
a TagList
shouldBe TagList
shouldFail bool
}

tests := []test{
{v: "A", a: TagList{}, shouldBe: TagList{}, shouldFail: true},
{v: "A", a: TagList{"A"}, shouldBe: TagList{}},
{v: "a", a: TagList{"A"}, shouldBe: TagList{}},
{v: "a:Hello", a: TagList{"a:hello"}, shouldBe: TagList{}},
{v: "a:a", a: TagList{"a:A"}, shouldBe: TagList{}},
}

for idx, test := range tests {
err := test.a.RemoveEqualsFold(test.v)
if test.shouldFail && err == nil {
t.Fatalf("[%d] expected delete to fail: %v", idx, test.a)
}
if !test.a.Equals(&test.shouldBe) {
t.Fatalf("[%d] expected lists to be equal: %v", idx, test.a)
}
}
}

0 comments on commit e5da714

Please sign in to comment.