core

package module
v0.18.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2025 License: MIT Imports: 21 Imported by: 87

README

Core helpers for darvaza.org projects

Go Reference Go Report Card codecov

This package contains simple mechanisms used by other darvaza.org projects. It's not allowed to have dependencies outside of Go's Standard Library, and if something should be on a subdirectory, it shouldn't be here.

Type Constraints

Generic type constraints for use with Go generics:

  • Signed - signed integer types.
  • Unsigned - unsigned integer types.
  • Integer - all integer types (signed and unsigned).
  • Float - floating-point types.
  • Complex - complex number types.
  • Bool - boolean type.
  • String - string type.
  • Ordered - types that support ordering operations.

Context

Context Keys
  • NewContextKey[T](name) - creates a new type-safe key bound to specified type and friendly name.
  • ContextKey[T].WithValue(ctx, value) - safely attach value to context, comparable to standard context.WithValue().
  • ContextKey[T].Get(ctx) - extracts value bound to this key in context, returns (value, found) with nil receiver safety.
Timeout Utilities
  • WithTimeout(parent, duration) - equivalent to context.WithDeadline() but takes duration instead of absolute time. Returns parent context and no-op cancel for zero/negative durations.
  • WithTimeoutCause(parent, duration, cause) - equivalent to context.WithDeadlineCause() but takes duration instead of absolute time. Attaches custom cause error to timeout context.

Network Utilities

IP Address Functions
  • GetIPAddresses() - get IP addresses as netip.Addr.
  • GetNetIPAddresses() - get IP addresses as net.IP.
  • GetStringIPAddresses() - get IP addresses as strings.
  • AddrFromNetIP(ip) - convert net.IP to netip.Addr.
  • ParseAddr(s) - parse string to netip.Addr.
  • ParseNetIP(s) - parse string to net.IP.
Host/Port Functions
Parsing and Splitting
  • SplitHostPort(hostport) - enhanced version of net.SplitHostPort that accepts portless strings and validates both host and port. Supports IPv6 addresses, international domain names, and descriptive error messages.
  • SplitAddrPort(addrport) - splits IP address and optional port into netip.Addr and uint16. Validates address format and port range (1-65535), returns zero values for portless addresses.
Joining and Construction
  • JoinHostPort(host, port) - enhanced version of net.JoinHostPort that validates inputs and returns portless host when port is empty. Properly handles IPv6 bracketing and international domain names.
  • MakeHostPort(hostport, defaultPort) - constructs validated host:port string from input with optional default port. Rejects port 0 in input, supports portless output when default is 0.
  • AddrPort(v) - extracts netip.AddrPort from various network types (*net.TCPAddr, *net.UDPAddr, etc.), returns (AddrPort, bool).
Interface Functions
  • GetInterfacesNames() - get network interface names.

Generic Utilities

Zero Value Utilities
Zero Value Creation
  • Zero[T](_ *T) - returns the zero value for type T using a typed nil pointer for type inference. Supports all Go types including complex generics, interfaces, and custom types.
Zero Value Detection
  • IsZero(v) - reports whether a value is in an uninitialized state and ready to be set. Answers the question: "Is this value uninitialized and ready to be set?"

Key semantic distinctions:

  • Nil vs Empty: []int(nil) returns true (needs initialization), []int{} returns false (already initialized).
  • Pointer States: (*int)(nil) returns true (can be assigned), new(int) returns false (already points to memory).
  • Interface Support: Types implementing IsZero() bool are handled via their method, enabling custom zero semantics.
Nil Value Detection
  • IsNil(v) - reports whether a value is nil (typed or untyped). Answers the question: "Is this value nil?"

Key distinctions from IsZero:

  • Scope: Only checks for nil state, not zero state.
  • Basic Types: IsNil(0) returns false (integers cannot be nil), IsZero(0) returns true (zero integer is uninitialized).
  • Collections: IsNil([]int{}) returns false (empty slice is not nil), IsZero([]int{}) returns false (empty slice is initialized).
  • Structs: IsNil(struct{}{}) returns false (structs cannot be nil), IsZero(struct{}{}) returns true (zero struct is uninitialized).
Same Value Detection
  • IsSame(a, b) - reports whether two values are the same. For reference types (slices, maps, pointers), compares by pointer equality. For value types (numbers, strings, booleans), compares by equal values. Two nils of the same type are considered the same.
Other Utilities
  • Coalesce[T](values...) returns the first non-zero value.
  • IIf[T](condition, ifTrue, ifFalse) conditional expression.
Type Conversion
  • As[T,V](v) attempts to convert value to target type
  • AsFn[T,V](v, fn) converts value using a provided function
  • AsError[T](v) attempts to convert value to error
  • AsErrors[T](v) attempts to convert value to error slice
Slice Operations
Search and Comparison
  • SliceContains[T](slice, value) - check if slice contains value.
  • SliceContainsFn[T](slice, value, eq) - check containment with custom equality.
  • SliceEqual[T](a, b) - compare two slices for equality.
  • SliceEqualFn[T](a, b, eq) - compare slices with custom equality function.
Transformation
  • SliceAs[T,V] / SliceAsFn[T,V] - convert slice elements to different type.
  • SliceMap[T1,T2](slice, fn) - transform each element with cumulative function.
  • SliceReplaceFn[T](slice, fn) - replace/filter elements in-place.
  • SliceCopy[T](slice) - create shallow copy of slice.
  • SliceCopyFn[T](slice, fn) - create filtered/transformed copy.
Set Operations
  • SliceMinus[T](a, b) - elements in a but not in b.
  • SliceMinusFn[T](a, b, eq) - set difference with custom equality.
  • SliceUnique[T](slice) - return slice with unique elements only.
  • SliceUniqueFn[T](slice, eq) - unique elements with custom equality.
  • SliceUniquify[T](ptr) - remove duplicates in-place, modify original.
  • SliceUniquifyFn[T](ptr, eq) - remove duplicates with custom equality.
Sorting and Ordering
  • SliceSort[T](slice, cmp) - sort using comparison function (returns int).
  • SliceSortFn[T](slice, less) - sort using less function (returns bool).
  • SliceSortOrdered[T](slice) - sort ordered types (int, string, float64).
  • SliceReverse[T](slice) - reverse slice in-place.
  • SliceReversed[T](slice) - return reversed copy.
  • SliceReversedFn[T](slice, fn) - return transformed and reversed copy.
Utilities
  • SliceRandom[T](slice) - select random element, returns (value, found).
  • SliceP[T](slice,p) - return the p-th percentile of the slice (p must be 0.0-1.0). Sorts the slice in-place. Returns the zero value for empty slices or invalid p.
List Operations (container/list)
Search and Membership
  • ListContains[T](list, value) - check if list contains element with default equality.
  • ListContainsFn[T](list, value, eq) - check if list contains element with custom equality function.
Iteration
  • ListForEach[T](list, fn) - iterate forward over list values until fn returns true.
  • ListForEachElement(list, fn) - iterate forward over list elements until fn returns true.
  • ListForEachBackward[T](list, fn) - iterate backward over list values until fn returns true.
  • ListForEachBackwardElement(list, fn) - iterate backward over list elements until fn returns true.
Copying and Transformation
  • ListCopy[T](list) - create shallow copy of list.
  • ListCopyFn[T](list, fn) - create filtered/transformed copy with helper function.
Map Operations
Basic Map Functions
  • MapContains[K]() checks if a map contains a key.
  • MapValue[K,V]() returns the value for a key, or a fallback value.
  • Keys[K,T]() returns a slice of the keys in the map.
  • SortedKeys[K,T]() returns a sorted slice of the keys.
  • SortedValues[K,T]() returns values sorted by key.
  • SortedValuesCond[K,T]() returns filtered values sorted by key.
  • SortedValuesUnlikelyCond[K,T]() like SortedValuesCond but more efficient.
Map List Operations
  • MapListContains[K,T] / MapListContainsFn[K,T]
  • MapListForEach[K,T] / MapListForEachElement[K]
  • MapListInsert[K,T] / MapListAppend[K,T]
  • MapListInsertUnique[K,T] / MapListInsertUniqueFn[K,T]
  • MapListAppendUnique[K,T] / MapListAppendUniqueFn[K,T]
  • MapListCopy[T] / MapListCopyFn[K,V]
Map All List Operations
  • MapAllListContains[K,T] / MapAllListContainsFn[K,T]
  • MapAllListForEach[K,T] / MapAllListForEachElement[K]

Error Handling

Standard Error Variables

Predefined error values for common conditions:

  • ErrNotImplemented - functionality not yet implemented.
  • ErrTODO - placeholder for future implementation.
  • ErrExists - resource already exists.
  • ErrNotExists - resource does not exist.
  • ErrInvalid - invalid input or state.
  • ErrUnknown - unknown or unspecified error.
  • ErrNilReceiver - method called on nil receiver.
  • ErrUnreachable - indicates impossible condition.
Error Wrapping

The Unwrappable interface represents the classic Unwrap() error pattern, implemented by WrappedError. The Errors interface represents multi-error containers with Errors() []error.

Error wrapping functions:

  • Wrap(err, note) - wrap with simple string note.
  • Wrapf(err, format, args...) - wrap with formatted note.
  • QuietWrap(err, note) - wrap without including original error text.
  • Unwrap(err) []error - extract all sub-errors from wrapped errors.
Compound Errors

The CompoundError type aggregates multiple errors:

  • Implements both Unwrap() []error and Errors() []error interfaces.
  • .AppendError(err) / .Append(errs...) - add errors.
  • .AsError() - convert to single error or nil.
  • .OK() - check if no errors.
Panic Handling

The PanicError type wraps panic values with stack traces:

  • NewPanicError() / NewPanicErrorf() - create panic errors.
  • NewPanicWrap() / NewPanicWrapf() - wrap existing errors as panics.
  • Panic() / Panicf() / PanicWrap() / PanicWrapf() - panic with PanicError.

Panic recovery utilities:

  • Recovered interface - marks errors from recovered panics.
  • AsRecovered(v) - convert recover() result to error.
  • Catcher type - safely call functions that might panic.
  • Catch(fn) - execute function, returning error if panic occurs.
defer func() {
  if err := core.AsRecovered(recover()); err != nil {
    // handle panic as error
  }
}()
Must/Maybe Utilities

Convenience functions for common error-handling patterns:

  • Must[T](value T, err error) T - returns value or panics with PanicError if err is not nil. Follows the common Go pattern of Must* functions for cases where errors should never occur.
  • Maybe[T](value T, err error) T - always returns the value, ignoring any error. When an error occurs, the returned value may be the zero value of type T depending on the function that produced it.
  • MustOK[T](value T, ok bool) T - returns value or panics with PanicError if ok is false. Useful for operations that should always succeed, such as map access or type assertions that are guaranteed to be valid.
  • MaybeOK[T](value T, ok bool) T - always returns the value, ignoring the ok flag. When ok is false, the returned value is typically the zero value of type T from the failed operation.
  • MustT[T](value any) T - equivalent to MustOK(As[any, T](value)). Returns converted value or panics with PanicError if type conversion fails.
  • MaybeT[T](value any) T - equivalent to MaybeOK(As[any, T](value)). Returns converted value on success, or the zero value of type T if conversion fails.

All these utilities work together with the As[any, T] function, which returns (value, ok) for type conversion, allowing custom handling of conversion failures.

// Must - panic on error (use in tests, config loading, etc.)
config := Must(loadConfig("config.json"))  // panics if loadConfig fails
conn := Must(net.Dial("tcp", "localhost:8080"))  // panics if dial fails

// Maybe - ignore errors, proceed with values (may be zero values)
content := Maybe(os.ReadFile("optional.txt"))  // []byte{} if file missing
count := Maybe(strconv.Atoi(userInput))       // 0 if parsing fails

// MustOK - panic on failure (use when operation should always succeed)
value := MustOK(MapValue(m, "key", 0))  // panics if key doesn't exist
str := MustOK(As[any, string](v))       // panics if v is not a string

// MaybeOK - ignore ok flag, proceed with values (zero values on failure)
value := MaybeOK(MapValue(m, "key", 0))  // 0 if key doesn't exist
str := MaybeOK(As[any, string](v))       // "" if type assertion fails

// MustT - equivalent to MustOK(As[any, T](value))
str := MustT[string](value)  // panics if value is not a string
num := MustT[int](value)     // panics if value is not an int

// MaybeT - equivalent to MaybeOK(As[any, T](value))
str := MaybeT[string](value)  // "" (zero value) if value is not a string
num := MaybeT[int](value)     // 0 (zero value) if value is not an int

// As - the building block for type conversion with custom handling
if str, ok := As[any, string](value); ok {
    // use converted string
} else {
    str = "custom default"  // your own fallback logic
}
Unreachable Conditions

For indicating impossible code paths:

  • NewUnreachableError() - create unreachable error.
  • NewUnreachableErrorf(format, args...) - create formatted unreachable error.

These create PanicError instances with stack traces.

Temporary and Timeout Errors

Special error types for network-style temporary and timeout conditions:

  • TemporaryError type - implements Temporary() bool and IsTemporary() bool interfaces for marking recoverable errors.
  • NewTemporaryError(err) - wrap error as temporary condition.
  • NewTimeoutError(err) - wrap error as timeout condition with both temporary and timeout properties.
  • IsTemporary(err) - recursively test if error chain contains temporary condition via Temporary() or IsTemporary() methods.
  • CheckIsTemporary(err) - test single error for temporary condition without unwrapping chain, returns (is, known) tuple.
  • IsTimeout(err) - recursively test if error chain contains timeout condition via Timeout() or IsTimeout() methods.
  • CheckIsTimeout(err) - test single error for timeout condition without unwrapping chain, returns (is, known) tuple.
Error Testing and Utilities
  • IsError(err, errs...) / IsErrorFn(check, errs...) / IsErrorFn2(check, errs...) - error testing with custom checker functions and multiple error comparison.
  • CoalesceError(errs...) - return first non-nil error from argument list.

Stack Tracing

Stack tracing utilities for debugging, error reporting, and call context:

Core Types
  • Frame - represents a single function call frame with source location.
  • Stack - slice of frames representing a complete call stack.
  • MaxDepth - maximum stack capture depth (32 frames).
  • CallStacker interface - types that can provide their call stack.
Stack Capture Functions
Frame Capture
  • Here() - capture the current stack frame where called. Returns nil if capture fails. Useful for immediate calling context.
  • StackFrame(skip) - capture a specific frame in the call stack, skipping the specified number of levels. Returns nil if insufficient frames.
Complete Stack Capture
  • StackTrace(skip) - capture complete call stack starting from skip level. Returns empty Stack on failure. Maximum depth limited by MaxDepth.
Frame Information Methods
Function Names
  • Frame.Name() - full qualified function name including package path (e.g., "darvaza.org/core.TestFunction").
  • Frame.FuncName() - function name only without package qualification (e.g., "TestFunction").
  • Frame.PkgName() - package path portion only (e.g., "darvaza.org/core").
  • Frame.SplitName() - split full name into (package, function) components. Handles generic functions by ignoring "[...]" suffixes.
Source Location
  • Frame.File() - full path to source file containing the function.
  • Frame.Line() - line number within source file (0 if unavailable).
  • Frame.FileLine() - formatted "file:line" string for display.
Formatting
  • Frame.Format(fmt.State, rune) - implements fmt.Formatter interface with support for multiple format verbs:

    • %s - source file basename.
    • %d - line number.
    • %n - function name (short form).
    • %v - equivalent to %s:%d.
    • %+s - function name + full file path (newline separated).
    • %+n - full qualified function name.
    • %+v - equivalent to %+s:%d.
  • Stack.Format(fmt.State, rune) - formats entire stack with same verbs as Frame plus '#' flag support:

    • %#s, %#n, %#v - each frame on new line.
    • %#+s, %#+n, %#+v - numbered frames with [index/total] prefix.
Usage Examples
// Capture current location
frame := Here()
if frame != nil {
    fmt.Printf("Called from %s at %s", frame.FuncName(), frame.FileLine())
}

// Capture complete stack for error reporting
stack := StackTrace(1) // skip current function
fmt.Printf("Stack trace:%+v", stack)

// Numbered stack output
fmt.Printf("Debug stack:%#+v", stack)

Testing Utilities

This package provides comprehensive public testing utilities for both internal library tests and external library users.

T Interface and MockT
  • T interface - abstracts testing functionality for both *testing.T and mock implementations.
  • MockT - thread-safe mock testing.T implementation with error/log collection, helper tracking, state inspection (HasErrors(), HasLogs(), LastError(), LastLog()), reset capabilities, and full Fatal/FailNow support with panic recovery via the Run() method.
Cross-Compatible Test Functions

For test utilities that need to work with both *testing.T and MockT, use interface type assertions to detect Run() method support. This enables nested subtests that gracefully degrade to direct function calls:

func doRun(t T, name string, fn func(T)) {
    switch tt := t.(type) {
    case interface { Run(string, func(*testing.T)) bool }:
        tt.Run(name, func(subT *testing.T) { fn(subT) })
    case interface { Run(string, func(T)) bool }:
        tt.Run(name, fn)
    default:
        fn(t) // Fallback for simple T implementations
    }
}
Test Helpers
  • S[T](values...) - concise slice creation: S(1, 2, 3) instead of []int{1, 2, 3}.
  • S[T]() - empty slice creation: S[string]() instead of []string{}.
Assertion Functions

All assertions return boolean results, log successful cases, and work with both *testing.T and MockT:

Basic Assertions
  • AssertEqual[T](t, expected, actual, name...) - generic value comparison.
  • AssertNotEqual[T](t, expected, actual, name...) - generic inequality comparison.
  • AssertSliceEqual[T](t, expected, actual, name...) - slice comparison using reflect.DeepEqual.
  • AssertSame(t, expected, actual, name...) - same value/reference comparison using pointer equality for reference types, value equality for basic types.
  • AssertNotSame(t, expected, actual, name...) - different value/reference comparison.
  • AssertTrue(t, condition, name...) / AssertFalse(t, condition, name...) - boolean assertions.
  • AssertNil(t, value, name...) / AssertNotNil(t, value, name...) - nil checking.
  • AssertContains(t, text, substring, name...) - string containment.
  • AssertNotContain(t, text, substring, name...) - string exclusion.
Error and Type Assertions
  • AssertError(t, err, name...) / AssertNoError(t, err, name...) - error presence/absence.
  • AssertErrorIs(t, err, target, name...) - error chain checking with errors.Is.
  • AssertTypeIs[T](t, value, name...) - type assertion with casting, returns (value, ok).
  • AssertPanic(t, fn, expectedPanic, name...) / AssertNoPanic(t, fn, name...) - panic testing with type-aware matching.
Fatal Assertions

All AssertMustFoo() functions call the corresponding AssertFoo() function and automatically call t.FailNow() if the assertion fails, terminating test execution immediately. These follow Go testing conventions where "Fatal" methods terminate execution, similar to t.Error() vs t.Fatal().

Key Differences:

  • AssertFoo() - like t.Error(), logs failure and allows test to continue.
  • AssertMustFoo() - like t.Fatal(), logs failure and terminates test execution.

Fatal Assertion Functions:

  • AssertMustEqual[T](t, expected, actual, name...) - terminate on inequality.
  • AssertMustNotEqual[T](t, expected, actual, name...) - terminate on equality.
  • AssertMustSliceEqual[T](t, expected, actual, name...) - terminate on slice inequality.
  • AssertMustTrue(t, condition, name...) / AssertMustFalse(t, condition, name...) - terminate on boolean mismatch.
  • AssertMustNil(t, value, name...) / AssertMustNotNil(t, value, name...) - terminate on nil check failure.
  • AssertMustContains(t, text, substring, name...) - terminate if substring not found.
  • AssertMustNotContain(t, text, substring, name...) - terminate if substring found.
  • AssertMustError(t, err, name...) / AssertMustNoError(t, err, name...) - terminate on error expectation mismatch.
  • AssertMustErrorIs(t, err, target, name...) - terminate on error chain mismatch.
  • AssertMustTypeIs[T](t, value, name...) T - terminate on type assertion failure, returns cast value.
  • AssertMustPanic(t, fn, expectedPanic, name...) / AssertMustNoPanic(t, fn, name...) - terminate on panic expectation mismatch.
  • AssertMustSame(t, expected, actual, name...) / AssertMustNotSame(t, expected, actual, name...) - terminate on same-ness mismatch.

Usage Examples:

// Error pattern - logs failure, test continues
AssertEqual(t, expected, actual, "value check")
// execution continues even if assertion fails

// Fatal pattern - logs failure, test terminates
AssertMustEqual(t, expected, actual, "critical value check")
// execution stops here if assertion fails

// Traditional early abort pattern (equivalent to AssertMust*)
if !AssertEqual(t, expected, actual, "critical value") {
    t.FailNow()
}
Advanced Testing Utilities
  • TestCase interface - standardised interface for table-driven tests with Name() and Test(t) methods.
  • RunTestCases[T TestCase](t, cases) - table-driven test runner for TestCase implementations.
  • RunConcurrentTest(t, numWorkers, workerFn) - concurrent testing with goroutines.
  • RunBenchmark(b, setupFn, execFn) - benchmark testing with setup/execution phases.
Documentation

For detailed testing patterns and guidelines:

  • TESTING.md - General testing patterns for all darvaza.org projects
  • TESTING_core.md - Core-specific testing patterns and self-testing approaches

Synchronization

WaitGroup

Enhanced wait group with error handling:

  • WaitGroup - wait group that collects errors.
  • .OnError(fn) - set error handler.
  • .Go(fn) / .GoCatch(fn) - run functions in goroutines.
  • .Wait() - wait for completion.
  • .Err() - get first error.
ErrGroup

Context-aware error group with cancellation:

  • ErrGroup - context-based error group.
  • .SetDefaults() - configure with defaults.
  • .OnError(fn) - set error handler.
  • .Cancel() / .Context() - cancellation control.
  • .Go(fn) / .GoCatch(fn) - run functions with context.
  • .Wait() - wait and return first error.
  • .IsCancelled() / .Cancelled() - check cancellation state.
Deprecated

Development

Requirements: Go 1.23 or later

For detailed development setup, build commands, and AI agent guidance:

  • AGENTS.md - Development guidelines, build system, and testing patterns.
Quick Start
make all    # Full build cycle (get deps, generate, tidy, build)
make test   # Run tests
make tidy   # Format and tidy (run before committing)

See also

Documentation

Overview

Package core provides fundamental helpers for darvaza.org projects

Index

Constants

View Source
const (
	// MaxDepth is the maximum depth we will go in the stack.
	MaxDepth = 32
)

Variables

View Source
var (
	// ErrNotImplemented indicates something hasn't been implemented yet
	ErrNotImplemented = errors.New("not implemented")
	// ErrTODO is like ErrNotImplemented but used especially to
	// indicate something needs to be implemented
	ErrTODO = Wrap(ErrNotImplemented, "TODO")
	// ErrExists indicates something already exists
	ErrExists = errors.New("already exists")
	// ErrNotExists indicates something doesn't exist
	ErrNotExists = errors.New("does not exist")
	// ErrInvalid indicates an argument isn't valid
	ErrInvalid = errors.New("invalid argument")
	// ErrUnknown indicates something isn't recognized
	ErrUnknown = errors.New("unknown")
	// ErrNilReceiver indicates a method was called over a nil instance
	ErrNilReceiver = errors.New("nil receiver")
	// ErrUnreachable indicates something impossible happened
	ErrUnreachable = errors.New("unreachable")
)

Functions

func AddrFromNetIP

func AddrFromNetIP(addr net.Addr) (netip.Addr, bool)

AddrFromNetIP attempts to convert a net.Addr into a netip.Addr

func AddrPort

func AddrPort(v any) (netip.AddrPort, bool)

AddrPort attempts to extract a netip.AddrPort from an object. It supports the following types:

  • netip.AddrPort (returned as-is)
  • *netip.AddrPort (dereferenced)
  • *net.TCPAddr (converted with IPv4 unmapping)
  • *net.UDPAddr (converted with IPv4 unmapping)
  • Types implementing AddrPort() netip.AddrPort method (if result is valid)
  • Types implementing Addr() net.Addr method (recursively processed)
  • Types implementing RemoteAddr() net.Addr method (recursively processed)

IPv4 addresses are properly unmapped, so 192.168.1.1:80 is returned instead of [::ffff:192.168.1.1]:80. Invalid AddrPort values return false.

func As added in v0.14.8

func As[T, V any](v T) (V, bool)

As returns a value cast to a different type

func AsError added in v0.14.8

func AsError[T any](v T) error

AsError attempts to convert a value to an error, checking different interfaces.

* AsError() error * Error() string * OK() bool * IsZero() bool

func AsErrors added in v0.14.8

func AsErrors[T any](vv []T) []error

AsErrors uses AsError to return the subset of the elements that are errors.

func AsFn added in v0.14.8

func AsFn[T, V any](fn func(T) (V, bool), v T) (V, bool)

AsFn returns a value cast to a different type using a helper function

func AssertContains added in v0.18.0

func AssertContains(t T, s, substr, name string, args ...any) bool

AssertContains fails the test if the string does not contain the substring. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertContains(t, "hello world", "world", "substring check")
AssertContains(t, output, "success", "command output for %s", cmd)

func AssertEqual added in v0.18.0

func AssertEqual[U comparable](t T, expected, actual U, name string, args ...any) bool

AssertEqual compares two values and reports differences. This is a generic helper that works with any comparable type. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertEqual(t, 42, result, "result value")
AssertEqual(t, "hello", str, "string %d comparison", 1)

func AssertError added in v0.18.0

func AssertError(t T, err error, name string, args ...any) bool

AssertError fails the test if error is nil. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertError(t, err, "parse error")
AssertError(t, err, "operation %s", "save")

func AssertErrorIs added in v0.18.0

func AssertErrorIs(t T, err, target error, name string, args ...any) bool

AssertErrorIs fails the test if the error does not match the target error. Uses errors.Is to check if the error matches. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertErrorIs(t, err, ErrNotFound, "lookup error")
AssertErrorIs(t, err, ErrInvalid, "validation for %s", field)

func AssertFalse added in v0.18.0

func AssertFalse(t T, value bool, name string, args ...any) bool

AssertFalse fails the test if value is not false. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertFalse(t, hasError, "no errors expected")
AssertFalse(t, isEmpty, "container %s should not be empty", name)

revive:disable-next-line:flag-parameter

func AssertMustContains added in v0.18.1

func AssertMustContains(t T, s, substr, name string, args ...any)

AssertMustContains calls AssertContains and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustContains(t, "hello world", "world", "substring check")
AssertMustContains(t, output, "success", "command output for %s", cmd)

func AssertMustEqual added in v0.18.1

func AssertMustEqual[U comparable](t T, expected, actual U, name string, args ...any)

AssertMustEqual calls AssertEqual and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustEqual(t, 42, result, "result value")
AssertMustEqual(t, "hello", str, "string %d comparison", 1)

func AssertMustError added in v0.18.1

func AssertMustError(t T, err error, name string, args ...any)

AssertMustError calls AssertError and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustError(t, err, "parse error")
AssertMustError(t, err, "operation %s", "save")

func AssertMustErrorIs added in v0.18.1

func AssertMustErrorIs(t T, err, target error, name string, args ...any)

AssertMustErrorIs calls AssertErrorIs and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustErrorIs(t, err, ErrNotFound, "lookup error")
AssertMustErrorIs(t, err, ErrInvalid, "validation for %s", field)

func AssertMustFalse added in v0.18.1

func AssertMustFalse(t T, value bool, name string, args ...any)

AssertMustFalse calls AssertFalse and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustFalse(t, hasError, "no errors expected")
AssertMustFalse(t, isEmpty, "container %s should not be empty", name)

revive:disable-next-line:flag-parameter

func AssertMustNil added in v0.18.1

func AssertMustNil(t T, value any, name string, args ...any)

AssertMustNil calls AssertNil and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustNil(t, err, "error should be nil")
AssertMustNil(t, ptr, "pointer %s should be nil", ptrName)

func AssertMustNoError added in v0.18.1

func AssertMustNoError(t T, err error, name string, args ...any)

AssertMustNoError calls AssertNoError and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustNoError(t, err, "initialization")
AssertMustNoError(t, err, "loading %s", filename)

func AssertMustNoPanic added in v0.18.1

func AssertMustNoPanic(t T, fn func(), name string, args ...any)

AssertMustNoPanic calls AssertNoPanic and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustNoPanic(t, func() { safeFunction() }, "safe function")
AssertMustNoPanic(t, func() { handleNilInput(nil) }, "nil input %s", "handling")

func AssertMustNotContain added in v0.18.4

func AssertMustNotContain(t T, s, substr, name string, args ...any)

AssertMustNotContain calls AssertNotContain and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustNotContain(t, "hello world", "goodbye", "substring absence check")
AssertMustNotContain(t, output, "error", "no errors in %s", cmd)

func AssertMustNotEqual added in v0.18.1

func AssertMustNotEqual[U comparable](t T, expected, actual U, name string, args ...any)

AssertMustNotEqual calls AssertNotEqual and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustNotEqual(t, 42, result, "result value")
AssertMustNotEqual(t, "hello", str, "string %d comparison", 1)

func AssertMustNotNil added in v0.18.1

func AssertMustNotNil(t T, value any, name string, args ...any)

AssertMustNotNil calls AssertNotNil and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustNotNil(t, result, "result should not be nil")
AssertMustNotNil(t, m, "map %s should not be nil", mapName)

func AssertMustNotSame added in v0.18.2

func AssertMustNotSame(t T, expected, actual any, name string, args ...any)

AssertMustNotSame asserts that two values are not the same, calling t.FailNow() on failure.

For value types (numbers, strings, booleans), same-ness means equal values. For reference types (slices, maps, pointers, channels, functions), same-ness means pointer equality to the same underlying data structure.

AssertMustNotSame(t, slice1, slice2, "slice reference")
AssertMustNotSame(t, 42, 43, "number value")

func AssertMustPanic added in v0.18.1

func AssertMustPanic(t T, fn func(), expectedPanic any, name string, args ...any)

AssertMustPanic calls AssertPanic and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustPanic(t, func() { someFunctionThatPanics() }, nil, "panic test")
AssertMustPanic(t, func() { divide(1, 0) }, "division by zero", "divide %d by zero", 1)

func AssertMustSame added in v0.18.2

func AssertMustSame(t T, expected, actual any, name string, args ...any)

AssertMustSame asserts that two values are the same, calling t.FailNow() on failure.

For value types (numbers, strings, booleans), same-ness means equal values. For reference types (slices, maps, pointers, channels, functions), same-ness means pointer equality to the same underlying data structure.

AssertMustSame(t, slice1, slice2, "slice reference")
AssertMustSame(t, 42, 42, "number value")

func AssertMustSliceEqual added in v0.18.1

func AssertMustSliceEqual[U any](t T, expected, actual []U, name string, args ...any)

AssertMustSliceEqual calls AssertSliceEqual and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustSliceEqual(t, S(1, 2, 3), result, "result slice")
AssertMustSliceEqual(t, S("a", "b"), strings, "string slice %s", "test")

func AssertMustTrue added in v0.18.1

func AssertMustTrue(t T, value bool, name string, args ...any)

AssertMustTrue calls AssertTrue and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure.

Example usage:

AssertMustTrue(t, result, "operation succeeded")
AssertMustTrue(t, isValid, "validation for %s", field)

revive:disable-next-line:flag-parameter

func AssertMustTypeIs added in v0.18.1

func AssertMustTypeIs[U any](t T, value any, name string, args ...any) U

AssertMustTypeIs calls AssertTypeIs and t.FailNow() if the assertion fails. This is a convenience function for tests that should terminate on assertion failure. Returns the cast value on success, or the zero value if the test fails.

Example usage:

val := AssertMustTypeIs[*MyError](t, err, "error type")
config := AssertMustTypeIs[*Config](t, result, "config type for %s", name)

func AssertNil added in v0.18.0

func AssertNil(t T, value any, name string, args ...any) bool

AssertNil asserts that a value is nil. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertNil(t, err, "error should be nil")
AssertNil(t, ptr, "pointer %s should be nil", ptrName)

func AssertNoError added in v0.18.0

func AssertNoError(t T, err error, name string, args ...any) bool

AssertNoError fails the test if error is not nil. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertNoError(t, err, "initialization")
AssertNoError(t, err, "loading %s", filename)

func AssertNoPanic added in v0.18.0

func AssertNoPanic(t T, fn func(), name string, args ...any) (ok bool)

AssertNoPanic runs a function expecting it not to panic. This is useful for testing that functions handle edge cases gracefully. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertNoPanic(t, func() { safeFunction() }, "safe function")
AssertNoPanic(t, func() { handleNilInput(nil) }, "nil input %s", "handling")

func AssertNotContain added in v0.18.4

func AssertNotContain(t T, s, substr, name string, args ...any) bool

AssertNotContain fails the test if the string contains the substring. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertNotContain(t, "hello world", "goodbye", "substring absence check")
AssertNotContain(t, output, "error", "command output for %s", cmd)

func AssertNotEqual added in v0.18.0

func AssertNotEqual[U comparable](t T, expected, actual U, name string, args ...any) bool

AssertNotEqual compares two values and ensures they are different. This is a generic helper that works with any comparable type. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertNotEqual(t, 42, result, "result value")
AssertNotEqual(t, "hello", str, "string %d comparison", 1)

func AssertNotNil added in v0.18.0

func AssertNotNil(t T, value any, name string, args ...any) bool

AssertNotNil asserts that a value is not nil. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertNotNil(t, result, "result should not be nil")
AssertNotNil(t, m, "map %s should not be nil", mapName)

func AssertNotSame added in v0.18.2

func AssertNotSame(t T, expected, actual any, name string, args ...any) bool

AssertNotSame asserts that two values are not the same. For reference types, this tests that they do not point to the same underlying data. For value types, this tests that they have different values. This is useful for testing that two slices, maps, or pointers reference different memory locations, even if they have equal contents. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}  // same content, different backing array
AssertNotSame(t, slice1, slice2, "slice reference")

map1 := make(map[string]int)
map2 := make(map[string]int)  // different maps
AssertNotSame(t, map1, map2, "map reference")

AssertNotSame(t, 42, 43, "number value")
AssertNotSame(t, "hello", "world", "string value")

func AssertPanic added in v0.18.0

func AssertPanic(t T, fn func(), expectedPanic any, name string, args ...any) (ok bool)

AssertPanic runs a function expecting it to panic and optionally validates the panic value. The expectedPanic parameter determines how the panic value is validated:

  • nil: Any panic is acceptable (most common case - just verify it panics).
  • error: Uses errors.Is semantics to match error chains (resilient to wrapping).
  • string: Checks if the panic message contains this substring (resilient to message changes).
  • Recovered: Direct comparison without unwrapping (for testing panic recovery).
  • other types: Exact equality check after unwrapping Recovered if present.

This type-specific matching makes tests more resilient to implementation changes whilst still validating that panics occur for the right reasons. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

// Just verify it panics (most common)
AssertPanic(t, func() { slice[999] }, nil, "out of bounds")

// Check panic message contains substring
AssertPanic(t, func() { divide(1, 0) }, "division", "divide by zero")

// Check panic with specific error type
AssertPanic(t, func() { mustValidate(nil) }, ErrValidation, "validation")

func AssertSame added in v0.18.2

func AssertSame(t T, expected, actual any, name string, args ...any) bool

AssertSame asserts that two values are the same. For reference types, this tests that they point to the same underlying data. For value types, this tests that they have equal values. This is useful for testing that two slices, maps, or pointers reference the same memory location, not just equal contents. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

slice1 := []int{1, 2, 3}
slice2 := slice1
AssertSame(t, slice1, slice2, "slice reference")

map1 := make(map[string]int)
map2 := map1
AssertSame(t, map1, map2, "map reference")

AssertSame(t, 42, 42, "number value")
AssertSame(t, "hello", "hello", "string value")

func AssertSliceEqual added in v0.18.0

func AssertSliceEqual[U any](t T, expected, actual []U, name string, args ...any) bool

AssertSliceEqual compares two slices and reports differences. This uses reflect.DeepEqual for comprehensive comparison. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertSliceEqual(t, S(1, 2, 3), result, "result slice")
AssertSliceEqual(t, S("a", "b"), strings, "string slice %s", "test")

func AssertTrue added in v0.18.0

func AssertTrue(t T, value bool, name string, args ...any) bool

AssertTrue fails the test if value is not true. The name parameter can include printf-style formatting. Returns true if the assertion passed, false otherwise.

Example usage:

AssertTrue(t, result, "operation succeeded")
AssertTrue(t, isValid, "validation for %s", field)

revive:disable-next-line:flag-parameter

func AssertTypeIs added in v0.18.0

func AssertTypeIs[U any](t T, value any, name string, args ...any) (U, bool)

AssertTypeIs fails the test if value is not of the expected type. It returns the value cast to the expected type and a boolean indicating success. The name parameter can include printf-style formatting.

Example usage:

val, ok := AssertTypeIs[*MyError](t, err, "error type")
config, ok := AssertTypeIs[*Config](t, result, "config type for %s", name)

func Catch added in v0.14.10

func Catch(fn func() error) error

Catch uses a Catcher to safely call a function and return the organic error or the Recovered PanicError.

func CheckIsTemporary added in v0.13.2

func CheckIsTemporary(err error) (is, known bool)

CheckIsTemporary tests an error for temporary conditions without unwrapping. It checks if the error implements Temporary() bool or IsTemporary() bool interfaces directly, without traversing wrapped error chains.

The function examines the error in the following priority order:

  • Temporary() bool interface (legacy net.Error style)
  • IsTemporary() bool interface (modern style)
  • Falls back to CheckIsTimeout for timeout-based temporary errors

Returns:

  • is: true if the error indicates a temporary condition
  • known: true if the error type implements a recognized interface

For nil errors, returns (false, true) indicating definitively not temporary. For errors with no recognized interface, returns result from CheckIsTimeout.

func CheckIsTimeout added in v0.13.2

func CheckIsTimeout(err error) (is, known bool)

CheckIsTimeout tests an error for timeout conditions without unwrapping. It checks if the error implements Timeout() bool or IsTimeout() bool interfaces directly, without traversing wrapped error chains.

The function examines the error in the following priority order:

  • Timeout() bool interface (legacy net.Error style)
  • IsTimeout() bool interface (modern style)

Returns:

  • is: true if the error indicates a timeout condition
  • known: true if the error type implements a recognized timeout interface

For nil errors, returns (false, true) indicating definitively not a timeout. For errors with no recognized timeout interface, returns (false, false).

Note that timeout errors are typically also considered temporary conditions, but this function specifically tests for timeout semantics only.

func Coalesce

func Coalesce[T any](opts ...T) T

Coalesce returns the first non-zero argument

func CoalesceError added in v0.9.5

func CoalesceError(errs ...error) error

CoalesceError returns the first non-nil error argument. error isn't compatible with Coalesce's comparable generic type.

func GetIPAddresses

func GetIPAddresses(ifaces ...string) ([]netip.Addr, error)

GetIPAddresses returns a list of netip.Addr bound to the given interfaces or all if none are given

func GetInterfacesNames

func GetInterfacesNames(except ...string) ([]string, error)

GetInterfacesNames returns the list of interfaces, considering an optional exclusion list

func GetNetIPAddresses

func GetNetIPAddresses(ifaces ...string) ([]net.IP, error)

GetNetIPAddresses returns a list of net.IP addresses bound to the given interfaces or all if none are given

func GetStringIPAddresses

func GetStringIPAddresses(ifaces ...string) ([]string, error)

GetStringIPAddresses returns a list of text IP addresses bound to the given interfaces or all if none are given

func IIf

func IIf[T any](cond bool, yes, no T) T

IIf returns one value or the other depending on a condition.

func IsError added in v0.13.0

func IsError(err error, errs ...error) bool

IsError recursively check if the given error is in in the given list, or just non-nil if no options to check are given.

func IsErrorFn added in v0.13.0

func IsErrorFn(check func(error) bool, errs ...error) bool

IsErrorFn recursively checks if any of the given errors satisfies the specified check function.

revive:disable:cognitive-complexity

func IsErrorFn2 added in v0.13.0

func IsErrorFn2(check func(error) (bool, bool), errs ...error) (is, known bool)

IsErrorFn2 recursively checks if any of the given errors gets a certain answer from the check function. As opposed to IsErrorFn, IsErrorFn2 will stop when it has certainty of a false result.

revive:disable:cognitive-complexity

func IsNil added in v0.17.5

func IsNil(vi any) bool

IsNil reports whether vi is nil or a typed nil value. It answers the question: "Is this value nil (typed or untyped)?"

IsNil returns true for:

  • nil (untyped nil)
  • nil pointers, slices, maps, channels, functions, and interfaces
  • reflect.Value that is invalid or has a nil underlying value

IsNil returns false for:

  • Zero values of basic types (0, "", false) - these are not nil
  • Non-nil pointers (even if pointing to zero values)
  • Initialized empty collections ([]int{}, map[string]int{})
  • Non-nil interfaces containing zero values
  • Zero-valued structs (structs cannot be nil)

The key distinction from IsZero: IsNil only checks for nil state, while IsZero checks for uninitialized state (which includes nil).

Comparison with IsZero:

  • IsNil(nil) // true - untyped nil
  • IsNil(0) // false - zero int is not nil
  • IsNil("") // false - zero string is not nil
  • IsNil([]int(nil)) // true - nil slice
  • IsNil([]int{}) // false - empty slice is not nil
  • IsNil((*int)(nil)) // true - nil pointer
  • IsNil(new(int)) // false - non-nil pointer
  • IsNil(struct{}{}) // false - structs cannot be nil

Example:

var ptr *int
IsNil(ptr)                   // true  - nil pointer
IsZero(ptr)                  // true  - nil pointer is also zero

var slice []int
IsNil(slice)                 // true  - nil slice
IsZero(slice)                // true  - nil slice is also zero

slice = []int{}
IsNil(slice)                 // false - empty slice is not nil
IsZero(slice)                // false - empty slice is initialized

var num int
IsNil(num)                   // false - integers cannot be nil
IsZero(num)                  // true  - zero integer is uninitialized

func IsSame added in v0.18.2

func IsSame(a, b any) bool

IsSame reports whether two values are the same. It answers the question: "Are these values the same?"

For reference types, IsSame returns true when they point to the same underlying data:

  • Two slices pointing to the same backing array.
  • Two maps pointing to the same map data.
  • Two channels pointing to the same channel.
  • Two function values pointing to the same function.
  • Two pointers pointing to the same address.
  • Two interfaces containing the same pointer value.

For value types, IsSame returns true when they have equal values:

  • Numbers with the same value (42 == 42).
  • Strings with the same content ("hello" == "hello").
  • Booleans with the same value (true == true).

IsSame returns false for:

  • Different backing arrays/maps/channels/functions/pointers.
  • Different values for basic types.
  • One nil and one non-nil value.
  • Different types.
  • Arrays, structs, and other composite types (not handled).

Special case for slices: Go's runtime optimises zero-capacity slices (make([]T, 0)) to share a common zero-sized allocation. IsSame treats these as distinct to preserve expected semantics.

Example:

// Value types - compared by value
IsSame(42, 42)           // true  - same value
IsSame(42, 43)           // false - different values
IsSame("hello", "hello") // true  - same string content
IsSame("hello", "world") // false - different strings

// Nil handling
IsSame(nil, nil)         // true  - both untyped nil
var s1, s2 []int         // both nil slices of same type
IsSame(s1, s2)           // true  - both nil of same type
IsSame(s1, []int{})      // false - one nil, one empty slice

// Reference types - compared by reference
slice1 := []int{1, 2, 3}
slice2 := slice1         // same backing array
slice3 := []int{1, 2, 3} // different backing array
IsSame(slice1, slice2)   // true  - same backing array
IsSame(slice1, slice3)   // false - different backing arrays

map1 := make(map[string]int)
map2 := map1             // same map
map3 := make(map[string]int) // different map
IsSame(map1, map2)       // true  - same map
IsSame(map1, map3)       // false - different maps

x := 42
ptr1 := &x
ptr2 := ptr1             // same pointer
ptr3 := &x               // different pointer variable, same address
IsSame(ptr1, ptr2)       // true  - same pointer
IsSame(ptr1, ptr3)       // true  - both point to same address

func IsTemporary added in v0.13.2

func IsTemporary(err error) bool

IsTemporary tests an error chain for temporary conditions recursively. It traverses wrapped error chains using IsErrorFn2 to find any error that implements temporary condition interfaces.

This function provides comprehensive temporary error detection by:

  • Checking each error in the unwrapping chain via CheckIsTemporary
  • Following both Unwrap() error and Unwrap() []error patterns
  • Detecting legacy net.Error.Temporary() implementations
  • Detecting modern IsTemporary() bool implementations
  • Detecting timeout errors (which are also considered temporary)

Returns true if any error in the chain indicates a temporary condition. Returns false for nil errors or chains with no temporary indicators.

Use this function when you need to determine if an operation should be retried based on the error's temporary nature.

func IsTimeout added in v0.13.2

func IsTimeout(err error) bool

IsTimeout tests an error chain for timeout conditions recursively. It traverses wrapped error chains using IsErrorFn2 to find any error that implements timeout condition interfaces.

This function provides comprehensive timeout error detection by:

  • Checking each error in the unwrapping chain via CheckIsTimeout
  • Following both Unwrap() error and Unwrap() []error patterns
  • Detecting legacy net.Error.Timeout() implementations
  • Detecting modern IsTimeout() bool implementations

Returns true if any error in the chain indicates a timeout condition. Returns false for nil errors or chains with no timeout indicators.

Use this function when you need to distinguish timeout errors from other types of temporary errors for specialized retry logic or timeout-specific error handling.

func IsZero added in v0.9.8

func IsZero(vi any) bool

IsZero reports whether vi is in a state where it can/should be initialized. It answers the question: "Is this value uninitialized and ready to be set?"

IsZero returns true for values that are in their uninitialized state:

  • nil (untyped nil)
  • Zero values of basic types (0, "", false)
  • nil pointers, slices, maps, channels, and functions
  • Zero-valued structs (all fields are zero)
  • Values whose IsZero() method returns true

IsZero returns false for values that have been explicitly initialized:

  • Non-zero basic values (42, "hello", true)
  • Initialized empty collections ([]int{}, map[string]int{})
  • Non-nil pointers (even if pointing to zero values)
  • Non-zero structs (any field is non-zero)

The key insight: something set to nil but assignable is zero; something explicitly initialized (even if empty) is not zero.

Initialization semantics:

  • var slice []int // nil slice, IsZero = true (needs initialization)
  • slice := []int{} // empty but initialized, IsZero = false (already set)
  • var m map[string]int // nil map, IsZero = true (needs initialization)
  • m := make(map[string]int) // empty but initialized, IsZero = false (already set)
  • var ptr *int // nil pointer, IsZero = true (can be assigned)
  • ptr := new(int) // non-nil pointer, IsZero = false (already assigned)

Example:

IsZero(nil)              // true  - uninitialized
IsZero(0)                // true  - zero basic value
IsZero(42)               // false - initialized basic value
IsZero("")               // true  - zero string
IsZero("hello")          // false - initialized string
IsZero([]int(nil))       // true  - nil slice (uninitialized)
IsZero([]int{})          // false - empty slice (initialized)
IsZero([]int{1, 2})      // false - non-empty slice (initialized)
IsZero((*int)(nil))      // true  - nil pointer (uninitialized)
IsZero(new(int))         // false - non-nil pointer (initialized)

func JoinHostPort added in v0.14.3

func JoinHostPort(host, port string) (string, error)

JoinHostPort is like the standard net.JoinHostPort, but it validates the host name and port, and returns it portless if the port argument is empty.

Unlike net.JoinHostPort, this function:

  • Validates hostname and port before joining
  • Returns host without port if port is empty
  • Properly handles IPv6 addresses with bracketing
  • Supports international domain names
  • Returns descriptive errors for invalid inputs

Examples:

  • JoinHostPort("localhost", "8080") → "localhost:8080"
  • JoinHostPort("localhost", "") → "localhost"
  • JoinHostPort("192.168.1.1", "80") → "192.168.1.1:80"
  • JoinHostPort("::1", "443") → "[::1]:443"
  • JoinHostPort("::1", "") → "::1"
  • JoinHostPort("example.com", "0") → "example.com:0" (port 0 allowed)
  • JoinHostPort("invalid host", "80") → error
  • JoinHostPort("example.com", "99999") → error (port out of range)

func Keys added in v0.13.5

func Keys[K comparable, T any](m map[K]T) []K

Keys returns the list of keys of a map

func ListContains

func ListContains[T comparable](l *list.List, val T) bool

ListContains checks if a container/list contains an element

func ListContainsFn

func ListContainsFn[T any](l *list.List, val T, eq func(T, T) bool) bool

ListContainsFn checks if a container/list contains an element that satisfies a given function

func ListCopy added in v0.14.9

func ListCopy[T any](src *list.List) *list.List

ListCopy makes a shallow copy of a list

func ListCopyFn added in v0.14.9

func ListCopyFn[T any](src *list.List, fn func(v T) (T, bool)) *list.List

ListCopyFn makes a copy of a list using the given helper

func ListForEach

func ListForEach[T any](l *list.List, fn func(v T) bool)

ListForEach calls a function for each value until told to stop

func ListForEachBackward

func ListForEachBackward[T any](l *list.List, fn func(v T) bool)

ListForEachBackward calls a function for each value until told to stop

func ListForEachBackwardElement

func ListForEachBackwardElement(l *list.List, fn func(*list.Element) bool)

ListForEachBackwardElement calls a function for each element until told to stop

func ListForEachElement

func ListForEachElement(l *list.List, fn func(*list.Element) bool)

ListForEachElement calls a function for each element until told to stop

func MakeHostPort added in v0.14.3

func MakeHostPort(hostPort string, defaultPort uint16) (string, error)

MakeHostPort produces a validated host:port from an input string optionally using the given default port when the string doesn't specify one. port 0 on the string input isn't considered valid.

Examples:

  • MakeHostPort("localhost", 8080) → "localhost:8080"
  • MakeHostPort("localhost:9000", 8080) → "localhost:9000"
  • MakeHostPort("192.168.1.1", 80) → "192.168.1.1:80"
  • MakeHostPort("::1", 443) → "[::1]:443"
  • MakeHostPort("example.com", 0) → "example.com"
  • MakeHostPort("example.com:0", 80) → error (port 0 invalid)

func MapAllListContains

func MapAllListContains[K comparable, T comparable](m map[K]*list.List, v T) bool

MapAllListContains check if a value exists on any entry of the map

func MapAllListContainsFn

func MapAllListContainsFn[K comparable, T any](m map[K]*list.List, match func(v T) bool) bool

MapAllListContainsFn check if a value exists on any entry of the map using a match function

func MapAllListForEach

func MapAllListForEach[K comparable, T any](m map[K]*list.List, fn func(v T) bool)

MapAllListForEach calls a function for each value on all map entries until told to stop

func MapAllListForEachElement

func MapAllListForEachElement[K comparable](m map[K]*list.List, fn func(*list.Element) bool)

MapAllListForEachElement calls a function for each element on all map entries until told to stop

func MapContains

func MapContains[K comparable](m map[K]any, key K) bool

MapContains tells if a given map contains a key. this helper is intended for switch/case conditions

func MapListAppend

func MapListAppend[K comparable, T any](m map[K]*list.List, key K, v T)

MapListAppend adds a value at the end of the list of a map entry

func MapListAppendUnique

func MapListAppendUnique[K comparable, T comparable](m map[K]*list.List, key K, v T)

MapListAppendUnique adds a value at the end of the list of a map entry if it's not already there

func MapListAppendUniqueFn

func MapListAppendUniqueFn[K comparable, T any](m map[K]*list.List, key K, v T,
	eq func(T, T) bool)

MapListAppendUniqueFn adds a value at the end of the list of a map entry if it's not already there using a function to compare values

func MapListContains

func MapListContains[K comparable, T comparable](m map[K]*list.List, key K, v T) bool

MapListContains checks if the list.List on a map contains an element

func MapListContainsFn

func MapListContainsFn[K comparable, T any](m map[K]*list.List, key K, v T,
	eq func(T, T) bool) bool

MapListContainsFn checks if the list.List on a map contains an element using a match functions

func MapListCopy added in v0.14.9

func MapListCopy[T comparable](src map[T]*list.List) map[T]*list.List

MapListCopy duplicates a map containing a list.List

func MapListCopyFn added in v0.14.9

func MapListCopyFn[K comparable, V any](src map[K]*list.List,
	fn func(v V) (V, bool)) map[K]*list.List

MapListCopyFn duplicates a map containing a list.List but allows the element's values to be cloned by a helper function

func MapListForEach

func MapListForEach[K comparable, T any](m map[K]*list.List, key K,
	fn func(v T) bool)

MapListForEach calls a function for each value on a map entry until told to stop

func MapListForEachElement

func MapListForEachElement[K comparable](m map[K]*list.List, key K,
	fn func(el *list.Element) bool)

MapListForEachElement calls a function for each element on a map entry until told to stop

func MapListInsert

func MapListInsert[K comparable, T any](m map[K]*list.List, key K, v T)

MapListInsert adds a value at the front of the list of a map entry

func MapListInsertUnique

func MapListInsertUnique[K comparable, T comparable](m map[K]*list.List, key K, v T)

MapListInsertUnique adds a value at the front of the list of a map entry if it's not already there

func MapListInsertUniqueFn

func MapListInsertUniqueFn[K comparable, T any](m map[K]*list.List, key K, v T,
	eq func(va, vb T) bool)

MapListInsertUniqueFn adds a value at the front of the list of a map entry if it's not already there using a function to compare values

func MapValue added in v0.14.9

func MapValue[K comparable, V any](m map[K]V, key K, def V) (V, bool)

MapValue returns a value of an entry or a default if not found

func Maybe added in v0.18.0

func Maybe[V any](value V, _ error) V

Maybe returns the value, ignoring any error. This is useful when you want to proceed with a default or zero value regardless of whether an error occurred. Unlike Must, it never panics.

Example usage:

// Use empty string if ReadFile fails
content := Maybe(os.ReadFile("optional.txt"))

// Use zero value if parsing fails
count := Maybe(strconv.Atoi(userInput))

// Chain operations where errors are non-critical
data := Maybe(json.Marshal(obj))

func MaybeOK added in v0.18.0

func MaybeOK[V any](value V, _ bool) V

MaybeOK returns the value, ignoring the ok flag. This is useful when you want to proceed with a default or zero value regardless of whether the operation succeeded. Unlike MustOK, it never panics.

Example usage:

// Use zero value if key doesn't exist in map
value := MaybeOK(MapValue(m, "key", 0))

// Use zero value if type assertion fails
str := MaybeOK(As[any, string](v))

// Chain operations where success is non-critical
result := MaybeOK(someFunc())

func MaybeT added in v0.18.1

func MaybeT[T any](value any) T

MaybeT returns the converted value if type conversion succeeds, otherwise returns the zero value of the target type. This is useful when you want to proceed with a default value regardless of whether the type conversion succeeded. Unlike MustT, it never panics.

Example usage:

// Use zero value if conversion fails
str := MaybeT[string](value)  // empty string if value is not a string
num := MaybeT[int](value)     // zero if value is not an int
reader := MaybeT[io.Reader](value)  // nil if value doesn't implement io.Reader

func Must added in v0.18.0

func Must[V any](value V, err error) V

Must panics if err is not nil, otherwise returns value. This is useful for situations where errors should never occur, such as test setup or configuration loading. It follows the common Go pattern of Must* functions that panic on error. The panic includes proper stack traces pointing to the caller.

Example usage:

config := Must(loadConfig("config.json"))  // panics if loadConfig returns error
conn := Must(net.Dial("tcp", "localhost:8080"))  // panics if dial fails
data := Must(json.Marshal(obj))  // panics if marshal fails

func MustOK added in v0.18.0

func MustOK[V any](value V, ok bool) V

MustOK panics if ok is false, otherwise returns value. This is useful for situations where operations should always succeed, such as accessing map values that are known to exist or type assertions that are guaranteed to be valid. It follows the common Go pattern of Must* functions that panic on failure. The panic includes proper stack traces pointing to the caller.

Example usage:

value := MustOK(MapValue(m, "key", 0))  // panics if key doesn't exist in map
str := MustOK(As[any, string](v))  // panics if v is not a string
result := MustOK(someFunc())  // panics if someFunc returns false for ok

revive:disable-next-line:flag-parameter

func MustT added in v0.18.1

func MustT[T any](value any) T

MustT panics if type conversion fails, otherwise returns the converted value. This is useful for type conversions that should always succeed, such as casting values to interfaces they are known to implement or converting between compatible types. It follows the common Go pattern of Must* functions that panic on failure. The panic includes proper stack traces pointing to the caller.

Example usage:

str := MustT[string](value)  // panics if value is not a string
num := MustT[int](value)     // panics if value is not an int
reader := MustT[io.Reader](value)  // panics if value doesn't implement io.Reader

func NewTemporaryError added in v0.13.2

func NewTemporaryError(err error) error

NewTemporaryError returns an error that returns false to IsTimeout() and true to IsTemporary()

func NewTimeoutError added in v0.13.2

func NewTimeoutError(err error) error

NewTimeoutError returns an error that returns true to IsTimeout() and IsTemporary()

func NewUnreachableError added in v0.16.0

func NewUnreachableError(skip int, err error, note string) error

NewUnreachableError creates a new annotated ErrUnreachable with callstack.

func NewUnreachableErrorf added in v0.16.0

func NewUnreachableErrorf(skip int, err error, format string, args ...any) error

NewUnreachableErrorf creates a new annotated ErrUnreachable with callstack.

func Panic

func Panic(payload any)

Panic emits a PanicError with the given payload

func PanicWrap

func PanicWrap(err error, note string)

PanicWrap emits a PanicError wrapping an annotated error.

func PanicWrapf

func PanicWrapf(err error, format string, args ...any)

PanicWrapf emits a PanicError wrapping an annotated error using a formatting string.

func Panicf

func Panicf(format string, args ...any)

Panicf emits a PanicError with a formatted string as payload

func ParseAddr

func ParseAddr(s string) (addr netip.Addr, err error)

ParseAddr turns a string into netip.Addr

func ParseNetIP

func ParseNetIP(s string) (ip net.IP, err error)

ParseNetIP turns a string into a net.IP

func QuietWrap added in v0.13.3

func QuietWrap(err error, format string, args ...any) error

QuietWrap replaces the text of the error it's wrapping.

func RunBenchmark added in v0.18.0

func RunBenchmark(b *testing.B, setup func() any, fn func(any))

RunBenchmark runs a benchmark with setup and execution phases. This standardizes benchmark patterns with proper timer management.

Example usage:

RunBenchmark(b, func() interface{} {
	return setupTestData()
}, func(data interface{}) {
	processData(data)
})

func RunConcurrentTest added in v0.18.0

func RunConcurrentTest(t T, numWorkers int, worker func(int) error) error

RunConcurrentTest runs multiple goroutines and waits for completion. This standardizes concurrent testing patterns.

Example usage:

err := RunConcurrentTest(t, 10, func(id int) error {
	// worker logic here
	return nil
})
AssertNoError(t, err, "concurrent test should not fail")

func RunTestCases added in v0.18.0

func RunTestCases[T TestCase](t *testing.T, cases []T)

RunTestCases runs a slice of test cases that implement the TestCase interface. This eliminates the boilerplate of looping through test cases and calling t.Run.

Example usage:

RunTestCases(t, testCases)

func S added in v0.18.0

func S[T any](v ...T) []T

S is a helper function for creating test slices in a more concise way. It takes variadic arguments and returns a slice of the same type. This is particularly useful in table-driven tests where many slice literals are used. The function accepts any type, including structs with non-comparable fields.

Example usage:

S(1, 2, 3)           // []int{1, 2, 3}
S("a", "b", "c")     // []string{"a", "b", "c"}
S[int]()             // []int{}
S[string]()          // []string{}
S(testCase{...})     // []testCase{...} (works with any struct)

func SliceAs added in v0.14.8

func SliceAs[T, V any](vv []T) []V

SliceAs returns a subset of a slice that could be cast into a different type

func SliceAsFn added in v0.14.8

func SliceAsFn[T, V any](fn func(T) (V, bool), vv []T) []V

SliceAsFn returns a subset of a slice that could be cast into a different type, using a helper function.

func SliceContains

func SliceContains[T comparable](a []T, v T) bool

SliceContains tells if a slice contains a given element

func SliceContainsFn

func SliceContainsFn[T any](a []T, v T, eq func(T, T) bool) bool

SliceContainsFn tells if a slice contains a given element according to the callback eq

func SliceCopy added in v0.14.0

func SliceCopy[T any](s []T) []T

SliceCopy makes a shallow copy of a given slice

func SliceCopyFn

func SliceCopyFn[T any](s []T,
	fn func(partial []T, before T) (after T, include bool),
) []T

SliceCopyFn makes a copy of a slice, optionally modifying in-flight the items using a function. If no function is provided, the destination will be a shallow copy of the source slice.

func SliceEqual added in v0.13.5

func SliceEqual[T comparable](a, b []T) bool

SliceEqual tells if two slices are equal.

func SliceEqualFn added in v0.13.5

func SliceEqualFn[T any](a, b []T, eq func(va, vb T) bool) bool

SliceEqualFn tells if two slices are equal using a comparing helper.

func SliceMap added in v0.14.1

func SliceMap[T1 any, T2 any](a []T1,
	fn func(partial []T2, v T1) (newEntries []T2)) []T2

SliceMap takes a []T1 and uses a function to produce a []T2 by processing each item on the source slice.

func SliceMinus

func SliceMinus[T comparable](a, b []T) []T

SliceMinus returns a new slice containing only the elements of one slice not present on the second

func SliceMinusFn

func SliceMinusFn[T any](a, b []T, eq func(T, T) bool) []T

SliceMinusFn returns a new slice containing only elements of slice A that aren't on slice B according to the callback eq

func SliceP added in v0.18.5

func SliceP[T Ordered](a []T, p float64) T

SliceP returns the p-th percentile element from a slice. The slice is sorted in place (modifying the original slice) before calculating the percentile. p must be between 0.0 (minimum) and 1.0 (maximum). Returns the zero value for empty slices or when p is outside the valid range. This is commonly used for performance metrics and latency measurements to identify outliers while excluding the worst values.

Example:

responseTimes := []int{100, 150, 120, 450, 89, 2000, 110, 130, 140, 160}
p99 := SliceP(responseTimes, 0.99) // Returns the value at the 99th percentile
// Note: responseTimes is now sorted

func SliceRandom added in v0.9.2

func SliceRandom[T any](a []T) (T, bool)

SliceRandom returns a random element from a slice if the slice is empty it will return the zero value of the slice type and false

func SliceReplaceFn

func SliceReplaceFn[T any](s []T,
	fn func(partial []T, before T) (after T, replace bool),
) []T

SliceReplaceFn replaces or skips entries in a slice

func SliceReverse added in v0.14.7

func SliceReverse[T any](x []T)

SliceReverse modifies a slice reversing the order of its elements.

func SliceReversed added in v0.14.7

func SliceReversed[T any](a []T) []T

SliceReversed returns a copy of the slice, in reverse order.

func SliceReversedFn added in v0.14.7

func SliceReversedFn[T any](a []T,
	fn func(partial []T, before T) (after T, include bool)) []T

SliceReversedFn returns a modified copy of the slice, in reverse order.

func SliceSort added in v0.13.5

func SliceSort[T any](x []T, cmp func(a, b T) int)

SliceSort sorts the slice x in ascending order as determined by the cmp function. This sort is not guaranteed to be stable. cmp(a, b) should return a negative number when a < b, a positive number when a > b and zero when a == b.

func SliceSortFn added in v0.14.2

func SliceSortFn[T any](x []T, less func(a, b T) bool)

SliceSortFn sorts the slice x in ascending order as a less function. This sort is not guaranteed to be stable. less(a, b) should true when a < b

func SliceSortOrdered added in v0.14.2

func SliceSortOrdered[T Ordered](x []T)

SliceSortOrdered sorts the slice x of an Ordered type in ascending order.

func SliceUnique

func SliceUnique[T comparable](a []T) []T

SliceUnique returns a new slice containing only unique elements

func SliceUniqueFn

func SliceUniqueFn[T any](a []T, eq func(T, T) bool) []T

SliceUniqueFn returns a new slice containing only unique elements according to the callback eq

func SliceUniquify

func SliceUniquify[T comparable](ptr *[]T) []T

SliceUniquify returns the same slice, reduced to only contain unique elements

func SliceUniquifyFn

func SliceUniquifyFn[T any](ptr *[]T, eq func(T, T) bool) []T

SliceUniquifyFn returns the same slice, reduced to only contain unique elements according to the callback eq

func SortedKeys added in v0.13.5

func SortedKeys[K Ordered, T any](m map[K]T) []K

SortedKeys returns a sorted list of the keys of a map

func SortedValues added in v0.16.2

func SortedValues[K Ordered, T any](m map[K]T) []T

SortedValues returns a slice of values from the map, sorted by their keys

func SortedValuesCond added in v0.16.2

func SortedValuesCond[K Ordered, T any](m map[K]T, fn func(T) bool) []T

SortedValuesCond returns a slice of values from the map, sorted by their keys, filtered by the optional predicate function fn, preallocated to the size of the map.

func SortedValuesUnlikelyCond added in v0.16.2

func SortedValuesUnlikelyCond[K Ordered, T any](m map[K]T, fn func(T) bool) []T

SortedValuesUnlikelyCond returns a slice of values from the map, sorted by their keys, filtered by the optional predicate function fn, without preallocation.

func SplitAddrPort added in v0.10.1

func SplitAddrPort(addrPort string) (addr netip.Addr, port uint16, err error)

SplitAddrPort splits a string containing an IP address and an optional port, and validates it. Returns the address as netip.Addr and port as uint16.

This function:

  • Accepts IP addresses with optional port numbers
  • Validates the address is a valid IPv4 or IPv6 address
  • Validates the port is in range 1-65535 (0 if no port specified)
  • Properly handles IPv6 addresses with brackets
  • Returns zero values and error for invalid inputs

Examples:

  • SplitAddrPort("192.168.1.1:8080") → (192.168.1.1, 8080, nil)
  • SplitAddrPort("192.168.1.1") → (192.168.1.1, 0, nil)
  • SplitAddrPort("[::1]:443") → (::1, 443, nil)
  • SplitAddrPort("::1") → (::1, 0, nil)
  • SplitAddrPort("127.0.0.1:80") → (127.0.0.1, 80, nil)
  • SplitAddrPort("invalid") → error
  • SplitAddrPort("192.168.1.1:99999") → error (port out of range)

func SplitHostPort

func SplitHostPort(hostPort string) (host, port string, err error)

SplitHostPort is like net.SplitHostPort but doesn't fail if the port isn't part of the string and it validates it if present. SplitHostPort will also validate the host is a valid IP or name

Unlike net.SplitHostPort, this function:

  • Accepts hostport strings without port (returns empty port)
  • Validates the host is a valid IP address or hostname
  • Validates the port is a valid port number (1-65535)
  • Properly handles IPv6 addresses with and without brackets
  • Supports international domain names with punycode conversion
  • Returns descriptive errors for invalid inputs

Examples:

  • SplitHostPort("localhost:8080") → ("localhost", "8080", nil)
  • SplitHostPort("localhost") → ("localhost", "", nil)
  • SplitHostPort("192.168.1.1:80") → ("192.168.1.1", "80", nil)
  • SplitHostPort("[::1]:443") → ("::1", "443", nil)
  • SplitHostPort("::1") → ("::1", "", nil)
  • SplitHostPort("example.com") → ("example.com", "", nil)
  • SplitHostPort("Hello.世界") → ("hello.世界", "", nil)
  • SplitHostPort("invalid host") → error
  • SplitHostPort("example.com:99999") → error (port out of range)

func Unwrap added in v0.13.0

func Unwrap(err error) []error

Unwrap unwraps one layer of a compound error, ensuring there are no nil entries.

func WithTimeout added in v0.15.5

func WithTimeout(parent context.Context, tio time.Duration) (context.Context, context.CancelFunc)

WithTimeout is equivalent to context.WithDeadline but taking a duration instead of an absolute time.

If the duration is zero or negative the context won't expire.

func WithTimeoutCause added in v0.15.5

func WithTimeoutCause(parent context.Context, tio time.Duration, cause error) (context.Context, context.CancelFunc)

WithTimeoutCause is equivalent to context.WithDeadlineCause but taking a duration instead of an absolute time.

If the duration is zero or negative the context won't expire.

func Wrap

func Wrap(err error, msg string) error

Wrap annotates an error with a single string.

func Wrapf

func Wrapf(err error, format string, args ...any) error

Wrapf annotates an error with a formatted string.

func Zero added in v0.9.8

func Zero[T any](_ *T) T

Zero returns the zero value of type T. It takes a pointer to T as a parameter to infer the type, but the pointer value itself is ignored.

This function is useful when you need to obtain the zero value of a generic type without having to declare a variable.

Example:

var p *int
zero := Zero(p)  // returns 0

var s *string
empty := Zero(s) // returns ""

type Person struct { Name string; Age int }
var person *Person
zeroPerson := Zero(person) // returns Person{Name: "", Age: 0}

Types

type Bool added in v0.14.0

type Bool interface {
	~bool
}

Bool is any boolean type.

type CallStacker

type CallStacker interface {
	CallStack() Stack
}

CallStacker represents an object that can provide its call stack. Types implementing this interface can be used for stack trace collection and debugging purposes.

type Catcher

type Catcher struct {
	// contains filtered or unexported fields
}

Catcher is a runner that catches panics

func (*Catcher) Do

func (p *Catcher) Do(fn func() error) error

Do calls a function, returning its organic error, or the caught panic

func (*Catcher) Recovered

func (p *Catcher) Recovered() Recovered

Recovered returns the error corresponding to a panic when the Catcher was running a function

func (*Catcher) Try

func (p *Catcher) Try(fn func() error) error

Try calls a function, returning its organic error, or storing the recovered error for later consumption

type Complex added in v0.14.0

type Complex interface {
	~complex64 | ~complex128
}

Complex is any complex numeric type.

type CompoundError added in v0.9.1

type CompoundError struct {
	Errs []error
}

A CompoundError can contain more that one error

func (*CompoundError) Append added in v0.14.5

func (w *CompoundError) Append(err error, note string, args ...any) *CompoundError

Append adds an error to the collection, optionally annotating it with a formatted note. If err is nil and a note is provided, a new error is created from the note. If both err and note are non-empty, the error is wrapped with the note. Returns the updated CompoundError for method chaining.

func (*CompoundError) AppendError added in v0.9.1

func (w *CompoundError) AppendError(errs ...error) *CompoundError

AppendError adds an error to the collection, unwrapping other implementers of the Errors interface when possible. It returns the updated CompoundError for method chaining.

func (*CompoundError) AsError added in v0.9.1

func (w *CompoundError) AsError() error

AsError returns itself as an `error` when there are errors stored, and nil when there aren't

func (*CompoundError) Error added in v0.9.1

func (w *CompoundError) Error() string

func (*CompoundError) Errors added in v0.9.1

func (w *CompoundError) Errors() []error

Errors returns the contained slice of errors

func (*CompoundError) OK added in v0.18.0

func (w *CompoundError) OK() bool

OK tells when there are no errors stored

func (*CompoundError) Ok deprecated added in v0.9.1

func (w *CompoundError) Ok() bool

Ok tells when there are no errors stored

Deprecated: Use OK() instead.

func (*CompoundError) Unwrap added in v0.13.0

func (w *CompoundError) Unwrap() []error

Unwrap returns the contained slice of errors

type ContextKey

type ContextKey[T any] struct {
	// contains filtered or unexported fields
}

ContextKey is a type-safe key for a context.Context value

func NewContextKey

func NewContextKey[T any](name string) *ContextKey[T]

NewContextKey creates a new ContextKey bound to the specified type and friendly name

func (*ContextKey[T]) Get

func (ck *ContextKey[T]) Get(ctx context.Context) (T, bool)

Get attempts to extract a value bound to this key in a context.Context For convenience this method will safely operate over a nil receiver.

func (*ContextKey[T]) GoString

func (ck *ContextKey[T]) GoString() string

GoString renders this key in Go syntax for %v

func (*ContextKey[T]) String

func (ck *ContextKey[T]) String() string

String returns the name

func (*ContextKey[T]) WithValue

func (ck *ContextKey[T]) WithValue(ctx context.Context, v T) context.Context

WithValue safely attaches a value to a context.Context under this key.

type ErrGroup added in v0.11.0

type ErrGroup struct {
	Parent context.Context
	// contains filtered or unexported fields
}

ErrGroup handles a group of workers where all are canceled once one fails. As it's based on WaitGroup it also catches panics.

func (*ErrGroup) Cancel added in v0.11.0

func (eg *ErrGroup) Cancel(cause error) bool

Cancel initiates a shutdown of the group. The returned value indicates if it was the first time.

func (*ErrGroup) Cancelled added in v0.11.0

func (eg *ErrGroup) Cancelled() <-chan struct{}

Cancelled returns a channel marker to know when the Group has been cancelled and the shutdown has been initiated.

Cancelled() doesn't indicate all workers have finished, for that call ErrGroup.Wait or ErrGroup.Done.

func (*ErrGroup) Context added in v0.11.0

func (eg *ErrGroup) Context() context.Context

Context returns the cancellable context used with the workers

func (*ErrGroup) Done added in v0.11.1

func (eg *ErrGroup) Done() <-chan struct{}

Done returns a channel that gets closed when all workers have finished.

func (*ErrGroup) Err added in v0.11.0

func (eg *ErrGroup) Err() error

Err returns the error that initiated the group's shutdown.

func (*ErrGroup) Go added in v0.11.0

func (eg *ErrGroup) Go(run func(context.Context) error, shutdown func() error)

Go spawns a worker and an optional shutdown routine to be invoked when the ErrGroup is cancelled, otherwise the provided context needs to be monitored and shutdown called.

func (*ErrGroup) GoCatch added in v0.11.0

func (eg *ErrGroup) GoCatch(run func(context.Context) error,
	catch func(context.Context, error) error)

GoCatch runs a worker on the Group, with a custom error handler.

func (*ErrGroup) IsCancelled added in v0.11.0

func (eg *ErrGroup) IsCancelled() bool

IsCancelled tells the ErrGroup has been cancelled

func (*ErrGroup) OnError added in v0.11.0

func (eg *ErrGroup) OnError(fn func(error))

OnError sets a helper that will be called when a worker returns an error or panics

func (*ErrGroup) SetDefaults added in v0.11.0

func (eg *ErrGroup) SetDefaults()

SetDefaults fills gaps in the config and initializes the internal structure.

func (*ErrGroup) Wait added in v0.11.0

func (eg *ErrGroup) Wait() error

Wait waits until all workers in the group have finished.

type Errors added in v0.9.1

type Errors interface {
	Error() string
	Errors() []error
}

Errors in an error that contains a slice of errors

type Float added in v0.14.0

type Float interface {
	~float32 | ~float64
}

Float is any floating-point type.

type Frame

type Frame struct {
	// contains filtered or unexported fields
}

Frame represents a single function call frame in a call stack. It captures function name, source file, line number, and program counter information at the time of stack capture.

This implementation is heavily based on github.com/pkg/errors.Frame but resolves all information immediately for efficient later consumption. Each Frame contains:

  • Function name (package.function)
  • Source file path
  • Line number
  • Program counter and entry point

func Here

func Here() *Frame

Here captures and returns the current stack frame where it was called. This is useful for capturing the immediate calling context for debugging.

Returns nil if stack capture fails or if called in an environment where runtime stack information is unavailable.

Example:

frame := Here()
if frame != nil {
    fmt.Printf("Called from %s at %s", frame.FuncName(), frame.FileLine())
}

func StackFrame

func StackFrame(skip int) *Frame

StackFrame captures a specific frame in the call stack, skipping the specified number of stack levels above the caller.

Parameters:

  • skip: number of stack frames to skip (0 = caller, 1 = caller's caller, etc.)

Returns nil if the stack doesn't have enough frames or if capture fails. Useful for creating stack-aware error reporting utilities.

Example:

// Get the frame 2 levels up the stack
frame := StackFrame(2)
if frame != nil {
    log.Printf("Error originated from %s", frame.Name())
}

func (Frame) File

func (f Frame) File() string

File returns the full path to the source file containing this frame's function. Returns empty string for zero-valued frames or when file information is unavailable.

func (Frame) FileLine

func (f Frame) FileLine() string

FileLine returns a formatted "file:line" string for this frame. If line number is available and positive, returns "filename:123". If line is zero or negative, returns just the filename. Useful for displaying source location in error messages and logs.

func (Frame) Format

func (f Frame) Format(s fmt.State, verb rune)

Format formats the frame according to the fmt.Formatter interface.

The following verbs are supported:

%s    source file
%d    source line
%n    function name
%v    equivalent to %s:%d

Format accepts flags that alter the printing of some verbs:

%+s   function name and path of source file relative to the compile time
      GOPATH separated by \n\t (<funcName>\n\t<path>)
%+n   full package name followed by function name
%+v   equivalent to %+s:%d
%#s   package/file format using PkgFile()
%#v   equivalent to %#s:%d

func (Frame) FuncName added in v0.9.10

func (f Frame) FuncName() string

FuncName returns only the function name without package qualification. For example: "TestFunction" or "main". Uses SplitName internally to separate package from function name.

func (Frame) Line

func (f Frame) Line() int

Line returns the line number within the source file for this frame. Returns 0 for zero-valued frames or when line information is unavailable.

func (Frame) Name

func (f Frame) Name() string

Name returns the full qualified function name including package path. For example: "darvaza.org/core.TestFunction" or "main.main". Returns empty string for zero-valued frames.

func (Frame) PkgFile added in v0.17.5

func (f Frame) PkgFile() string

PkgFile returns the package name (if present) followed by '/' and the file name. For example: "darvaza.org/core/stack.go". If no package name exists, returns just the file name. Returns empty string for zero-valued frames or when file information is unavailable.

func (Frame) PkgName added in v0.9.10

func (f Frame) PkgName() string

PkgName returns the package path portion of the function name. For example: "darvaza.org/core" or "main". Returns empty string if no package separator is found.

func (Frame) SplitName added in v0.9.10

func (f Frame) SplitName() (pkgName, funcName string)

SplitName splits the full function name into package and function components. Handles generic function names by ignoring trailing "[...]" suffixes. Searches for the last "." or "/" separator to determine the split point.

Returns:

  • pkgName: package path ("darvaza.org/core")
  • funcName: function name ("TestFunction")

If no separator is found, returns an empty package name and the full name as the function name.

func (Frame) String added in v0.17.5

func (f Frame) String() string

String returns a string representation of the frame equivalent to %v format. This implements the fmt.Stringer interface and returns "file:line" format using the same logic as FileLine but with basename only for the file.

type Integer added in v0.14.0

type Integer interface {
	Signed | Unsigned
}

Integer is any integer type, signed and unsigned.

type MockT added in v0.18.0

type MockT struct {
	Errors       []string
	Logs         []string
	HelperCalled int
	// contains filtered or unexported fields
}

MockT is a mock implementation of the T interface for testing purposes. It collects error and log messages instead of reporting them to the testing framework.

MockT supports all standard testing methods including Fatal/Fatalf which panic with a special error that can be caught by the Run method. This allows testing of assertion functions and other utilities that may call Fatal methods.

The Run method executes test functions and recovers from FailNow/Fatal panics, making it ideal for testing assertion functions where you need to verify both success and failure scenarios without terminating the test runner.

func (*MockT) Error added in v0.18.0

func (m *MockT) Error(args ...any)

Error implements the T interface and collects error messages. It also marks the test as failed.

func (*MockT) Errorf added in v0.18.0

func (m *MockT) Errorf(format string, args ...any)

Errorf implements the T interface and collects formatted error messages. It also marks the test as failed.

func (*MockT) Fail added in v0.18.0

func (m *MockT) Fail()

Fail implements the T interface and marks the test as failed.

func (*MockT) FailNow added in v0.18.1

func (m *MockT) FailNow()

FailNow implements the T interface and marks the test as failed, then panics.

func (*MockT) Failed added in v0.18.0

func (m *MockT) Failed() bool

Failed implements the T interface and returns whether the test has been marked as failed.

func (*MockT) Fatal added in v0.18.1

func (m *MockT) Fatal(args ...any)

Fatal implements the T interface and collects error messages, then panics. It combines Error and FailNow functionality.

func (*MockT) Fatalf added in v0.18.1

func (m *MockT) Fatalf(format string, args ...any)

Fatalf implements the T interface and collects formatted error messages, then panics. It combines Errorf and FailNow functionality.

func (*MockT) HasErrors added in v0.18.0

func (m *MockT) HasErrors() bool

HasErrors returns true if any errors were recorded.

func (*MockT) HasLogs added in v0.18.0

func (m *MockT) HasLogs() bool

HasLogs returns true if any log messages were recorded.

func (*MockT) Helper added in v0.18.0

func (m *MockT) Helper()

Helper implements the T interface and tracks that it was called.

func (*MockT) LastError added in v0.18.0

func (m *MockT) LastError() (string, bool)

LastError returns the last error message and whether one was found.

func (*MockT) LastLog added in v0.18.0

func (m *MockT) LastLog() (string, bool)

LastLog returns the last log message and whether one was found.

func (*MockT) Log added in v0.18.0

func (m *MockT) Log(args ...any)

Log implements the T interface and collects log messages.

func (*MockT) Logf added in v0.18.0

func (m *MockT) Logf(format string, args ...any)

Logf implements the T interface and collects formatted log messages.

func (*MockT) Reset added in v0.18.0

func (m *MockT) Reset()

Reset clears all recorded errors, logs, failed state, and helper state.

func (*MockT) Run added in v0.18.1

func (m *MockT) Run(_ string, f func(T)) (ok bool)

Run runs the test function f with the MockT instance and returns whether it passed. It recovers from FailNow/Fatal panics and returns false if the test failed or panicked. Non-FailNow panics are re-thrown. Returns false for nil MockT or nil function.

This method is ideal for testing assertion functions that may call Fatal/FailNow:

mock := &MockT{}
ok := mock.Run("test assertion", func(t T) {
	AssertEqual(t, 1, 2, "should fail") // This calls t.Fatal internally
})
// ok == false, mock.Failed() == true, mock.Errors contains failure message

Unlike testing.T.Run, this method uses the same MockT instance throughout, allowing inspection of all collected errors, logs, and failure state after execution.

This Run method enables compatibility patterns where test functions need to work with both *testing.T and MockT. Use interface type assertions to detect Run method support:

func doRun(t core.T, name string, fn func(core.T)) {
	switch tt := t.(type) {
	case interface { Run(string, func(*testing.T)) bool }:
		tt.Run(name, func(subT *testing.T) { fn(subT) })
	case interface { Run(string, func(core.T)) bool }:
		tt.Run(name, fn)
	default:
		fn(t) // Fallback for simple core.T implementations
	}
}

type Ordered added in v0.14.0

type Ordered interface {
	Signed | Unsigned | Float | String
}

Ordered is any type that supports order operators.

type PanicError

type PanicError struct {
	// contains filtered or unexported fields
}

PanicError is an error to be sent via panic, ideally to be caught using slog.Recover()

func NewPanicError

func NewPanicError(skip int, payload any) *PanicError

NewPanicError creates a new PanicError with arbitrary payload

func NewPanicErrorf

func NewPanicErrorf(skip int, format string, args ...any) *PanicError

NewPanicErrorf creates a new PanicError annotated with a string, optionally formatted. %w is expanded.

func NewPanicWrap

func NewPanicWrap(skip int, err error, note string) *PanicError

NewPanicWrap creates a new PanicError wrapping a given error annotated with a single string.

func NewPanicWrapf

func NewPanicWrapf(skip int, err error, format string, args ...any) *PanicError

NewPanicWrapf creates a new PanicError wrapping a given error annotated with a formatted string.

func (*PanicError) CallStack

func (p *PanicError) CallStack() Stack

CallStack returns the call stack associated to this panic() event

func (*PanicError) Error

func (p *PanicError) Error() string

Error returns the payload as a string

func (*PanicError) Recovered

func (p *PanicError) Recovered() any

Recovered returns the payload of the panic

func (*PanicError) Unwrap

func (p *PanicError) Unwrap() error

Unwrap returns the payload if it's and error

type Recovered

type Recovered interface {
	Error() string
	Recovered() any
}

Recovered is an error caught from a panic call

func AsRecovered

func AsRecovered(rvr any) Recovered

AsRecovered receives the value from recover() and wraps it as a Recovered error

type Signed added in v0.14.0

type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}

Signed is any signed integer type.

type SpinLock deprecated added in v0.15.3

type SpinLock uint32

SpinLock is a simple CompareAndSwap locking mechanism.

Deprecated: Use darvaza.org/x/sync/spinlock instead.

func (*SpinLock) Lock added in v0.15.3

func (sl *SpinLock) Lock()

Lock blocks until it can acquire the lock

func (*SpinLock) TryLock added in v0.15.3

func (sl *SpinLock) TryLock() bool

TryLock attempts to acquire the lock

func (*SpinLock) Unlock added in v0.15.3

func (sl *SpinLock) Unlock()

Unlock releases the lock

type Stack

type Stack []Frame

Stack represents a captured call stack as a slice of Frame objects. Each Frame in the stack corresponds to a function call, ordered from the most recent call (index 0) to the oldest call.

Stack implements custom formatting via the Format method, supporting various output formats for debugging and logging purposes.

func StackTrace

func StackTrace(skip int) Stack

StackTrace captures a complete call stack starting from the specified skip level. The resulting Stack contains frames ordered from most recent to oldest call.

Parameters:

  • skip: number of initial stack frames to skip before capture begins

Returns an empty Stack if capture fails or if there are insufficient frames. The maximum capture depth is limited by MaxDepth (32 frames).

This function is commonly used for error reporting, debugging, and logging where complete call context is needed.

Example:

// Capture stack excluding this function and its caller
stack := StackTrace(2)
for i, frame := range stack {
    fmt.Printf("[%d] %s at %s", i, frame.Name(), frame.FileLine())
}

func (Stack) Format

func (st Stack) Format(s fmt.State, verb rune)

Format formats the entire stack using the same verbs as Frame.Format with additional support for the '#' flag for numbered output.

Supported format verbs (same as Frame.Format):

%s, %d, %n, %v    - basic formatting
%+s, %+n, %+v     - verbose formatting with full paths/names

Additional '#' flag support:

%#s, %#n, %#v     - each frame on new line
%#+s, %#+n, %#+v  - numbered frames with [index/total] prefix

Example outputs:

fmt.Printf("%+v", stack)   - multi-line stack with full info
fmt.Printf("%#+v", stack)  - numbered multi-line stack
fmt.Printf("%#n", stack)   - function names only, numbered

func (Stack) String added in v0.17.5

func (st Stack) String() string

String returns a string representation of the stack equivalent to %v format. This implements the fmt.Stringer interface and returns a multi-line representation with each frame formatted as "file:line" on separate lines.

type String added in v0.14.0

type String interface {
	~string
}

String is any string type.

type T added in v0.18.0

type T interface {
	Helper()
	Error(args ...any)
	Errorf(format string, args ...any)
	Fatal(args ...any)
	Fatalf(format string, args ...any)
	Log(args ...any)
	Logf(format string, args ...any)
	Fail()
	FailNow()
	Failed() bool
}

T is an interface that abstracts the testing functionality we need. This allows our testing utilities to work with both *testing.T and mock implementations.

type TemporaryError added in v0.13.2

type TemporaryError struct {
	// contains filtered or unexported fields
}

TemporaryError is an error wrapper that satisfies IsTimeout() and IsTemporary()

func (*TemporaryError) Error added in v0.13.2

func (w *TemporaryError) Error() string

func (*TemporaryError) IsTemporary added in v0.13.2

func (*TemporaryError) IsTemporary() bool

IsTemporary tells this error is temporary.

func (*TemporaryError) IsTimeout added in v0.13.2

func (w *TemporaryError) IsTimeout() bool

IsTimeout tells if this error is a time-out or not.

func (*TemporaryError) Temporary added in v0.13.2

func (*TemporaryError) Temporary() bool

Temporary tells this error is temporary.

func (*TemporaryError) Timeout added in v0.13.2

func (w *TemporaryError) Timeout() bool

Timeout tells if this error is a time-out or not.

type TestCase added in v0.18.0

type TestCase interface {
	Name() string
	Test(t *testing.T)
}

TestCase represents a test case that can be executed. This interface is used by RunTestCases to standardize test case execution.

type Unsigned added in v0.14.0

type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}

Unsigned is any unsigned integer type.

type Unwrappable

type Unwrappable interface {
	Error() string
	Unwrap() error
}

Unwrappable represents an error that can be Unwrap() to get the cause

type WaitGroup

type WaitGroup struct {
	// contains filtered or unexported fields
}

WaitGroup is a safer way to run workers

func (*WaitGroup) Done added in v0.11.1

func (wg *WaitGroup) Done() <-chan struct{}

Done returns a channel that gets closed when all workers have finished.

func (*WaitGroup) Err

func (wg *WaitGroup) Err() error

Err returns the first error

func (*WaitGroup) Go

func (wg *WaitGroup) Go(fn func() error)

Go spawns a supervised goroutine

func (*WaitGroup) GoCatch

func (wg *WaitGroup) GoCatch(fn func() error, catch func(error) error)

GoCatch spawns a supervised goroutine, and uses a given function to intercept the returned error

func (*WaitGroup) OnError

func (wg *WaitGroup) OnError(fn func(error) error)

OnError sets a helper that will be called when a worker returns an error or panics

func (*WaitGroup) Wait

func (wg *WaitGroup) Wait() error

Wait waits until all workers have finished, and returns the first error

type WrappedError

type WrappedError struct {
	// contains filtered or unexported fields
}

WrappedError is an annotated error that can be Unwrapped

func (*WrappedError) Error

func (w *WrappedError) Error() string

func (*WrappedError) Unwrap

func (w *WrappedError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL