Files
opencloud/vendor/github.com/yashtewari/glob-intersection/glob.go
dependabot[bot] 1f069c7c00 build(deps): bump github.com/open-policy-agent/opa from 0.51.0 to 0.59.0
Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 0.51.0 to 0.59.0.
- [Release notes](https://github.com/open-policy-agent/opa/releases)
- [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-policy-agent/opa/compare/v0.51.0...v0.59.0)

---
updated-dependencies:
- dependency-name: github.com/open-policy-agent/opa
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-05 09:47:11 +01:00

179 lines
3.0 KiB
Go

// Package gintersect provides methods to check whether the intersection of several globs matches a non-empty set of strings.
package gintersect
import (
"fmt"
"strings"
)
// Glob represents a glob.
type Glob []Token
// NewGlob constructs a Glob from the given string by tokenizing and then simplifying it, or reports errors if any.
func NewGlob(input string) (Glob, error) {
tokens, err := Tokenize([]rune(input))
if err != nil {
return nil, err
}
tokens = Simplify(tokens)
return Glob(tokens), nil
}
// TokenType is the type of a Token.
type TokenType uint
const (
TTCharacter TokenType = iota
TTDot
TTSet
)
// Flag applies to a token.
type Flag uint
func (f Flag) String() (s string) {
for r, flag := range flagRunes {
if f == flag {
s = string(r)
break
}
}
return
}
const (
FlagNone = iota
FlagPlus
FlagStar
)
// Token is the element that makes up a Glob.
type Token interface {
Type() TokenType
Flag() Flag
SetFlag(Flag)
// Equal describes whether the given Token is exactly equal to this one, barring differences in flags.
Equal(Token) bool
String() string
}
// token is the base for all structs implementing Token.
type token struct {
ttype TokenType
flag Flag
}
func (t token) Type() TokenType {
return t.ttype
}
func (t token) Flag() Flag {
return t.flag
}
func (t *token) SetFlag(f Flag) {
t.flag = f
}
// character is a specific rune. It implements Token.
type character struct {
token
r rune
}
func NewCharacter(r rune) Token {
return &character{
token: token{ttype: TTCharacter},
r: r,
}
}
func (c character) Equal(other Token) bool {
if c.Type() != other.Type() {
return false
}
o := other.(*character)
return c.Rune() == o.Rune()
}
func (c character) String() string {
return fmt.Sprintf("{character: %s flag: %s}", string(c.Rune()), c.Flag().String())
}
func (c character) Rune() rune {
return c.r
}
// dot is any character. It implements Token.
type dot struct {
token
}
func NewDot() Token {
return &dot{
token: token{ttype: TTDot},
}
}
func (d dot) Equal(other Token) bool {
return d.Type() == other.Type()
}
func (d dot) String() string {
return fmt.Sprintf("{dot flag: %s}", d.Flag().String())
}
// set is a set of characters (similar to regexp character class).
// It implements Token.
type set struct {
token
runes map[rune]bool
}
func NewSet(runes []rune) Token {
m := map[rune]bool{}
for _, r := range runes {
m[r] = true
}
return &set{
token: token{ttype: TTSet},
runes: m,
}
}
func (s set) Equal(other Token) bool {
if s.Type() != other.Type() {
return false
}
o := other.(*set)
r1, r2 := s.Runes(), o.Runes()
if len(r1) != len(r2) {
return false
}
for k, _ := range r1 {
if _, ok := r2[k]; !ok {
return false
}
}
return true
}
func (s set) String() string {
rs := make([]string, 0, 30)
for r, _ := range s.Runes() {
rs = append(rs, string(r))
}
return fmt.Sprintf("{set: %s flag: %s}", strings.Join(rs, ""), s.Flag().String())
}
func (s set) Runes() map[rune]bool {
return s.runes
}