mirror of https://github.com/tailscale/tailscale/
util/stringsx: add package for extra string functions, like CompareFold
Noted as useful during review of #14448. Updates #14457 Change-Id: I0f16f08d5b05a8e9044b19ef6c02d3dab497f131 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>pull/14463/head
parent
4267d0fc5b
commit
9e2819b5d4
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// Package stringsx provides additional string manipulation functions
|
||||||
|
// that aren't in the standard library's strings package or go4.org/mem.
|
||||||
|
package stringsx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CompareFold returns -1, 0, or 1 depending on whether a < b, a == b, or a > b,
|
||||||
|
// like cmp.Compare, but case insensitively.
|
||||||
|
func CompareFold(a, b string) int {
|
||||||
|
// Track our position in both strings
|
||||||
|
ia, ib := 0, 0
|
||||||
|
for ia < len(a) && ib < len(b) {
|
||||||
|
ra, wa := nextRuneLower(a[ia:])
|
||||||
|
rb, wb := nextRuneLower(b[ib:])
|
||||||
|
if ra < rb {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if ra > rb {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
ia += wa
|
||||||
|
ib += wb
|
||||||
|
if wa == 0 || wb == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've reached here, one or both strings are exhausted
|
||||||
|
// The shorter string is "less than" if they match up to this point
|
||||||
|
switch {
|
||||||
|
case ia == len(a) && ib == len(b):
|
||||||
|
return 0
|
||||||
|
case ia == len(a):
|
||||||
|
return -1
|
||||||
|
default:
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nextRuneLower returns the next rune in the string, lowercased, along with its
|
||||||
|
// original (consumed) width in bytes. If the string is empty, it returns
|
||||||
|
// (utf8.RuneError, 0)
|
||||||
|
func nextRuneLower(s string) (r rune, width int) {
|
||||||
|
r, width = utf8.DecodeRuneInString(s)
|
||||||
|
return unicode.ToLower(r), width
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue