core

package module
v0.12.1 Latest Latest
Warning

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

Go to latest
Published: Mar 3, 2024 License: MIT Imports: 18 Imported by: 55

README

Core of helpers for darvaza.org projects

Go Reference Go Report Card Codebeat Score

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

Network

  • GetInterfacesNames
  • ParseAddr/ParseNetIP
  • SplitHostPort/SplitAddrPort
  • AddrPort
  • AddrFromNetIP
  • GetIPAddresses/GetNetIPAddresses/GetStringIPAddresses

Generics

  • Zero/IsZero
  • Coalesce/IIf
  • SliceContains/SliceContainsFn
  • SliceMinus/SliceMinusFn
  • SliceUnique/SliceUniqueFn
  • SliceUniquify/SliceUniquifyFn
  • SliceReplaceFn/SliceCopyFn
  • SliceRandom
  • ListContains/ListContainsFn
  • ListForEach/ListForEachElement
  • ListForEachBackward/ListForEachBackwardElement
  • MapContains
  • MapListContains/MapListContainsFn
  • MapListForEach/MapListForEachElement
  • MapListInsert/MapListAppend
  • MapListInsertUnique/MapListInsertUniqueFn
  • MapListAppendUnique/MapListAppendUniqueFn
  • MapAllListContains/MapAllListContainsFn
  • MapAllListForEach/MapAllListForEachElement
  • NewContextKey

Errors

  • Wrap/Unwrappable

  • Errors/CompoundError

  • CoalesceError

  • AsRecovered/Recovered

  • Catcher

  • PanicError

  • Panic/Panicf/PanicWrap

  • WaitGroup/ErrGroup

  • Frame/Stack

  • Here/StackFrame/StackTrace

  • CallStacker

  • ErrNotImplemented/ErrTODO

  • ErrExists/ErrNotExists

  • ErrInvalid/ErrUnknown

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")
)

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

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 IsZero added in v0.9.8

func IsZero(vi any) bool

IsZero checks if a given value is zero, either using the IsZero() bool interface or reflection

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 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 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 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 Panic

func Panic(payload any)

Panic emits a PanicError with the given payload

func PanicWrap

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

PanicWrap emits a PanicError wrapping an annotated error, optionally formatted. %w is expanded.

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 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 SliceCopyFn

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

SliceCopyFn conditionally copies a slice allowing modifications of the items

func SliceMinus

func SliceMinus[T comparable](a []T, 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 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 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 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.

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

func Wrap

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

Wrap annotates an error, optionally with a formatted string. if %w is used the argument will be unwrapped

func Zero added in v0.9.8

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

Zero returns the zero value of a type for which we got a pointer.

Types

type CallStacker

type CallStacker interface {
	CallStack() Stack
}

CallStacker represents an object with a method CallStack() returning a Stack

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 CompoundError added in v0.9.1

type CompoundError struct {
	Errs []error
}

A CompoundError can contain more that one error

func (*CompoundError) AppendError added in v0.9.1

func (w *CompoundError) AppendError(err error)

AppendError adds an error to the collection, unwrapping other implementers of the Errors interface when possible

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.9.1

func (w *CompoundError) Ok() bool

Ok tells when there are no errors stored

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 Frame

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

Frame represents a function call on the call Stack. This implementation is heavily based on github.com/pkg/errors.Frame but all parts are resolved immediately for later consumption.

func Here

func Here() *Frame

Here returns the Frame corresponding to where it was called, or nil if it wasn't possible

func StackFrame

func StackFrame(skip int) *Frame

StackFrame returns the Frame skip levels above from where it was called, or nil if it wasn't possible

func (Frame) File

func (f Frame) File() string

File returns the file name of the source code corresponding to this Frame

func (Frame) FileLine

func (f Frame) FileLine() string

FileLine returns File name and Line separated by a colon, or only the filename if the Line isn't known

func (Frame) Format

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

Format formats the frame according to the fmt.Formatter interface. * * %s source file * %d source line * %n function name * %v equivalent to %s:%d * * Format accepts flags that alter the printing of some verbs, as follows: * * %+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

func (Frame) FuncName added in v0.9.10

func (f Frame) FuncName() string

FuncName returns the name of the function, without the package name

func (Frame) Line

func (f Frame) Line() int

Line returns the file number on the source code corresponding to this Frame, or zero if unknown.

func (Frame) Name

func (f Frame) Name() string

Name returns the name of the function, including package name

func (Frame) PkgName added in v0.9.10

func (f Frame) PkgName() string

PkgName returns the package name

func (Frame) SplitName added in v0.9.10

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

SplitName returns package name and function name

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, format string, args ...any) *PanicError

NewPanicWrap creates a new PanicError wrapping a given error annotated, optionally formatted. %w is expanded.

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 Stack

type Stack []Frame

Stack is an snapshot of the call stack in the form of an array of Frames.

func StackTrace

func StackTrace(skip int) Stack

StackTrace returns a snapshot of the call stack starting skip levels above from where it was called, on an empty array if it wasn't possible

func (Stack) Format

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

Format formats the stack of Frames following the rules explained in Frame.Format with the addition of the '#' flag.

when '#' is passed, like for example %#+v each row will be prefixed by i/n indicating the position in the stack followed by the %+v representation of the Frame

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