feat: gitea client
This commit is contained in:
236
vendor/github.com/alecthomas/kong/scanner.go
generated
vendored
Normal file
236
vendor/github.com/alecthomas/kong/scanner.go
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
package kong
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TokenType is the type of a token.
|
||||
type TokenType int
|
||||
|
||||
// Token types.
|
||||
const (
|
||||
UntypedToken TokenType = iota
|
||||
EOLToken
|
||||
FlagToken // --<flag>
|
||||
FlagValueToken // =<value>
|
||||
ShortFlagToken // -<short>[<tail]
|
||||
ShortFlagTailToken // <tail>
|
||||
PositionalArgumentToken // <arg>
|
||||
)
|
||||
|
||||
func (t TokenType) String() string {
|
||||
switch t {
|
||||
case UntypedToken:
|
||||
return "untyped"
|
||||
case EOLToken:
|
||||
return "<EOL>"
|
||||
case FlagToken: // --<flag>
|
||||
return "long flag"
|
||||
case FlagValueToken: // =<value>
|
||||
return "flag value"
|
||||
case ShortFlagToken: // -<short>[<tail]
|
||||
return "short flag"
|
||||
case ShortFlagTailToken: // <tail>
|
||||
return "short flag remainder"
|
||||
case PositionalArgumentToken: // <arg>
|
||||
return "positional argument"
|
||||
}
|
||||
panic("unsupported type")
|
||||
}
|
||||
|
||||
// Token created by Scanner.
|
||||
type Token struct {
|
||||
Value any
|
||||
Type TokenType
|
||||
}
|
||||
|
||||
func (t Token) String() string {
|
||||
switch t.Type {
|
||||
case FlagToken:
|
||||
return fmt.Sprintf("--%v", t.Value)
|
||||
|
||||
case ShortFlagToken:
|
||||
return fmt.Sprintf("-%v", t.Value)
|
||||
|
||||
case EOLToken:
|
||||
return "EOL"
|
||||
|
||||
default:
|
||||
return fmt.Sprintf("%v", t.Value)
|
||||
}
|
||||
}
|
||||
|
||||
// IsEOL returns true if this Token is past the end of the line.
|
||||
func (t Token) IsEOL() bool {
|
||||
return t.Type == EOLToken
|
||||
}
|
||||
|
||||
// IsAny returns true if the token's type is any of those provided.
|
||||
func (t TokenType) IsAny(types ...TokenType) bool {
|
||||
for _, typ := range types {
|
||||
if t == typ {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// InferredType tries to infer the type of a token.
|
||||
func (t Token) InferredType() TokenType {
|
||||
if t.Type != UntypedToken {
|
||||
return t.Type
|
||||
}
|
||||
if v, ok := t.Value.(string); ok {
|
||||
if strings.HasPrefix(v, "--") { //nolint: gocritic
|
||||
return FlagToken
|
||||
} else if v == "-" {
|
||||
return PositionalArgumentToken
|
||||
} else if strings.HasPrefix(v, "-") {
|
||||
return ShortFlagToken
|
||||
}
|
||||
}
|
||||
return t.Type
|
||||
}
|
||||
|
||||
// IsValue returns true if token is usable as a parseable value.
|
||||
//
|
||||
// A parseable value is either a value typed token, or an untyped token NOT starting with a hyphen.
|
||||
func (t Token) IsValue() bool {
|
||||
tt := t.InferredType()
|
||||
return tt.IsAny(FlagValueToken, ShortFlagTailToken, PositionalArgumentToken) ||
|
||||
(tt == UntypedToken && !strings.HasPrefix(t.String(), "-"))
|
||||
}
|
||||
|
||||
// Scanner is a stack-based scanner over command-line tokens.
|
||||
//
|
||||
// Initially all tokens are untyped. As the parser consumes tokens it assigns types, splits tokens, and pushes them back
|
||||
// onto the stream.
|
||||
//
|
||||
// For example, the token "--foo=bar" will be split into the following by the parser:
|
||||
//
|
||||
// [{FlagToken, "foo"}, {FlagValueToken, "bar"}]
|
||||
type Scanner struct {
|
||||
allowHyphenated bool
|
||||
args []Token
|
||||
}
|
||||
|
||||
// ScanAsType creates a new Scanner from args with the given type.
|
||||
func ScanAsType(ttype TokenType, args ...string) *Scanner {
|
||||
s := &Scanner{}
|
||||
for _, arg := range args {
|
||||
s.args = append(s.args, Token{Value: arg, Type: ttype})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Scan creates a new Scanner from args with untyped tokens.
|
||||
func Scan(args ...string) *Scanner {
|
||||
return ScanAsType(UntypedToken, args...)
|
||||
}
|
||||
|
||||
// ScanFromTokens creates a new Scanner from a slice of tokens.
|
||||
func ScanFromTokens(tokens ...Token) *Scanner {
|
||||
return &Scanner{args: tokens}
|
||||
}
|
||||
|
||||
// AllowHyphenPrefixedParameters enables or disables hyphen-prefixed flag parameters on this Scanner.
|
||||
//
|
||||
// Disabled by default.
|
||||
func (s *Scanner) AllowHyphenPrefixedParameters(enable bool) *Scanner {
|
||||
s.allowHyphenated = enable
|
||||
return s
|
||||
}
|
||||
|
||||
// Len returns the number of input arguments.
|
||||
func (s *Scanner) Len() int {
|
||||
return len(s.args)
|
||||
}
|
||||
|
||||
// Pop the front token off the Scanner.
|
||||
func (s *Scanner) Pop() Token {
|
||||
if len(s.args) == 0 {
|
||||
return Token{Type: EOLToken}
|
||||
}
|
||||
arg := s.args[0]
|
||||
s.args = s.args[1:]
|
||||
return arg
|
||||
}
|
||||
|
||||
type expectedError struct {
|
||||
context string
|
||||
token Token
|
||||
}
|
||||
|
||||
func (e *expectedError) Error() string {
|
||||
return fmt.Sprintf("expected %s value but got %q (%s)", e.context, e.token, e.token.InferredType())
|
||||
}
|
||||
|
||||
// PopValue pops a value token, or returns an error.
|
||||
//
|
||||
// "context" is used to assist the user if the value can not be popped, eg. "expected <context> value but got <type>"
|
||||
func (s *Scanner) PopValue(context string) (Token, error) {
|
||||
t := s.Pop()
|
||||
if !s.allowHyphenated && !t.IsValue() {
|
||||
return t, &expectedError{context, t}
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// PopValueInto pops a value token into target or returns an error.
|
||||
//
|
||||
// "context" is used to assist the user if the value can not be popped, eg. "expected <context> value but got <type>"
|
||||
func (s *Scanner) PopValueInto(context string, target any) error {
|
||||
t, err := s.PopValue(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonTranscode(t.Value, target)
|
||||
}
|
||||
|
||||
// PopWhile predicate returns true.
|
||||
func (s *Scanner) PopWhile(predicate func(Token) bool) (values []Token) {
|
||||
for predicate(s.Peek()) {
|
||||
values = append(values, s.Pop())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// PopUntil predicate returns true.
|
||||
func (s *Scanner) PopUntil(predicate func(Token) bool) (values []Token) {
|
||||
for !predicate(s.Peek()) {
|
||||
values = append(values, s.Pop())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Peek at the next Token or return an EOLToken.
|
||||
func (s *Scanner) Peek() Token {
|
||||
if len(s.args) == 0 {
|
||||
return Token{Type: EOLToken}
|
||||
}
|
||||
return s.args[0]
|
||||
}
|
||||
|
||||
// PeekAll remaining tokens
|
||||
func (s *Scanner) PeekAll() []Token {
|
||||
return s.args
|
||||
}
|
||||
|
||||
// Push an untyped Token onto the front of the Scanner.
|
||||
func (s *Scanner) Push(arg any) *Scanner {
|
||||
s.PushToken(Token{Value: arg})
|
||||
return s
|
||||
}
|
||||
|
||||
// PushTyped pushes a typed token onto the front of the Scanner.
|
||||
func (s *Scanner) PushTyped(arg any, typ TokenType) *Scanner {
|
||||
s.PushToken(Token{Value: arg, Type: typ})
|
||||
return s
|
||||
}
|
||||
|
||||
// PushToken pushes a preconstructed Token onto the front of the Scanner.
|
||||
func (s *Scanner) PushToken(token Token) *Scanner {
|
||||
s.args = append([]Token{token}, s.args...)
|
||||
return s
|
||||
}
|
||||
Reference in New Issue
Block a user