Documentation
¶
Overview ¶
Package preset holds named bundles of barqr options.
A preset is the answer to "we always send the same fourteen query parameters". The caller names one — `?preset=print` — and the service expands it into the option keys the request layer already understands, in the same dot notation the query string and multipart transports use (`style.module`, `output.dpi`, `encode.ecc`). Nothing here knows what those keys mean; expansion and validation stay with the request layer, so adding an option to Request makes it presettable with no change to this package.
Presets come from two places: the built-ins compiled into the binary, and a directory of JSON files named by BARQR_PRESETS_PATH. The directory is operator-supplied and therefore untrusted input — see Load for the guards.
Index ¶
Constants ¶
const ( // MaxFileBytes caps one preset file. A preset is a flat map of a few dozen // short strings; 64 KiB is two orders of magnitude of headroom, and // anything larger is a mistake or an attack rather than a preset. MaxFileBytes = 64 << 10 // MaxPresets caps how many presets a Set may hold, built-ins included. // The names are served on /v1/presets and offered as typo suggestions, so // an unbounded count would turn a mounted directory into a response-size // and CPU problem elsewhere in the service. MaxPresets = 256 // MaxOptions caps the option keys in one preset. The request layer has // well under a hundred settable paths, so a preset needing more than this // is not describing a barqr request. MaxOptions = 128 )
Limits on what a presets directory may contain. They exist because the directory is mounted by an operator and read at boot: a runaway file or a runaway file count must fail loudly and cheaply, not exhaust the process.
Variables ¶
var ( // ErrNotADirectory means the configured presets path is not a directory. ErrNotADirectory = errors.New("presets path is not a directory") // ErrUnreadable means the presets directory could not be listed at all, // which is a configuration fault rather than a bad individual file. ErrUnreadable = errors.New("presets directory could not be read") )
Sentinel errors for the preset package.
Functions ¶
Types ¶
type Preset ¶
type Preset struct {
// Name is the slug the caller asks for. It matches ValidName.
Name string `json:"name"`
// Kind separates a layout from a theme, so a caller — or the documentation
// UI — can offer them as the two different questions they answer: where is
// this code going, and what should it look like. Empty means layout.
Kind Kind `json:"kind,omitempty"`
// Description is one line of prose for /v1/presets listings.
Description string `json:"description,omitempty"`
// Options maps dot-notation option keys to values.
Options map[string]any `json:"options"`
}
Preset is a named bundle of options.
Options are keyed in the request layer's dot notation — "style.module", "output.format", "encode.ecc" — and the values are whatever JSON produced: string, float64, bool. They are applied as if the caller had sent them, so an explicit parameter on the request overrides the preset's value for the same key.
func (Preset) Clone ¶
Clone returns a copy whose Options map shares nothing with the receiver.
Sets are read-only after construction and are shared by every in-flight request, so handing out the internal map would let one request's option merge corrupt every later request that names the same preset.
type Set ¶
type Set struct {
// contains filtered or unexported fields
}
Set is an immutable collection of presets, looked up by name.
The zero value is not usable; build one with Builtin or Load.
func Builtin ¶
func Builtin() *Set
Builtin returns the presets compiled into the binary.
The returned Set is a fresh copy, so a caller that loads a directory over it cannot mutate the built-ins seen by anything else.
func Load ¶
Load returns the built-in presets overlaid with the JSON files in dir.
A user preset whose name matches a built-in **overrides** it: the file wins, completely, and the built-in's options are not merged underneath. That is the point — an operator who wants "print" to mean 600 dpi in their shop should not have to fight the value compiled into the binary.
An empty dir means built-ins only, which is the default configuration.
A malformed, oversized or badly named file is a warning, not a failure: one bad file in a mounted directory must not stop the service booting. The warnings are returned so the caller can log them at boot; they name the file but never its path. An error is returned only when the directory itself cannot be used, which is a configuration fault the operator must see.
dir is operator-controlled input and is treated as untrusted. See the guards inline below: extension, file type, containment, name shape, size, and count.