mirror of
https://github.com/kubernetes/node-problem-detector.git
synced 2026-08-28 01:47:20 +00:00
- Update github.com/sirupsen/logrus v1.9.0 -> v1.9.3 in test/go.mod to fix GHSA-4f99-4q7p-p3gh (High) - Update github.com/prometheus/prometheus v0.35.0 -> v0.311.3 to fix GHSA-vffh-x6r8-xx99 (Medium) - Run go mod tidy and go mod vendor to update vendor directory
187 lines
4.2 KiB
Go
187 lines
4.2 KiB
Go
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package mangling
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
type (
|
|
lexemKind uint8
|
|
|
|
nameLexem struct {
|
|
original string
|
|
matchedInitialism string
|
|
kind lexemKind
|
|
}
|
|
)
|
|
|
|
const (
|
|
lexemKindCasualName lexemKind = iota
|
|
lexemKindInitialismName
|
|
)
|
|
|
|
func newInitialismNameLexem(original, matchedInitialism string) nameLexem {
|
|
return nameLexem{
|
|
kind: lexemKindInitialismName,
|
|
original: original,
|
|
matchedInitialism: matchedInitialism,
|
|
}
|
|
}
|
|
|
|
func newCasualNameLexem(original string) nameLexem {
|
|
return nameLexem{
|
|
kind: lexemKindCasualName,
|
|
original: trim(original), // TODO: save on calls to trim
|
|
}
|
|
}
|
|
|
|
// WriteTitleized writes the titleized lexeme to a bytes.Buffer.
|
|
//
|
|
// If the first letter cannot be capitalized, it doesn't write anything and return false,
|
|
// so the caller may attempt some workaround strategy.
|
|
func (l nameLexem) WriteTitleized(w *bytes.Buffer, alwaysUpper bool) bool {
|
|
if l.kind == lexemKindInitialismName {
|
|
w.WriteString(l.matchedInitialism)
|
|
|
|
return true
|
|
}
|
|
|
|
if len(l.original) == 0 {
|
|
return true
|
|
}
|
|
|
|
if len(l.original) == 1 {
|
|
// identifier is too short: casing will depend on the context
|
|
firstByte := l.original[0]
|
|
switch {
|
|
case 'A' <= firstByte && firstByte <= 'Z':
|
|
// safe
|
|
w.WriteByte(firstByte)
|
|
|
|
return true
|
|
case alwaysUpper && 'a' <= firstByte && firstByte <= 'z':
|
|
w.WriteByte(firstByte - 'a' + 'A')
|
|
|
|
return true
|
|
default:
|
|
|
|
// not a letter: skip and let the caller decide
|
|
return false
|
|
}
|
|
}
|
|
|
|
if firstByte := l.original[0]; firstByte < utf8.RuneSelf {
|
|
// ASCII
|
|
switch {
|
|
case 'A' <= firstByte && firstByte <= 'Z':
|
|
// already an upper case letter
|
|
w.WriteString(l.original)
|
|
|
|
return true
|
|
case 'a' <= firstByte && firstByte <= 'z':
|
|
w.WriteByte(firstByte - 'a' + 'A')
|
|
w.WriteString(l.original[1:])
|
|
|
|
return true
|
|
default:
|
|
// not a good candidate: doesn't start with a letter
|
|
return false
|
|
}
|
|
}
|
|
|
|
// unicode
|
|
firstRune, idx := utf8.DecodeRuneInString(l.original)
|
|
if !unicode.IsLetter(firstRune) || !unicode.IsUpper(unicode.ToUpper(firstRune)) {
|
|
// not a good candidate: doesn't start with a letter
|
|
// or a rune for which case doesn't make sense (e.g. East-Asian runes etc)
|
|
return false
|
|
}
|
|
|
|
rest := l.original[idx:]
|
|
w.WriteRune(unicode.ToUpper(firstRune))
|
|
w.WriteString(strings.ToLower(rest))
|
|
|
|
return true
|
|
}
|
|
|
|
// WriteLower is like write titleized but it writes a lower-case version of the lexeme.
|
|
//
|
|
// Similarly, there is no writing if the casing of the first rune doesn't make sense.
|
|
func (l nameLexem) WriteLower(w *bytes.Buffer, alwaysLower bool) bool {
|
|
if l.kind == lexemKindInitialismName {
|
|
w.WriteString(lower(l.matchedInitialism))
|
|
|
|
return true
|
|
}
|
|
|
|
if len(l.original) == 0 {
|
|
return true
|
|
}
|
|
|
|
if len(l.original) == 1 {
|
|
// identifier is too short: casing will depend on the context
|
|
firstByte := l.original[0]
|
|
switch {
|
|
case 'a' <= firstByte && firstByte <= 'z':
|
|
// safe
|
|
w.WriteByte(firstByte)
|
|
|
|
return true
|
|
case alwaysLower && 'A' <= firstByte && firstByte <= 'Z':
|
|
w.WriteByte(firstByte - 'A' + 'a')
|
|
|
|
return true
|
|
default:
|
|
|
|
// not a letter: skip and let the caller decide
|
|
return false
|
|
}
|
|
}
|
|
|
|
if firstByte := l.original[0]; firstByte < utf8.RuneSelf {
|
|
// ASCII
|
|
switch {
|
|
case 'a' <= firstByte && firstByte <= 'z':
|
|
// already a lower case letter
|
|
w.WriteString(l.original)
|
|
|
|
return true
|
|
case 'A' <= firstByte && firstByte <= 'Z':
|
|
w.WriteByte(firstByte - 'A' + 'a')
|
|
w.WriteString(l.original[1:])
|
|
|
|
return true
|
|
default:
|
|
// not a good candidate: doesn't start with a letter
|
|
return false
|
|
}
|
|
}
|
|
|
|
// unicode
|
|
firstRune, idx := utf8.DecodeRuneInString(l.original)
|
|
if !unicode.IsLetter(firstRune) || !unicode.IsLower(unicode.ToLower(firstRune)) {
|
|
// not a good candidate: doesn't start with a letter
|
|
// or a rune for which case doesn't make sense (e.g. East-Asian runes etc)
|
|
return false
|
|
}
|
|
|
|
rest := l.original[idx:]
|
|
w.WriteRune(unicode.ToLower(firstRune))
|
|
w.WriteString(rest)
|
|
|
|
return true
|
|
}
|
|
|
|
func (l nameLexem) GetOriginal() string {
|
|
return l.original
|
|
}
|
|
|
|
func (l nameLexem) IsInitialism() bool {
|
|
return l.kind == lexemKindInitialismName
|
|
}
|