mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
util/slicesx: add FirstElementEqual and LastElementEqual
And update a few callers as examples of motivation. (there are a couple others, but these are the ones where it's prettier) Updates #cleanup Change-Id: Ic8c5cb7af0a59c6e790a599136b591ebe16d38eb Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
910462a8e0
commit
cec779e771
@ -47,6 +47,7 @@
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/set"
|
||||
"tailscale.com/util/slicesx"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
|
||||
@ -1323,7 +1324,7 @@ func (s *Server) noteClientActivity(c *sclient) {
|
||||
cs.activeClient.Store(c)
|
||||
}
|
||||
|
||||
if sh := dup.sendHistory; len(sh) != 0 && sh[len(sh)-1] == c {
|
||||
if slicesx.LastEqual(dup.sendHistory, c) {
|
||||
// The client c was the last client to make activity
|
||||
// in this set and it was already recorded. Nothing to
|
||||
// do.
|
||||
|
@ -45,6 +45,7 @@
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/httpm"
|
||||
"tailscale.com/util/mak"
|
||||
"tailscale.com/util/slicesx"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -330,7 +331,7 @@ func (c *conn) nextAuthMethodCallback(cm gossh.ConnMetadata, prevErrors []error)
|
||||
switch {
|
||||
case c.anyPasswordIsOkay:
|
||||
nextMethod = append(nextMethod, "password")
|
||||
case len(prevErrors) > 0 && prevErrors[len(prevErrors)-1] == errPubKeyRequired:
|
||||
case slicesx.LastEqual(prevErrors, errPubKeyRequired):
|
||||
nextMethod = append(nextMethod, "publickey")
|
||||
}
|
||||
|
||||
|
@ -10,11 +10,13 @@
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"tailscale.com/util/slicesx"
|
||||
)
|
||||
|
||||
func formatMaybePrintable(b []byte) string {
|
||||
// Remove a single trailing null, if any
|
||||
if len(b) > 0 && b[len(b)-1] == 0 {
|
||||
// Remove a single trailing null, if any.
|
||||
if slicesx.LastEqual(b, 0) {
|
||||
b = b[:len(b)-1]
|
||||
}
|
||||
|
||||
|
@ -136,3 +136,15 @@ func CutSuffix[E comparable](s, suffix []E) (after []E, found bool) {
|
||||
}
|
||||
return s[:len(s)-len(suffix)], true
|
||||
}
|
||||
|
||||
// FirstEqual reports whether len(s) > 0 and
|
||||
// its first element == v.
|
||||
func FirstEqual[T comparable](s []T, v T) bool {
|
||||
return len(s) > 0 && s[0] == v
|
||||
}
|
||||
|
||||
// LastEqual reports whether len(s) > 0 and
|
||||
// its last element == v.
|
||||
func LastEqual[T comparable](s []T, v T) bool {
|
||||
return len(s) > 0 && s[len(s)-1] == v
|
||||
}
|
||||
|
@ -197,3 +197,28 @@ func TestCutSuffix(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFirstLastEqual(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in string
|
||||
v byte
|
||||
f func([]byte, byte) bool
|
||||
want bool
|
||||
}{
|
||||
{"first-empty", "", 'f', FirstEqual[byte], false},
|
||||
{"first-true", "foo", 'f', FirstEqual[byte], true},
|
||||
{"first-false", "foo", 'b', FirstEqual[byte], false},
|
||||
{"last-empty", "", 'f', LastEqual[byte], false},
|
||||
{"last-true", "bar", 'r', LastEqual[byte], true},
|
||||
{"last-false", "bar", 'o', LastEqual[byte], false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.f([]byte(tt.in), tt.v); got != tt.want {
|
||||
t.Errorf("got %v; want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user