Update dependencies
This commit is contained in:
185
vendor/tailscale.com/tstime/tstime.go
generated
vendored
Normal file
185
vendor/tailscale.com/tstime/tstime.go
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package tstime defines Tailscale-specific time utilities.
|
||||
package tstime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Parse3339 is a wrapper around time.Parse(time.RFC3339, s).
|
||||
func Parse3339(s string) (time.Time, error) {
|
||||
return time.Parse(time.RFC3339, s)
|
||||
}
|
||||
|
||||
// Parse3339B is Parse3339 but for byte slices.
|
||||
func Parse3339B(b []byte) (time.Time, error) {
|
||||
var t time.Time
|
||||
if err := t.UnmarshalText(b); err != nil {
|
||||
return Parse3339(string(b)) // reproduce same error message
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// ParseDuration is more expressive than [time.ParseDuration],
|
||||
// also accepting 'd' (days) and 'w' (weeks) literals.
|
||||
func ParseDuration(s string) (time.Duration, error) {
|
||||
for {
|
||||
end := strings.IndexAny(s, "dw")
|
||||
if end < 0 {
|
||||
break
|
||||
}
|
||||
start := end - (len(s[:end]) - len(strings.TrimRight(s[:end], "0123456789")))
|
||||
n, err := strconv.Atoi(s[start:end])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hours := 24
|
||||
if s[end] == 'w' {
|
||||
hours *= 7
|
||||
}
|
||||
s = s[:start] + s[end+1:] + strconv.Itoa(n*hours) + "h"
|
||||
}
|
||||
return time.ParseDuration(s)
|
||||
}
|
||||
|
||||
// Sleep is like [time.Sleep] but returns early upon context cancelation.
|
||||
// It reports whether the full sleep duration was achieved.
|
||||
func Sleep(ctx context.Context, d time.Duration) bool {
|
||||
timer := time.NewTimer(d)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return false
|
||||
case <-timer.C:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultClock is a wrapper around a Clock.
|
||||
// It uses StdClock by default if Clock is nil.
|
||||
type DefaultClock struct{ Clock }
|
||||
|
||||
// TODO: We should make the methods of DefaultClock inlineable
|
||||
// so that we can optimize for the common case where c.Clock == nil.
|
||||
|
||||
func (c DefaultClock) Now() time.Time {
|
||||
if c.Clock == nil {
|
||||
return time.Now()
|
||||
}
|
||||
return c.Clock.Now()
|
||||
}
|
||||
func (c DefaultClock) NewTimer(d time.Duration) (TimerController, <-chan time.Time) {
|
||||
if c.Clock == nil {
|
||||
t := time.NewTimer(d)
|
||||
return t, t.C
|
||||
}
|
||||
return c.Clock.NewTimer(d)
|
||||
}
|
||||
func (c DefaultClock) NewTicker(d time.Duration) (TickerController, <-chan time.Time) {
|
||||
if c.Clock == nil {
|
||||
t := time.NewTicker(d)
|
||||
return t, t.C
|
||||
}
|
||||
return c.Clock.NewTicker(d)
|
||||
}
|
||||
func (c DefaultClock) AfterFunc(d time.Duration, f func()) TimerController {
|
||||
if c.Clock == nil {
|
||||
return time.AfterFunc(d, f)
|
||||
}
|
||||
return c.Clock.AfterFunc(d, f)
|
||||
}
|
||||
func (c DefaultClock) Since(t time.Time) time.Duration {
|
||||
if c.Clock == nil {
|
||||
return time.Since(t)
|
||||
}
|
||||
return c.Clock.Since(t)
|
||||
}
|
||||
|
||||
// Clock offers a subset of the functionality from the std/time package.
|
||||
// Normally, applications will use the StdClock implementation that calls the
|
||||
// appropriate std/time exported funcs. The advantage of using Clock is that
|
||||
// tests can substitute a different implementation, allowing the test to control
|
||||
// time precisely, something required for certain types of tests to be possible
|
||||
// at all, speeds up execution by not needing to sleep, and can dramatically
|
||||
// reduce the risk of flakes due to tests executing too slowly or quickly.
|
||||
type Clock interface {
|
||||
// Now returns the current time, as in time.Now.
|
||||
Now() time.Time
|
||||
// NewTimer returns a timer whose notion of the current time is controlled
|
||||
// by this Clock. It follows the semantics of time.NewTimer as closely as
|
||||
// possible but is adapted to return an interface, so the channel needs to
|
||||
// be returned as well.
|
||||
NewTimer(d time.Duration) (TimerController, <-chan time.Time)
|
||||
// NewTicker returns a ticker whose notion of the current time is controlled
|
||||
// by this Clock. It follows the semantics of time.NewTicker as closely as
|
||||
// possible but is adapted to return an interface, so the channel needs to
|
||||
// be returned as well.
|
||||
NewTicker(d time.Duration) (TickerController, <-chan time.Time)
|
||||
// AfterFunc returns a ticker whose notion of the current time is controlled
|
||||
// by this Clock. When the ticker expires, it will call the provided func.
|
||||
// It follows the semantics of time.AfterFunc.
|
||||
AfterFunc(d time.Duration, f func()) TimerController
|
||||
// Since returns the time elapsed since t.
|
||||
// It follows the semantics of time.Since.
|
||||
Since(t time.Time) time.Duration
|
||||
}
|
||||
|
||||
// TickerController offers the receivers of a time.Ticker to ensure
|
||||
// compatibility with standard timers, but allows for the option of substituting
|
||||
// a standard timer with something else for testing purposes.
|
||||
type TickerController interface {
|
||||
// Reset follows the same semantics as with time.Ticker.Reset.
|
||||
Reset(d time.Duration)
|
||||
// Stop follows the same semantics as with time.Ticker.Stop.
|
||||
Stop()
|
||||
}
|
||||
|
||||
// TimerController offers the receivers of a time.Timer to ensure
|
||||
// compatibility with standard timers, but allows for the option of substituting
|
||||
// a standard timer with something else for testing purposes.
|
||||
type TimerController interface {
|
||||
// Reset follows the same semantics as with time.Timer.Reset.
|
||||
Reset(d time.Duration) bool
|
||||
// Stop follows the same semantics as with time.Timer.Stop.
|
||||
Stop() bool
|
||||
}
|
||||
|
||||
// StdClock is a simple implementation of Clock using the relevant funcs in the
|
||||
// std/time package.
|
||||
type StdClock struct{}
|
||||
|
||||
// Now calls time.Now.
|
||||
func (StdClock) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
// NewTimer calls time.NewTimer. As an interface does not allow for struct
|
||||
// members and other packages cannot add receivers to another package, the
|
||||
// channel is also returned because it would be otherwise inaccessible.
|
||||
func (StdClock) NewTimer(d time.Duration) (TimerController, <-chan time.Time) {
|
||||
t := time.NewTimer(d)
|
||||
return t, t.C
|
||||
}
|
||||
|
||||
// NewTicker calls time.NewTicker. As an interface does not allow for struct
|
||||
// members and other packages cannot add receivers to another package, the
|
||||
// channel is also returned because it would be otherwise inaccessible.
|
||||
func (StdClock) NewTicker(d time.Duration) (TickerController, <-chan time.Time) {
|
||||
t := time.NewTicker(d)
|
||||
return t, t.C
|
||||
}
|
||||
|
||||
// AfterFunc calls time.AfterFunc.
|
||||
func (StdClock) AfterFunc(d time.Duration, f func()) TimerController {
|
||||
return time.AfterFunc(d, f)
|
||||
}
|
||||
|
||||
// Since calls time.Since.
|
||||
func (StdClock) Since(t time.Time) time.Duration {
|
||||
return time.Since(t)
|
||||
}
|
||||
Reference in New Issue
Block a user