support

package
v0.41.2 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package support holds the small, dependency-free building blocks the rest of the framework is written on: time, environment, value holders, URLs and a handful of generic helpers.

Time

Now is the one place the current instant comes from, and everything else here reads it: Today, Tomorrow, Yesterday, Parse and the CreateFrom constructors. A test moves it with Travel, TravelTo, FreezeTime or SetTestNow and puts it back with TravelBack; Use and UseCallable replace the Clock outright.

There is no date type of this package's own. time.Time already is the value, and a second one would be a second way to hold an instant.

Values

Fluent is a bag of attributes read and written by dotted key, and ValidatedInput is the input that passed validation; both carry the typed readers String, Integer, Float, Boolean, Array and Date. Optional reads into a value that may be nil without checking at every step. MessageBag and ViewErrorBag collect messages keyed by field. HtmlString and Js carry markup that must not be escaped again.

Uri parses and edits a URL: every writer hands back a new instance and leaves the old one alone, and UriQueryString reads the query as nested data.

Control flow

Retry runs a callback again while it fails. Sleep builds a duration unit by unit. Once computes a value the first time a line is reached and gives it back after. Timebox refuses to return before its time is up, so the time a check took says nothing about its result. Lottery runs a callback on a fraction of the calls. Defer puts work off until the response has been sent. Tap, Transform and With pass a value through a callback.

Process-wide state

The clock, Sleep, Lottery and Once each hold state a test replaces for the whole process, so a test that replaces one cannot run in parallel with a test that does not. Each has a matching call that puts the default back: TravelBack and UseDefault, Fake, DetermineResultNormally, Flush.

Index

Constants

View Source
const DefaultErrorBag = "default"

DefaultErrorBag is the key a ViewErrorBag reads when no bag is named.

View Source
const DefaultMessageFormat = ":message"

DefaultMessageFormat is what a MessageBag wraps its messages in until MessageBag.SetFormat says otherwise: nothing at all, the message on its own.

A format is a template read on the way out, in MessageBag.Get, MessageBag.First and MessageBag.All: ":message" is replaced by the message and ":key" by the key it is filed under, so a bag set to "<li>:message</li>" hands every message back already wrapped. The messages held in the bag are never changed, only the copies it returns.

Variables

View Source
var Benchmark benchmarkFacade

Benchmark measures how long a callback takes, in milliseconds.

View Source
var Env envFacade

Env reads environment variables, parsing the well-known literals into the values they name. It is a value rather than a type because a process has one environment: support.Env.Get(key) is the whole call.

View Source
var ErrFloatGreaterThanOne = errors.New("Float must not be greater than 1.")

ErrFloatGreaterThanOne is returned by NewLottery and Odds for chances above one with no total to be out of.

View Source
var ErrMalformedConfigurationURL = errors.New("The database configuration URL is malformed.")

ErrMalformedConfigurationURL is returned when the configuration URL cannot be read.

View Source
var ErrNoDurationSpecified = errors.New("No duration specified.")

ErrNoDurationSpecified is held on a Sleep when a unit is asked for and no number is pending, and handed back by Sleep.Goodnight.

View Source
var ErrNoUrlGenerator = errors.New("support: no URL generator resolver has been set")

ErrNoUrlGenerator is returned by To, Route, SignedRoute and Action when no resolver was set, or when the resolver returned nothing.

View Source
var ErrNotAnOrderedID = errors.New("support: id is neither an ordered UUID nor a ULID")

ErrNotAnOrderedID is returned by CreateFromId when the string is neither an ordered UUID nor a ULID.

View Source
var ErrUnknownDelay = errors.New("support: delay must be a time.Time, a time.Duration or a number of seconds")

ErrUnknownDelay states the three shapes a delay may take: an instant (time.Time), a span (time.Duration) or a plain count of seconds. Anything else carries no duration and cannot be turned into one.

SecondsUntil, AvailableAt and ParseDateInterval never return it -- they take a value they cannot read as zero, so a delay of the wrong type schedules work for right now instead of failing. It is here for a caller that has to reject such a value rather than fall back, and it is the error to return.

View Source
var ErrUnknownDurationUnit = errors.New("Unknown duration unit.")

ErrUnknownDurationUnit is returned by Sleep.Goodnight when a number was given and no unit ever followed it.

View Source
var ProcessUtils processUtilsFacade

ProcessUtils holds the helpers for handing arguments to a shell.

Functions

func AddDriverAlias

func AddDriverAlias(alias, driver string)

AddDriverAlias registers a URL scheme and the driver it selects, replacing whatever the scheme mapped to before.

func AlwaysLose

func AlwaysLose(callback ...func())

AlwaysLose makes every later draw lose. The variadic argument is a callback: given one, drawing goes back to normal once it has run.

func AlwaysWin

func AlwaysWin(callback ...func())

AlwaysWin makes every later draw win. The variadic argument is a callback: given one, drawing goes back to normal once it has run.

func Append_config

func Append_config(array map[string]any) map[string]any

Append_config renumbers the numeric keys of a map past 9999, so a merge appends them instead of writing over what is already there.

A key counts as numeric when its text parses as a number. The numeric keys are renumbered in sorted order and every other key is carried through untouched.

func AssertInsomniac

func AssertInsomniac(t testing.TB)

AssertInsomniac fails the test unless every recorded sleep was of zero duration: sleeping was asked for, but nothing would have been waited.

func AssertNeverSlept

func AssertNeverSlept(t testing.TB)

AssertNeverSlept fails the test unless no sleep was recorded at all.

func AssertSequence

func AssertSequence(t testing.TB, sequence []*Sleep)

AssertSequence fails the test unless the recorded sleeps match the given ones, in order and in number. A nil entry skips the comparison at that position.

func AssertSlept

func AssertSlept(t testing.TB, expected func(duration time.Duration) bool, times ...int)

AssertSlept fails the test unless exactly the expected number of recorded durations pass the truth test. The variadic argument is that number and defaults to 1.

The testing.TB is the first argument because there is no ambient running test to find: the caller hands its own in.

func AssertSleptTimes

func AssertSleptTimes(t testing.TB, expected int)

AssertSleptTimes fails the test unless exactly that many sleeps were recorded.

func AvailableAt

func AvailableAt(delay any) int64

AvailableAt returns the UNIX timestamp the delay lands on. The delay is a time.Time, a time.Duration or a number of seconds; anything else lands on now.

func Blank

func Blank(v any) bool

Blank reports whether there is nothing there at all. A string of spaces is blank, a number and a bool never are, an empty slice, map, array or channel is, and a nil pointer, interface or func is; a pointer is read through.

func Class_basename

func Class_basename(class any) string

Class_basename returns the type name with its package path off. A string is read as the name itself, and a pointer type is read through. An untyped nil gives the empty string.

func CreateFromFormat

func CreateFromFormat(layout, value string) (time.Time, error)

CreateFromFormat reads a date out of a string against the given layout, in the local location.

func CreateFromId

func CreateFromId(id string) (time.Time, error)

CreateFromId returns the instant an ordered UUID or a ULID was made at, which both carry in their first 48 bits. The milliseconds are read here rather than through a library, so this package carries no dependency of its own. A string that is neither is ErrNotAnOrderedID.

func CreateFromTimestamp

func CreateFromTimestamp(timestamp int64) time.Time

CreateFromTimestamp returns the instant the given number of seconds after the epoch.

func CreateFromTimestampMs

func CreateFromTimestampMs(timestamp int64) time.Time

CreateFromTimestampMs returns the instant the given number of milliseconds after the epoch.

func CurrentTime

func CurrentTime() int64

CurrentTime returns Now as a UNIX timestamp.

func Dd

func Dd(values ...any)

Dd dumps the values and ends the process with status 1.

func Defer

func Defer(callback func(), options ...any) *deferpkg.DeferredCallback

Defer puts the callback off until the response has been sent, and returns the handle it can be called off by.

The variadic argument is the name and then the always flag, defaulting to an empty name and false; an empty name is filled with a random one. To reach the collection itself, call DeferredCallbackCollection.

func DeferredCallbackCollection

func DeferredCallbackCollection() *deferpkg.DeferredCallbackCollection

DeferredCallbackCollection returns the one collection every deferred callback of this process lands in, building it on first use. Nothing is resolved from a registry: the collection is this package's own.

func DetermineResultNormally

func DetermineResultNormally()

DetermineResultNormally drops any pinned result, so draws are random again.

func DetermineResultsNormally

func DetermineResultsNormally()

DetermineResultsNormally drops any pinned result, the same as DetermineResultNormally.

func Disable

func Disable()

Disable turns memoization off, so every call runs its callback.

func Dump

func Dump(values ...any) any

Dump writes the values to standard error with %#v, one per line, and returns the first of them; with no value it returns nil.

Standard error is where a dump belongs when standard output is the response.

func E

func E(v any, doubleEncode ...bool) string

E writes the HTML-special characters of a value as entities, so it cannot escape the attribute it is put in.

An Htmlable states its own markup and is not escaped again. The variadic argument is whether to double-encode and defaults to true; false leaves an ampersand that already opens an entity alone.

func Enable

func Enable()

Enable turns memoization back on.

func Encode

func Encode(data any) (string, error)

Encode returns the data as JSON, escaped the way Js needs it. A Jsonable is asked for its own JSON first, and a value carrying a ToArray method that is not already a json.Marshaler is asked for its map first.

func Enum

func Enum[T ~string | ~int](d dataSource, key string, cases []T) (T, bool)

Enum returns the value at the key as one of the given cases, or the zero value and false when it is not one of them.

The cases are an argument because there is no way to list the values of a named string or int type, and it is a function rather than a method because a method cannot take a type parameter.

func Enums

func Enums[T ~string | ~int](d dataSource, key string, cases []T) []T

Enums returns every value under the key that is one of the given cases. See Enum on why the cases are an argument.

func Fake

func Fake(options ...bool)

Fake makes every later sleep record its duration instead of waiting it out, and clears whatever was recorded before.

The variadic argument is whether to fake and whether to move the pinned clock forward by each sleep, in that order, defaulting to true and false. The setting is process-wide, so a test that calls it cannot run in parallel with one that does not.

func Filled

func Filled(v any) bool

Filled reports whether the value is not Blank.

func Fix

func Fix(sequence []bool, whenMissing ...func(chances float64, outOf *int) bool)

Fix pins the results a draw gives, the same as ForceResultWithSequence.

func Flush

func Flush()

Flush drops the store, so the next call at every site computes again.

func ForceResultWithSequence

func ForceResultWithSequence(sequence []bool, whenMissing ...func(chances float64, outOf *int) bool)

ForceResultWithSequence pins the results a draw gives, in order, and says what to do once they run out.

The variadic argument is the fallback: with none, drawing goes back to normal from there on.

func ForwardCallTo

func ForwardCallTo(object any, method string, parameters ...any) ([]any, error)

ForwardCallTo calls the named method on the object through reflection and returns what it returned, one entry per result.

A method the object does not carry, and a non-variadic method handed the wrong number of arguments, are both ErrBadMethodCall. A nil argument is passed as the zero value of the parameter it lands on.

func ForwardDecoratedCallTo

func ForwardDecoratedCallTo(decorator, object any, method string, parameters ...any) ([]any, error)

ForwardDecoratedCallTo is ForwardCallTo with one change: a result that is the object itself comes back as the decorator, so a chained call keeps returning the decorator.

func FreezeSecond

func FreezeSecond(callback ...func()) time.Time

FreezeSecond freezes on the start of the current second, so a comparison against a whole second holds.

func FreezeTime

func FreezeTime(callback ...func()) time.Time

FreezeTime pins "now" where it already is, so nothing moves while the callback runs. With no callback it stays frozen until TravelBack.

func GetDriverAliases

func GetDriverAliases() map[string]string

GetDriverAliases returns a copy of the table mapping a URL scheme to the driver it selects.

func GetTestNow

func GetTestNow() *time.Time

GetTestNow returns a copy of the pinned instant, or nil when nothing is pinned.

func HasTestNow

func HasTestNow() bool

HasTestNow reports whether an instant is pinned.

func Instance

func Instance() *onceRepository

Instance returns the process-wide memoization store, building it on first use.

func Laravel_cloud

func Laravel_cloud() bool

Laravel_cloud reports whether the hosting platform of that name is running this process, which it marks with an environment variable set to "1".

func Now

func Now() time.Time

Now returns the current instant, or the instant a test pinned with SetTestNow. It reads the Clock that Use set.

func Object_get

func Object_get(object any, key string, def ...any) any

Object_get reads a value out of a struct or a map by dotted key. An empty key gives the object itself, and a name that cannot be reached gives the optional default, which is nil when not given.

Each segment reads an exported struct field or a map key, through Optional, so a nil anywhere along the path stops the walk.

func Once

func Once[T any](callback func() T) T

Once runs the callback the first time this line of code is reached and gives back that value every time after. The value keeps the type it went in with; a stored value of another type reads as the zero T.

See TryFromTrace for what the value is keyed by, and what that does not take into account.

func Parse

func Parse(value string) (time.Time, error)

Parse reads a date out of a string, returning an error naming the string when no layout matches.

The empty string and "now" are Now; "today", "tomorrow" and "yesterday" are the calls of those names. A time-only string is placed on the day Now reports. Everything else is read in the local location.

func ParseDateInterval

func ParseDateInterval(delay any) any

ParseDateInterval turns a time.Duration into the instant it lands on, and leaves every other value alone.

func Preg_replace_array

func Preg_replace_array(pattern string, replacements []string, subject string) string

Preg_replace_array replaces each match of the pattern with the next value of the list, in order. A match past the end of the list is replaced with nothing, and a pattern that will not compile leaves the subject alone.

The pattern is a Go regular expression, carrying no delimiters.

func Retry

func Retry(times any, callback func(attempt int) (any, error), options ...any) (any, error)

Retry runs the callback again while it fails, up to the given number of attempts, and returns the last error when the attempts run out.

times is an int count of attempts, or a []int of backoff milliseconds, one per retry. The variadic argument is the pause between attempts and the test that decides whether to retry, in that order: the pause is an int of milliseconds, a func() int or a func(attempt int, err error) int, and defaults to none; the test is a func(err error) bool, and by default every error is retried. The pause goes through Usleep, so a test that called Fake captures it instead of serving it.

func RunTimeForHumans

func RunTimeForHumans(start time.Time, end ...time.Time) string

RunTimeForHumans writes the span between the two instants the way a console line writes it. At one second or below it is milliseconds with two decimals; above it, a short cascade of units, as in "1s 250ms". An absent end is Now, and an end before the start reads as zero.

func SecondsUntil

func SecondsUntil(delay any) int64

SecondsUntil returns how many seconds separate now from the delay. The delay is a time.Time, a time.Duration or a number of seconds; anything else reads as zero. An instant already past reads as zero rather than a negative count.

func SetResultFactory

func SetResultFactory(factory func(chances float64, outOf *int) bool)

SetResultFactory installs the function every later draw goes through. It is process-wide, so a test that sets it must put it back with DetermineResultNormally.

func SetTestNow

func SetTestNow(value *time.Time)

SetTestNow pins the instant every later Now reports. A nil value unpins, handing time back to the Clock.

func SetUrlGeneratorResolver

func SetUrlGeneratorResolver(resolver func() UrlGenerator)

SetUrlGeneratorResolver sets the function that hands back the UrlGenerator. It is process-wide.

func SyncWithCarbon

func SyncWithCarbon(value ...bool)

SyncWithCarbon says whether a faked sleep moves the pinned "now" forward by its duration. The variadic argument defaults to true.

func Tap

func Tap[T any](v T, callback func(T)) T

Tap hands the value to the callback, then hands the value back. A nil callback returns the value untouched.

func ThrowBadMethodCallException

func ThrowBadMethodCallException(object any, method string) error

ThrowBadMethodCallException builds an ErrBadMethodCall naming the object's type and the method, and returns it.

func Throw_if

func Throw_if(condition bool, err error) error

Throw_if returns the error when the condition holds, and nil when it does not.

func Throw_unless

func Throw_unless(condition bool, err error) error

Throw_unless returns the error when the condition does not hold, and nil when it does.

func Today

func Today() time.Time

Today returns midnight of the current day, in the current location.

func Tomorrow

func Tomorrow() time.Time

Tomorrow returns midnight of the day after Today.

func Transform

func Transform[T, R any](v T, callback func(T) R, def ...R) R

Transform returns the callback's result when the value is Filled, and the optional default when it is Blank. With no default, a blank value gives the zero R.

func Travel

func Travel(d time.Duration) time.Time

Travel moves the pinned "now" by the given amount and returns it. A time.Duration already carries its unit, so a five-day jump is Travel(5 * 24 * time.Hour).

func TravelBack

func TravelBack()

TravelBack unpins "now".

func TravelTo

func TravelTo(value time.Time, callback ...func()) time.Time

TravelTo pins "now" at the given instant and returns it. Given a callback, it runs the callback and then travels back.

func Use

func Use(c Clock)

Use sets the Clock every later Now reads. A nil clock restores SystemClock.

func UseCallable

func UseCallable(callable func() time.Time)

UseCallable sets the function every later Now reads. A nil callable is UseDefault.

func UseDefault

func UseDefault()

UseDefault restores SystemClock and unpins whatever was pinned.

func Value

func Value[T any](callback func() T) (T, float64)

Value returns what the callback returned and how long it took, in milliseconds. The value keeps the type it went in with.

func WhenFakingSleep

func WhenFakingSleep(callback func(duration time.Duration))

WhenFakingSleep registers a callback run with every duration that was recorded instead of slept.

func Windows_os

func Windows_os() bool

Windows_os reports whether the process is running on Windows.

func With

func With[T, R any](v T, callback func(T) R) R

With returns the value passed through the callback. The callback is required: a value passed through nothing is the value itself.

func WithLocale

func WithLocale(app Application, locale string, callback func() any) any

WithLocale runs the callback under the given locale and puts the old one back afterwards, whatever happens. An empty locale, or a nil application, runs the callback as it stands.

func WithTestNow

func WithTestNow(value time.Time, callback func())

WithTestNow runs the callback with the instant pinned, then puts back whatever was pinned before.

func Yesterday

func Yesterday() time.Time

Yesterday returns midnight of the day before Today.

Types

type Application

type Application interface {
	// GetLocale returns the locale the application is running under.
	GetLocale() string
	// SetLocale sets the locale the application runs under.
	SetLocale(locale string)
}

Application is the part of the running application that WithLocale touches. Nothing is resolved from a registry, so the caller hands it in.

type Clock

type Clock interface {
	// Now returns the current instant.
	Now() time.Time
}

Clock is the one place "now" comes from, so a test can replace it.

There is no date type of this package's own: time.Time already is the value, and a second one would be a second way to hold an instant. The seam is this interface, and a test reaches it through Use, UseCallable, SetTestNow, Travel, TravelTo, TravelBack and FreezeTime.

type ConfigurationUrlParser

type ConfigurationUrlParser struct{}

ConfigurationUrlParser turns a single database URL into the connection options a driver wants.

func NewConfigurationUrlParser

func NewConfigurationUrlParser() *ConfigurationUrlParser

NewConfigurationUrlParser returns a parser. It carries no state, so the zero value works just as well.

func (*ConfigurationUrlParser) ParseConfiguration

func (p *ConfigurationUrlParser) ParseConfiguration(config any) (map[string]any, error)

ParseConfiguration returns the configuration with its url key read out and spread over driver, database, host, port, username, password and whatever the query string carried.

The configuration is a map, or a bare string taken as the URL itself; nil and any other type give an empty map. A URL that cannot be read is ErrMalformedConfigurationURL.

type EnvRepository

type EnvRepository interface {
	// Get returns the raw value of a variable and whether it is set at all.
	Get(key string) (string, bool)
}

EnvRepository is a source of environment variables.

type EnvRepositoryFunc

type EnvRepositoryFunc func(key string) (string, bool)

EnvRepositoryFunc lets a plain function be an EnvRepository.

func (EnvRepositoryFunc) Get

func (f EnvRepositoryFunc) Get(key string) (string, bool)

Get calls f.

type ErrBadMethodCall

type ErrBadMethodCall struct {
	// Class is the type the call was forwarded to.
	Class string
	// Method is the name that was called on it.
	Method string
}

ErrBadMethodCall is returned when a call is forwarded to a method the target does not carry.

func (*ErrBadMethodCall) Error

func (e *ErrBadMethodCall) Error() string

Error names the type the call was forwarded to and the method called on it.

type Fluent

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

Fluent is a bag of attributes read and written by dotted key, with the typed readers of the embedded data source on top -- String, Integer, Float, Boolean, Array, Date, Collect and the rest.

func Make

func Make(attributes map[string]any) *Fluent

Make builds a Fluent over the given attributes, the same as NewFluent.

func NewFluent

func NewFluent(attributes map[string]any) *Fluent

NewFluent builds a Fluent over a copy of the given attributes, each written at the top level. A nil map gives an empty bag.

func (*Fluent) All

func (f *Fluent) All(keys ...string) map[string]any

All returns every attribute when given no key, and the subset under the given dotted keys otherwise. A key the bag does not hold comes back as nil.

func (Fluent) AnyFilled

func (d Fluent) AnyFilled(keys ...string) bool

AnyFilled reports whether at least one of the keys is filled.

func (Fluent) Array

func (d Fluent) Array(key string) []any

Array returns the value at the key as a list, wrapping a value that is not one. To read several keys at once, use [dataSource.Only]: the two shapes cannot share a return type.

func (Fluent) Boolean

func (d Fluent) Boolean(key string, def ...bool) bool

Boolean returns the value at the key as a bool: "1", "true", "on" and "yes" are true, in any case, and everything else is false. The optional default is used when the key is absent, and is false when not given.

func (Fluent) Collect

func (d Fluent) Collect(key string) []any

Collect is [dataSource.Array] under a second name.

func (Fluent) Data

func (d Fluent) Data(key string, def any) any

Data returns one value out of the source, by dotted key, falling back to the default. It is exported because Enum and Enums are functions and have to reach it from outside the type.

func (Fluent) Date

func (d Fluent) Date(key string, formatAndLocation ...string) (time.Time, error)

Date returns the value at the key as a time.Time. The variadic argument is the layout and then the location name, in that order; with no layout the value is read by Parse.

A key that is not filled gives the zero time and no error. A value that cannot be read, and a location name that cannot be loaded, are errors.

func (Fluent) Except

func (d Fluent) Except(keys ...string) map[string]any

Except returns everything but the given dotted keys. The data is copied first, so the source is left alone.

func (Fluent) Exists

func (d Fluent) Exists(keys ...string) bool

Exists is [dataSource.Has] under a second name.

func (*Fluent) Fill

func (f *Fluent) Fill(attributes map[string]any) *Fluent

Fill writes every pair at the top level, with no dot reading, and returns the Fluent.

func (Fluent) Filled

func (d Fluent) Filled(keys ...string) bool

Filled reports whether every key holds something that is not an empty string. A bool, a list and a map count as filled even when empty.

func (Fluent) Float

func (d Fluent) Float(key string, def ...float64) float64

Float returns the value at the key as a float64, reading the leading numeric run, or zero when there is none. The optional default is used when the key is absent, and is zero when not given.

func (*Fluent) Get

func (f *Fluent) Get(key string, def ...any) any

Get returns the value under a dotted key, falling back to the optional default, which is nil when not given. An empty key returns every attribute, and the default is not consulted.

func (*Fluent) GetAttributes

func (f *Fluent) GetAttributes() map[string]any

GetAttributes returns a copy of every attribute.

func (Fluent) Has

func (d Fluent) Has(keys ...string) bool

Has reports whether every one of the dotted keys is present. With no key it is false.

func (Fluent) HasAny

func (d Fluent) HasAny(keys ...string) bool

HasAny reports whether at least one of the dotted keys is present.

func (Fluent) Integer

func (d Fluent) Integer(key string, def ...int) int

Integer returns the value at the key as an int, reading the leading numeric run and truncating it, or zero when there is none. The optional default is used when the key is absent, and is zero when not given.

func (Fluent) IsNotFilled

func (d Fluent) IsNotFilled(keys ...string) bool

IsNotFilled reports whether every one of the keys is empty.

func (*Fluent) MarshalJSON

func (f *Fluent) MarshalJSON() ([]byte, error)

MarshalJSON encodes the attributes, so a Fluent nests inside another encoded value. An empty bag encodes as {}.

func (Fluent) Missing

func (d Fluent) Missing(keys ...string) bool

Missing reports whether any of the dotted keys is absent.

func (Fluent) Only

func (d Fluent) Only(keys ...string) map[string]any

Only returns the subset under the given dotted keys, leaving out the keys that are absent.

func (*Fluent) Scope

func (f *Fluent) Scope(key string, def ...any) *Fluent

Scope returns the value under the key as a Fluent of its own. A map becomes its attributes, a slice is keyed by its decimal index, nil gives an empty bag, and anything else becomes a one-attribute bag under the key "0".

func (*Fluent) Set

func (f *Fluent) Set(key string, v any) *Fluent

Set writes a value under a dotted key, creating the levels that are missing, and returns the Fluent.

func (Fluent) Str

func (d Fluent) Str(key string, def ...any) string

Str is [dataSource.String] under a second name.

func (Fluent) String

func (d Fluent) String(key string, def ...any) string

String returns the value at the key as a string, falling back to the optional default. It is a plain string and not a richer wrapper, so this package carries no dependency on the string package.

func (*Fluent) ToArray

func (f *Fluent) ToArray() map[string]any

ToArray returns a copy of the attributes, so the caller cannot write through it into the bag.

func (*Fluent) ToJson

func (f *Fluent) ToJson() (string, error)

ToJson encodes the attributes as JSON, or returns the error encoding raised.

func (*Fluent) Value

func (f *Fluent) Value(key string, def ...any) any

Value returns the attribute under the exact key, with no dot reading, falling back to the optional default. A default that is a func() any is invoked and its result returned.

func (Fluent) WhenFilled

func (d Fluent) WhenFilled(key string, callback func(value any), def ...func())

WhenFilled runs the callback with the value when the key is filled, and the optional fallback when it is not. It returns nothing for the reason given on [dataSource.WhenHas].

func (Fluent) WhenHas

func (d Fluent) WhenHas(key string, callback func(value any), def ...func())

WhenHas runs the callback with the value when the key is present, and the optional fallback when it is not.

It returns nothing: an embedded struct cannot reach the type that embeds it, so there is no receiver to hand back for chaining.

func (Fluent) WhenMissing

func (d Fluent) WhenMissing(key string, callback func(value any), def ...func())

WhenMissing runs the callback when the key is absent, and the optional fallback when it is present. It returns nothing for the reason given on [dataSource.WhenHas].

type HtmlString

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

HtmlString is a string already safe to write into a template, which the view layer must not escape.

func NewHtmlString

func NewHtmlString(html string) *HtmlString

NewHtmlString marks the given markup as already escaped. The empty string is allowed.

func (*HtmlString) IsEmpty

func (h *HtmlString) IsEmpty() bool

IsEmpty reports whether the markup is the empty string.

func (*HtmlString) IsNotEmpty

func (h *HtmlString) IsNotEmpty() bool

IsNotEmpty reports whether the markup holds anything.

func (*HtmlString) String

func (h *HtmlString) String() string

String returns the markup, so HtmlString satisfies fmt.Stringer.

func (*HtmlString) ToHtml

func (h *HtmlString) ToHtml() string

ToHtml returns the markup. A nil receiver returns the empty string.

type Htmlable

type Htmlable interface {
	// ToHtml returns the value as markup, ready to write into a template.
	ToHtml() string
}

Htmlable is a value that knows how to present itself as HTML which must not be escaped again.

type Js

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

Js is data turned into a JavaScript expression meant to be dropped inside an HTML attribute.

The encoding escapes inside string literals only, leaving the structural characters of the JSON alone: a forward slash leaves as \/, so a literal cannot close a script element. Anything that is not a scalar comes back wrapped in a JSON.parse call, so the browser parses it instead of the JavaScript parser reading an object literal.

func From

func From(data any) (*Js, error)

From turns the data into a JavaScript expression, the same as NewJs.

func NewJs

func NewJs(data any) (*Js, error)

NewJs turns the data into a JavaScript expression, or returns the error encoding it raised.

func (*Js) String

func (j *Js) String() string

String returns the expression, so Js satisfies fmt.Stringer.

func (*Js) ToHtml

func (j *Js) ToHtml() string

ToHtml returns the expression. A nil receiver returns the empty string.

type Jsonable

type Jsonable interface {
	// ToJson returns the value as JSON, or the error encoding it raised.
	ToJson() (string, error)
}

Jsonable is a value that knows how to present itself as JSON.

type Lottery

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

Lottery runs one callback or the other at the odds given, so a slow path runs on a fraction of the requests.

func NewLottery

func NewLottery(chances float64, outOf ...int) (*Lottery, error)

NewLottery builds a lottery at the given chances. The variadic argument is the total to be out of; with no total the chances are read as a probability in [0, 1], and anything above one is ErrFloatGreaterThanOne.

func Odds

func Odds(chances float64, outOf ...int) (*Lottery, error)

Odds builds a lottery at the given chances, the same as NewLottery.

func (*Lottery) Choose

func (l *Lottery) Choose(times ...int) any

Choose draws. With no argument it draws once and returns what the callback returned; with a count it draws that many times and returns a []any of the results.

func (*Lottery) Loser

func (l *Lottery) Loser(callback func() any) *Lottery

Loser sets the callback run when the draw loses, and returns the lottery.

func (*Lottery) Winner

func (l *Lottery) Winner(callback func() any) *Lottery

Winner sets the callback run when the draw wins, and returns the lottery.

type MessageBag

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

MessageBag is the keyed list of messages a validator hands to a view.

A map has no order of its own, so the bag carries the key order beside it: MessageBag.All, MessageBag.Keys and MessageBag.Unique walk the keys in the order they were first added.

func NewMessageBag

func NewMessageBag(messages map[string][]string) *MessageBag

NewMessageBag builds a bag over the given messages. Each list is deduplicated, keeping the first occurrence.

A map has no order, so the initial keys are sorted to make the bag deterministic. Keys added later with MessageBag.Add keep their insertion order.

func (*MessageBag) Add

func (b *MessageBag) Add(key, message string) *MessageBag

Add files a message under a key and returns the bag. A key and message pair the bag already holds is not added twice.

func (*MessageBag) AddIf

func (b *MessageBag) AddIf(boolean bool, key, message string) *MessageBag

AddIf adds the message only when the condition holds, and returns the bag.

func (*MessageBag) All

func (b *MessageBag) All(format ...string) []string

All returns every message in the bag, in key order, formatted.

func (*MessageBag) Any

func (b *MessageBag) Any() bool

Any reports whether the bag holds any message.

func (*MessageBag) Count

func (b *MessageBag) Count() int

Count returns how many messages the bag holds, counting messages and not keys.

func (*MessageBag) First

func (b *MessageBag) First(key string, format ...string) string

First returns the first message under the key, or the empty string when there is none. An empty key takes the first message in the whole bag. The variadic argument overrides the bag's format; only the first is read.

func (*MessageBag) Forget

func (b *MessageBag) Forget(key string) *MessageBag

Forget drops every message under the key and returns the bag.

func (*MessageBag) Get

func (b *MessageBag) Get(key string, format ...string) []string

Get returns the messages under the key, formatted. A key holding a * is a pattern: * stands for any run of characters, including none, and every other rune is literal. The matches come back flattened, in key order.

func (*MessageBag) GetFormat

func (b *MessageBag) GetFormat() string

GetFormat returns the format messages are wrapped in, which is DefaultMessageFormat when none was set.

func (*MessageBag) GetMessageBag

func (b *MessageBag) GetMessageBag() *MessageBag

GetMessageBag returns the bag itself, so *MessageBag satisfies MessageProvider.

func (*MessageBag) GetMessages

func (b *MessageBag) GetMessages() map[string][]string

GetMessages returns a copy of the messages, the same as MessageBag.Messages.

func (*MessageBag) Has

func (b *MessageBag) Has(keys ...string) bool

Has reports whether the bag holds a message for every key given. With no key it reports whether the bag holds anything at all.

func (*MessageBag) HasAny

func (b *MessageBag) HasAny(keys ...string) bool

HasAny reports whether the bag holds a message for any key given. With no key it is false.

func (*MessageBag) IsEmpty

func (b *MessageBag) IsEmpty() bool

IsEmpty reports whether the bag holds no message.

func (*MessageBag) IsNotEmpty

func (b *MessageBag) IsNotEmpty() bool

IsNotEmpty reports whether the bag holds any message.

func (*MessageBag) Keys

func (b *MessageBag) Keys() []string

Keys returns the keys the bag holds messages under, in order.

func (*MessageBag) MarshalJSON

func (b *MessageBag) MarshalJSON() ([]byte, error)

MarshalJSON encodes the messages, so a MessageBag nests inside another encoded value. An empty bag encodes as {}.

func (*MessageBag) Merge

func (b *MessageBag) Merge(messages map[string][]string) *MessageBag

Merge appends the given messages and returns the bag, so a key present on both sides ends up carrying both lists, duplicates included.

To merge a MessageProvider, pass provider.GetMessageBag().GetMessages().

func (*MessageBag) Messages

func (b *MessageBag) Messages() map[string][]string

Messages returns a copy of the messages, keyed by field, unformatted.

func (*MessageBag) Missing

func (b *MessageBag) Missing(keys ...string) bool

Missing reports whether the bag holds no message for any of the keys.

func (*MessageBag) SetFormat

func (b *MessageBag) SetFormat(format string) *MessageBag

SetFormat sets the format messages are wrapped in and returns the bag. An empty format means DefaultMessageFormat.

func (*MessageBag) String

func (b *MessageBag) String() string

String returns the messages as JSON, or "{}" when they cannot be encoded, so MessageBag satisfies fmt.Stringer.

func (*MessageBag) ToArray

func (b *MessageBag) ToArray() map[string][]string

ToArray returns a copy of the messages, keyed by field.

func (*MessageBag) ToJson

func (b *MessageBag) ToJson() (string, error)

ToJson encodes the messages as JSON, or returns the error encoding raised.

func (*MessageBag) Unique

func (b *MessageBag) Unique(format ...string) []string

Unique returns every message in the bag with duplicates dropped, keeping the first occurrence.

type MessageProvider

type MessageProvider interface {
	// GetMessageBag returns the messages the value carries.
	GetMessageBag() *MessageBag
}

MessageProvider is implemented by a value that carries validation messages and can hand them over as a MessageBag. Taking the interface instead of the bag lets a caller pass whatever produced the errors and leave it to decide which messages to expose.

*MessageBag implements it by returning itself, so any type that holds a bag satisfies it by delegating one method.

type NamespacedItemResolver

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

NamespacedItemResolver turns a key of the form "package::group.item" into its three parts. Configuration keys and translation keys are both read this way. It is safe for concurrent use.

func NewNamespacedItemResolver

func NewNamespacedItemResolver() *NamespacedItemResolver

NewNamespacedItemResolver returns a resolver with an empty cache.

func (*NamespacedItemResolver) FlushParsedKeys

func (r *NamespacedItemResolver) FlushParsedKeys()

FlushParsedKeys empties the cache.

func (*NamespacedItemResolver) ParseKey

func (r *NamespacedItemResolver) ParseKey(key string) (namespace, group, item string)

ParseKey returns the namespace, the group and the item of a key, in that order. A key with no namespace, and a group asked for whole, give the empty string for the part they lack. Every key parsed is cached.

func (*NamespacedItemResolver) SetParsedKey

func (r *NamespacedItemResolver) SetParsedKey(key, namespace, group, item string)

SetParsedKey caches the three parts of a key, so NamespacedItemResolver.ParseKey hands them back without reading it.

type Onceable

type Onceable struct {
	// Hash is the key the value is stored under.
	Hash string
	// Object is whatever the call was made on, and may be nil.
	Object any
	// Callable computes the value the first time it is asked for.
	Callable func() any
}

Onceable identifies a memoized call: the call site, whatever it was called on, and the callback whose value is kept.

func NewOnceable

func NewOnceable(hash string, object any, callable func() any) *Onceable

NewOnceable builds an Onceable from a hash, an object and a callback.

func TryFromTrace

func TryFromTrace(skip int, callable func() any) *Onceable

TryFromTrace builds an Onceable keyed by the call site, or nil when the stack cannot be read. skip is how many frames to step over: 0 is the caller of TryFromTrace.

The key is the file, the function and the line, and nothing else: a closure cannot be asked what it captured, so two calls from one line share a value however their captured variables differ.

type Optional

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

Optional wraps a value and hands back nil for anything that value does not have, so a caller reading into it does not have to check at every step.

A nil Optional, and one wrapping nil, read the same: every lookup is nil.

func NewOptional

func NewOptional(value any) *Optional

NewOptional wraps a value, which may be nil.

func (*Optional) Get

func (o *Optional) Get(key string) any

Get returns the member of the value underneath named by key, or nil. A map is read by key and a struct by exported field name, with pointers followed; anything else is nil.

func (*Optional) IsSet

func (o *Optional) IsSet(key string) bool

IsSet reports whether Optional.Get finds anything non-nil under the key.

func (*Optional) OffsetExists

func (o *Optional) OffsetExists(key string) bool

OffsetExists reports whether the value underneath is a map[string]any that holds the key.

func (*Optional) OffsetGet

func (o *Optional) OffsetGet(key string) any

OffsetGet returns the value under the key, the same as Optional.Get.

func (*Optional) OffsetSet

func (o *Optional) OffsetSet(key string, v any)

OffsetSet writes under the key, but only when the value underneath is a map[string]any. Any other value drops the write.

func (*Optional) OffsetUnset

func (o *Optional) OffsetUnset(key string)

OffsetUnset deletes the key, but only when the value underneath is a map[string]any. Any other value drops the call.

func (*Optional) Value

func (o *Optional) Value() any

Value returns the value being wrapped.

type Sleep

type Sleep struct {
	// Duration is how long the sleep has been built up to so far.
	Duration time.Duration
	// contains filtered or unexported fields
}

Sleep is a duration built up unit by unit, which a test can capture instead of waiting out.

Nothing is slept until Sleep.Goodnight or Sleep.Then is called: there is no destructor to sleep from, so the end of the chain is where the wait happens. Calling either twice sleeps once.

func For

func For(duration any) *Sleep

For starts a sleep. A time.Duration is the whole duration; any other number is left pending until a unit method names it, as in For(2).Seconds().

func Until

func Until(timestamp any) *Sleep

Until starts a sleep that runs until the given instant, which is a time.Time or a number of seconds since the epoch. An instant already past is no sleep at all.

func Usleep

func Usleep(duration int) *Sleep

Usleep starts a sleep of the given number of microseconds.

func (*Sleep) And

func (s *Sleep) And(duration any) *Sleep

And leaves another number pending, waiting for its unit.

func (*Sleep) Goodnight

func (s *Sleep) Goodnight() error

Goodnight waits the duration out, and is what a caller writes at the end of the chain. Calling it twice sleeps once.

A number left without a unit is ErrUnknownDurationUnit. While a test is faking, nothing is waited: the duration is recorded, every callback registered with WhenFakingSleep is run with it, and the pinned clock moves forward by it when SyncWithCarbon asked for that.

func (*Sleep) Microsecond

func (s *Sleep) Microsecond() *Sleep

Microsecond is Sleep.Microseconds under the singular name.

func (*Sleep) Microseconds

func (s *Sleep) Microseconds() *Sleep

Microseconds reads the pending number as microseconds and adds it to the duration.

func (*Sleep) Millisecond

func (s *Sleep) Millisecond() *Sleep

Millisecond is Sleep.Milliseconds under the singular name.

func (*Sleep) Milliseconds

func (s *Sleep) Milliseconds() *Sleep

Milliseconds reads the pending number as milliseconds and adds it to the duration.

func (*Sleep) Minute

func (s *Sleep) Minute() *Sleep

Minute is Sleep.Minutes under the singular name.

func (*Sleep) Minutes

func (s *Sleep) Minutes() *Sleep

Minutes reads the pending number as minutes and adds it to the duration.

func (*Sleep) Second

func (s *Sleep) Second() *Sleep

Second is Sleep.Seconds under the singular name.

func (*Sleep) Seconds

func (s *Sleep) Seconds() *Sleep

Seconds reads the pending number as seconds and adds it to the duration.

func (*Sleep) Then

func (s *Sleep) Then(then func() any) (any, error)

Then sleeps, then runs the callback and hands back what it returned. A sleep that failed returns its error and the callback does not run.

func (*Sleep) Unless

func (s *Sleep) Unless(condition any) *Sleep

Unless sleeps only when the condition does not hold. It accepts the same shapes as Sleep.When.

func (*Sleep) When

func (s *Sleep) When(condition any) *Sleep

When sleeps only when the condition holds. The condition is a bool, a func() bool or a func(*Sleep) bool; anything else is read for its truth.

func (*Sleep) While

func (s *Sleep) While(callback func() bool) *Sleep

While keeps the sleep repeating for as long as the callback returns true.

type SystemClock

type SystemClock struct{}

SystemClock is the Clock the framework runs on outside a test: time.Now.

func (SystemClock) Now

func (SystemClock) Now() time.Time

Now returns the current instant, read from the operating system.

type Timebox

type Timebox struct {
	// EarlyReturn lifts the wait: the box returns as soon as the callback
	// does.
	EarlyReturn bool
}

Timebox runs a callback and does not return before the given number of microseconds has passed, so that the time a check took says nothing about its result.

func NewTimebox

func NewTimebox() *Timebox

NewTimebox returns a timebox that waits out its full duration.

func (*Timebox) Call

func (t *Timebox) Call(callback func(*Timebox) (any, error), microseconds int) (any, error)

Call runs the callback inside the timebox and returns what it returned. An error from the callback is held until the box has been waited out, so a failure does not come back any sooner than a success.

func (*Timebox) DontReturnEarly

func (t *Timebox) DontReturnEarly() *Timebox

DontReturnEarly restores the wait, and returns the timebox.

func (*Timebox) ReturnEarly

func (t *Timebox) ReturnEarly() *Timebox

ReturnEarly lifts the wait, and returns the timebox.

type Uri

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

Uri is a parsed URI whose every writer hands back a new instance and leaves the old one alone. It wraps a *url.URL, so this package carries no dependency of its own.

func Action

func Action(action string, parameters map[string]any, absolute bool) (*Uri, error)

Action returns the URI of a controller action.

func NewUri

func NewUri(uri string) (*Uri, error)

NewUri parses a URI, returning the error when it cannot be read.

func Of

func Of(uri string) (*Uri, error)

Of parses a URI, the same as NewUri.

func Route

func Route(name string, parameters map[string]any, absolute bool) (*Uri, error)

Route returns the URI of a named route, with its parameters filled in.

func SignedRoute

func SignedRoute(name string, parameters map[string]any, expiration *time.Time, absolute bool) (*Uri, error)

SignedRoute returns the URI of a named route carrying a signature, and an expiry when one is given.

func TemporarySignedRoute

func TemporarySignedRoute(name string, expiration time.Time, parameters map[string]any, absolute bool) (*Uri, error)

TemporarySignedRoute is SignedRoute with the expiry required and moved to the front.

func To

func To(path string) (*Uri, error)

To returns an absolute URI for the path, built by the UrlGenerator.

func (*Uri) Decode

func (u *Uri) Decode() string

Decode returns the URI with its query string percent-decoded, which is what a person reads in a browser bar.

func (*Uri) Fragment

func (u *Uri) Fragment() string

Fragment returns the fragment, without its leading hash.

func (*Uri) GetUri

func (u *Uri) GetUri() *url.URL

GetUri returns the *url.URL underneath. Writing to it writes through to this Uri, which every other method avoids.

func (*Uri) Host

func (u *Uri) Host() string

Host returns the host, without the port.

func (*Uri) IsEmpty

func (u *Uri) IsEmpty() bool

IsEmpty reports whether the URI written out is blank.

func (*Uri) Password

func (u *Uri) Password() string

Password returns the password, or the empty string when the URI carries none.

func (*Uri) Path

func (u *Uri) Path() string

Path returns the path with its slashes trimmed off both ends. An empty or missing path is a single "/".

func (*Uri) PathSegments

func (u *Uri) PathSegments() []string

PathSegments returns the path split on its slashes. An empty path is an empty list.

func (*Uri) Port

func (u *Uri) Port() int

Port returns the port, or zero when the URI carries none.

func (*Uri) PushOntoQuery

func (u *Uri) PushOntoQuery(key string, v any) *Uri

PushOntoQuery appends to the list a query parameter holds. A list already holding the value is left alone; a single value becomes a list of the two, with no such check.

func (*Uri) Query

func (u *Uri) Query() *UriQueryString

Query returns the query string as a UriQueryString.

func (*Uri) Redirect

func (u *Uri) Redirect(status int, headers map[string]string) nethttp.Handler

Redirect returns a handler that redirects to this URI with the given status.

It hands back a net/http.Handler rather than a response type of this framework's, because such a type lives in the http package and that package imports this one.

headers is applied before the redirect is written, because WriteHeader freezes the header map.

func (*Uri) ReplaceQuery

func (u *Uri) ReplaceQuery(query map[string]any) *Uri

ReplaceQuery returns a copy whose query string is thrown away and written again from the given pairs.

func (*Uri) Scheme

func (u *Uri) Scheme() string

Scheme returns the URI's scheme.

func (*Uri) String

func (u *Uri) String() string

String returns the URI written out, so Uri satisfies fmt.Stringer.

func (*Uri) ToHtml

func (u *Uri) ToHtml() string

ToHtml returns the URI as markup, ready to write into a template.

func (*Uri) ToResponse

func (u *Uri) ToResponse(*nethttp.Request) nethttp.Handler

ToResponse returns a handler that redirects to this URI with status 302.

The request is taken and ignored: the parameter is there so the method fits the shape a caller turning a value into a response expects.

func (*Uri) User

func (u *Uri) User(withPassword bool) string

User returns the user name, or the whole user info when withPassword is true. A URI carrying neither is the empty string.

func (*Uri) Value

func (u *Uri) Value() string

Value returns the URI written out as a string.

func (*Uri) WithFragment

func (u *Uri) WithFragment(fragment string) *Uri

WithFragment returns a copy carrying the given fragment.

func (*Uri) WithHost

func (u *Uri) WithHost(host string) *Uri

WithHost returns a copy carrying the given host, keeping whatever port the URI already had.

func (*Uri) WithPath

func (u *Uri) WithPath(path string) *Uri

WithPath returns a copy carrying the given path, which is given a leading slash when it does not already have one.

func (*Uri) WithPort

func (u *Uri) WithPort(port int) *Uri

WithPort returns a copy carrying the given port. A zero port removes it.

func (*Uri) WithQuery

func (u *Uri) WithQuery(query map[string]any, merge ...bool) *Uri

WithQuery returns a copy with the pairs written into the query string by dotted key. The variadic argument is whether to merge into the query already there and defaults to true; false replaces it instead.

func (*Uri) WithQueryIfMissing

func (u *Uri) WithQueryIfMissing(query map[string]any) *Uri

WithQueryIfMissing returns a copy carrying only the keys the query string does not already hold.

func (*Uri) WithScheme

func (u *Uri) WithScheme(scheme string) *Uri

WithScheme returns a copy carrying the given scheme.

func (*Uri) WithUser

func (u *Uri) WithUser(user string, password ...string) *Uri

WithUser returns a copy carrying the given user, and the password when one is given. An empty user drops the user info entirely.

func (*Uri) WithoutQuery

func (u *Uri) WithoutQuery(keys ...string) *Uri

WithoutQuery returns a copy whose query string has dropped the given keys.

type UriQueryString

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

UriQueryString is the query string of a Uri, read as nested data. The typed readers of the embedded data source read that data.

func NewUriQueryString

func NewUriQueryString(uri *Uri) *UriQueryString

NewUriQueryString builds the query string reader for a Uri.

func (*UriQueryString) All

func (q *UriQueryString) All(keys ...string) map[string]any

All returns the whole query string when given no key, and the subset under the given dotted keys otherwise.

func (UriQueryString) AnyFilled

func (d UriQueryString) AnyFilled(keys ...string) bool

AnyFilled reports whether at least one of the keys is filled.

func (UriQueryString) Array

func (d UriQueryString) Array(key string) []any

Array returns the value at the key as a list, wrapping a value that is not one. To read several keys at once, use [dataSource.Only]: the two shapes cannot share a return type.

func (UriQueryString) Boolean

func (d UriQueryString) Boolean(key string, def ...bool) bool

Boolean returns the value at the key as a bool: "1", "true", "on" and "yes" are true, in any case, and everything else is false. The optional default is used when the key is absent, and is false when not given.

func (UriQueryString) Collect

func (d UriQueryString) Collect(key string) []any

Collect is [dataSource.Array] under a second name.

func (UriQueryString) Data

func (d UriQueryString) Data(key string, def any) any

Data returns one value out of the source, by dotted key, falling back to the default. It is exported because Enum and Enums are functions and have to reach it from outside the type.

func (UriQueryString) Date

func (d UriQueryString) Date(key string, formatAndLocation ...string) (time.Time, error)

Date returns the value at the key as a time.Time. The variadic argument is the layout and then the location name, in that order; with no layout the value is read by Parse.

A key that is not filled gives the zero time and no error. A value that cannot be read, and a location name that cannot be loaded, are errors.

func (*UriQueryString) Decode

func (q *UriQueryString) Decode() string

Decode returns the whole query string percent-decoded, or as it stands when it cannot be decoded.

func (UriQueryString) Except

func (d UriQueryString) Except(keys ...string) map[string]any

Except returns everything but the given dotted keys. The data is copied first, so the source is left alone.

func (UriQueryString) Exists

func (d UriQueryString) Exists(keys ...string) bool

Exists is [dataSource.Has] under a second name.

func (UriQueryString) Filled

func (d UriQueryString) Filled(keys ...string) bool

Filled reports whether every key holds something that is not an empty string. A bool, a list and a map count as filled even when empty.

func (UriQueryString) Float

func (d UriQueryString) Float(key string, def ...float64) float64

Float returns the value at the key as a float64, reading the leading numeric run, or zero when there is none. The optional default is used when the key is absent, and is zero when not given.

func (*UriQueryString) Get

func (q *UriQueryString) Get(key string, def ...any) any

Get returns one parameter by dotted key, falling back to the optional default. An empty key returns the whole query string, and the default is not consulted.

func (UriQueryString) Has

func (d UriQueryString) Has(keys ...string) bool

Has reports whether every one of the dotted keys is present. With no key it is false.

func (UriQueryString) HasAny

func (d UriQueryString) HasAny(keys ...string) bool

HasAny reports whether at least one of the dotted keys is present.

func (UriQueryString) Integer

func (d UriQueryString) Integer(key string, def ...int) int

Integer returns the value at the key as an int, reading the leading numeric run and truncating it, or zero when there is none. The optional default is used when the key is absent, and is zero when not given.

func (UriQueryString) IsNotFilled

func (d UriQueryString) IsNotFilled(keys ...string) bool

IsNotFilled reports whether every one of the keys is empty.

func (UriQueryString) Missing

func (d UriQueryString) Missing(keys ...string) bool

Missing reports whether any of the dotted keys is absent.

func (UriQueryString) Only

func (d UriQueryString) Only(keys ...string) map[string]any

Only returns the subset under the given dotted keys, leaving out the keys that are absent.

func (UriQueryString) Str

func (d UriQueryString) Str(key string, def ...any) string

Str is [dataSource.String] under a second name.

func (UriQueryString) String

func (d UriQueryString) String(key string, def ...any) string

String returns the value at the key as a string, falling back to the optional default. It is a plain string and not a richer wrapper, so this package carries no dependency on the string package.

func (*UriQueryString) ToArray

func (q *UriQueryString) ToArray() map[string]any

ToArray returns the query string as nested data.

A key is decoded before its brackets are read, so a%5Bb%5D=c and a[b]=c give the same nesting.

func (*UriQueryString) Value

func (q *UriQueryString) Value() string

Value returns the raw query string, or the empty string when there is no URI behind it.

func (UriQueryString) WhenFilled

func (d UriQueryString) WhenFilled(key string, callback func(value any), def ...func())

WhenFilled runs the callback with the value when the key is filled, and the optional fallback when it is not. It returns nothing for the reason given on [dataSource.WhenHas].

func (UriQueryString) WhenHas

func (d UriQueryString) WhenHas(key string, callback func(value any), def ...func())

WhenHas runs the callback with the value when the key is present, and the optional fallback when it is not.

It returns nothing: an embedded struct cannot reach the type that embeds it, so there is no receiver to hand back for chaining.

func (UriQueryString) WhenMissing

func (d UriQueryString) WhenMissing(key string, callback func(value any), def ...func())

WhenMissing runs the callback when the key is absent, and the optional fallback when it is present. It returns nothing for the reason given on [dataSource.WhenHas].

type UrlGenerator

type UrlGenerator interface {
	// To returns an absolute URL for the given path.
	To(path string) string
	// Route returns the URL of a named route, with its parameters filled in.
	Route(name string, parameters map[string]any, absolute bool) (string, error)
	// SignedRoute returns the URL of a named route carrying a signature, and
	// an expiry when one is given.
	SignedRoute(name string, parameters map[string]any, expiration *time.Time, absolute bool) (string, error)
	// Action returns the URL of a controller action.
	Action(action string, parameters map[string]any, absolute bool) (string, error)
}

UrlGenerator builds absolute URLs for named routes and actions. The routing package fills it in; only what Uri calls is declared here, so this package carries no dependency on routing.

type ValidatedInput

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

ValidatedInput carries the input that passed validation, and nothing else.

The typed readers of the embedded data source -- String, Integer, Float, Boolean, Array, Date, Only, Except, Collect, Has, Missing -- read that input.

func NewValidatedInput

func NewValidatedInput(input map[string]any) *ValidatedInput

NewValidatedInput builds a ValidatedInput over a copy of the given input.

func (*ValidatedInput) All

func (v *ValidatedInput) All(keys ...string) map[string]any

All returns the whole input when given no key, and the subset under the given dotted keys otherwise.

func (ValidatedInput) AnyFilled

func (d ValidatedInput) AnyFilled(keys ...string) bool

AnyFilled reports whether at least one of the keys is filled.

func (ValidatedInput) Array

func (d ValidatedInput) Array(key string) []any

Array returns the value at the key as a list, wrapping a value that is not one. To read several keys at once, use [dataSource.Only]: the two shapes cannot share a return type.

func (ValidatedInput) Boolean

func (d ValidatedInput) Boolean(key string, def ...bool) bool

Boolean returns the value at the key as a bool: "1", "true", "on" and "yes" are true, in any case, and everything else is false. The optional default is used when the key is absent, and is false when not given.

func (ValidatedInput) Collect

func (d ValidatedInput) Collect(key string) []any

Collect is [dataSource.Array] under a second name.

func (ValidatedInput) Data

func (d ValidatedInput) Data(key string, def any) any

Data returns one value out of the source, by dotted key, falling back to the default. It is exported because Enum and Enums are functions and have to reach it from outside the type.

func (ValidatedInput) Date

func (d ValidatedInput) Date(key string, formatAndLocation ...string) (time.Time, error)

Date returns the value at the key as a time.Time. The variadic argument is the layout and then the location name, in that order; with no layout the value is read by Parse.

A key that is not filled gives the zero time and no error. A value that cannot be read, and a location name that cannot be loaded, are errors.

func (*ValidatedInput) Dd

func (v *ValidatedInput) Dd(keys ...string)

Dd dumps, then ends the process with status 1.

func (*ValidatedInput) Dump

func (v *ValidatedInput) Dump(keys ...string) *ValidatedInput

Dump writes the input to standard error through Dump and returns the ValidatedInput. Given keys, only those are written.

func (ValidatedInput) Except

func (d ValidatedInput) Except(keys ...string) map[string]any

Except returns everything but the given dotted keys. The data is copied first, so the source is left alone.

func (ValidatedInput) Exists

func (d ValidatedInput) Exists(keys ...string) bool

Exists is [dataSource.Has] under a second name.

func (ValidatedInput) Filled

func (d ValidatedInput) Filled(keys ...string) bool

Filled reports whether every key holds something that is not an empty string. A bool, a list and a map count as filled even when empty.

func (ValidatedInput) Float

func (d ValidatedInput) Float(key string, def ...float64) float64

Float returns the value at the key as a float64, reading the leading numeric run, or zero when there is none. The optional default is used when the key is absent, and is zero when not given.

func (ValidatedInput) Has

func (d ValidatedInput) Has(keys ...string) bool

Has reports whether every one of the dotted keys is present. With no key it is false.

func (ValidatedInput) HasAny

func (d ValidatedInput) HasAny(keys ...string) bool

HasAny reports whether at least one of the dotted keys is present.

func (*ValidatedInput) Input

func (v *ValidatedInput) Input(key string, def ...any) any

Input returns one item by dotted key, falling back to the optional default, which is nil when not given. An empty key returns everything.

func (ValidatedInput) Integer

func (d ValidatedInput) Integer(key string, def ...int) int

Integer returns the value at the key as an int, reading the leading numeric run and truncating it, or zero when there is none. The optional default is used when the key is absent, and is zero when not given.

func (ValidatedInput) IsNotFilled

func (d ValidatedInput) IsNotFilled(keys ...string) bool

IsNotFilled reports whether every one of the keys is empty.

func (*ValidatedInput) Keys

func (v *ValidatedInput) Keys() []string

Keys returns the top-level keys, sorted. A map has no order of its own, so sorted is the only order that can be promised.

func (*ValidatedInput) Merge

func (v *ValidatedInput) Merge(items map[string]any) *ValidatedInput

Merge returns a new ValidatedInput carrying this input with the given items written over it. The receiver is left alone.

func (ValidatedInput) Missing

func (d ValidatedInput) Missing(keys ...string) bool

Missing reports whether any of the dotted keys is absent.

func (ValidatedInput) Only

func (d ValidatedInput) Only(keys ...string) map[string]any

Only returns the subset under the given dotted keys, leaving out the keys that are absent.

func (ValidatedInput) Str

func (d ValidatedInput) Str(key string, def ...any) string

Str is [dataSource.String] under a second name.

func (ValidatedInput) String

func (d ValidatedInput) String(key string, def ...any) string

String returns the value at the key as a string, falling back to the optional default. It is a plain string and not a richer wrapper, so this package carries no dependency on the string package.

func (*ValidatedInput) ToArray

func (v *ValidatedInput) ToArray() map[string]any

ToArray returns a copy of the whole input.

func (ValidatedInput) WhenFilled

func (d ValidatedInput) WhenFilled(key string, callback func(value any), def ...func())

WhenFilled runs the callback with the value when the key is filled, and the optional fallback when it is not. It returns nothing for the reason given on [dataSource.WhenHas].

func (ValidatedInput) WhenHas

func (d ValidatedInput) WhenHas(key string, callback func(value any), def ...func())

WhenHas runs the callback with the value when the key is present, and the optional fallback when it is not.

It returns nothing: an embedded struct cannot reach the type that embeds it, so there is no receiver to hand back for chaining.

func (ValidatedInput) WhenMissing

func (d ValidatedInput) WhenMissing(key string, callback func(value any), def ...func())

WhenMissing runs the callback when the key is absent, and the optional fallback when it is present. It returns nothing for the reason given on [dataSource.WhenHas].

type ViewErrorBag

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

ViewErrorBag holds the named MessageBag values a request carries, one of them under DefaultErrorBag.

The read side of MessageBag is repeated on this type, each method reading the default bag, so a view does not have to name it.

func NewViewErrorBag

func NewViewErrorBag() *ViewErrorBag

NewViewErrorBag returns a ViewErrorBag holding no bags.

func (*ViewErrorBag) All

func (v *ViewErrorBag) All(format ...string) []string

All returns every message in the default bag.

func (*ViewErrorBag) Any

func (v *ViewErrorBag) Any() bool

Any reports whether the default bag holds any message.

func (*ViewErrorBag) Count

func (v *ViewErrorBag) Count() int

Count returns how many messages the default bag holds.

func (*ViewErrorBag) First

func (v *ViewErrorBag) First(key string, format ...string) string

First returns the first message under the key in the default bag.

func (*ViewErrorBag) Get

func (v *ViewErrorBag) Get(key string, format ...string) []string

Get returns the messages under the key in the default bag.

func (*ViewErrorBag) GetBag

func (v *ViewErrorBag) GetBag(key string) *MessageBag

GetBag returns the bag under the key, or an empty MessageBag when there is none. It is never nil, so a view can call First on it unguarded. An empty key means DefaultErrorBag.

func (*ViewErrorBag) GetBags

func (v *ViewErrorBag) GetBags() map[string]*MessageBag

GetBags returns a copy of the map of bags, keyed by name.

func (*ViewErrorBag) Has

func (v *ViewErrorBag) Has(keys ...string) bool

Has reports whether the default bag holds a message for every key given.

func (*ViewErrorBag) HasAny

func (v *ViewErrorBag) HasAny(keys ...string) bool

HasAny reports whether the default bag holds a message for any key given.

func (*ViewErrorBag) HasBag

func (v *ViewErrorBag) HasBag(key string) bool

HasBag reports whether a bag is held under the key. An empty key means DefaultErrorBag.

func (*ViewErrorBag) IsEmpty

func (v *ViewErrorBag) IsEmpty() bool

IsEmpty reports whether the default bag holds no message.

func (*ViewErrorBag) IsNotEmpty

func (v *ViewErrorBag) IsNotEmpty() bool

IsNotEmpty reports whether the default bag holds any message.

func (*ViewErrorBag) Keys

func (v *ViewErrorBag) Keys() []string

Keys lists the keys the default bag holds messages under.

func (*ViewErrorBag) Messages

func (v *ViewErrorBag) Messages() map[string][]string

Messages returns the default bag's messages, keyed by field.

func (*ViewErrorBag) Missing

func (v *ViewErrorBag) Missing(keys ...string) bool

Missing reports whether the default bag holds no message for any of the keys.

func (*ViewErrorBag) Names

func (v *ViewErrorBag) Names() []string

Names lists the bag names, sorted. A map has no order of its own, so sorted is the only order that can be promised.

func (*ViewErrorBag) Put

func (v *ViewErrorBag) Put(key string, bag *MessageBag) *ViewErrorBag

Put stores a bag under the key and returns the ViewErrorBag. An empty key means DefaultErrorBag.

func (*ViewErrorBag) String

func (v *ViewErrorBag) String() string

String returns the default bag as JSON, so ViewErrorBag satisfies fmt.Stringer.

func (*ViewErrorBag) ToArray

func (v *ViewErrorBag) ToArray() map[string][]string

ToArray returns the default bag's messages keyed by field, which is what a view writes out when it dumps the errors.

func (*ViewErrorBag) ToJson

func (v *ViewErrorBag) ToJson() (string, error)

ToJson encodes the default bag's messages as JSON.

func (*ViewErrorBag) Unique

func (v *ViewErrorBag) Unique(format ...string) []string

Unique returns every message in the default bag, with duplicates dropped.

Directories

Path Synopsis
Package deferpkg holds work put off until after the response has been sent.
Package deferpkg holds work put off until after the response has been sent.
Package exceptions holds the error types the support packages share.
Package exceptions holds the error types the support packages share.
Package facades declares nothing, and never will.
Package facades declares nothing, and never will.
Package testing groups the test doubles this module ships.
Package testing groups the test doubles this module ships.
fakes
Package fakes holds the test doubles a test installs so that nothing leaves the process, and so that every message, job, event and notification can be asserted on afterwards.
Package fakes holds the test doubles a test installs so that nothing leaves the process, and so that every message, job, event and notification can be asserted on afterwards.
Package traits declares nothing, and is kept only so the import path resolves.
Package traits declares nothing, and is kept only so the import path resolves.

Jump to

Keyboard shortcuts

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