std/uri/template
std/uri/src/template.trb
UriTemplate: RFC 6570, all four levels - read once, expanded into a URI reference, and matched backwards where the
template allows it (docs/design/URI.md section 9a).
type TemplateValue
type TemplateValue with Show, Equals, Hash
What a variable of a template holds: RFC 6570 section 2.3's three kinds of value. A variable that is not in the map
handed to UriTemplate.expanded is undefined, and so is an empty list or an empty list of pairs.
type UriTemplate
type UriTemplate<Variables> with Show, Equals, Hash, TryFrom<String, UriError>
An RFC 6570 URI template: literal text and {…} expressions, read once with UriTemplate.tryFrom and expanded with
variables into a URI reference - "/orders/{id}{?fields*}" with id = 7 and fields = ["a", "b"] is
/orders/7?fields=a&fields=b.
The four levels are all there: simple strings ({var}), reserved and fragment expansion ({+var}, {#var}), the
label, path, parameter and query operators with several variables ({.x,y}, {/x}, {;x}, {?x,y}, {&x}), and
the prefix and explode modifiers ({var:3}, {list*}).
Variables is the type whose fields the variables are (docs/design/URI.md section 9a): a string literal where a
UriTemplate<Order> is expected is read by the compiler, and a variable that is not a field of Order - or a
field without a default that is no variable - is an error at the literal. UriTemplate.expandedFrom and
UriTemplate.decoded go through the fields; TemplateValues is the type of a template read at run time, whose
variables are whatever the map holds. Inside such a literal {id} is the template's own brace and never an
interpolation, so it needs no raw.
Examples
const template: UriTemplate<TemplateValues> = "/orders/{id}{?fields}"
var values: TemplateValues = [:]
values["id"] = TemplateValue.Text "7"
print template.expanded(values)
Pitfalls
- Matching reads a template backwards only where that is unambiguous;
UriTemplate.isMatchablesays whether it is. - A typed template read at run time,
UriTemplate<Order>.tryFrom(text), is checked againstOrderonly when it is expanded or matched; a literal is checked where it is written.
Related
TemplateValue- what a variable holds.TemplateRoutesofstd/uri- templates typed against the cases of one type, which is what a router holds.
fn tryFrom
static fn tryFrom(value: String): Result<UriTemplate<Variables>, UriError>
A text read as an RFC 6570 template.
Errors
UriError.InvalidTemplatefor an unclosed or a nested brace, an empty expression, a variable name outsidevarchar, a prefix outside 1 to 9999, a reserved operator (=,,,!,@,|), and a literal character no URI may hold.
fn templateVariables
fn templateVariables(): List<TemplateVariable>
Every variable once, in the order it first appears, with what kind of value fills it: what a value of
Variables is checked against.
fn expandedFrom
fn expandedFrom(values: Variables): Result<UriReference, UriError> where Variables: Encode
The template expanded with the fields of values: each field is the variable of its name, a list field an
exploded one, and a field that is None an undefined variable. Fields no variable names are left out.
Errors
- As for
UriTemplate.expanded.
fn decoded
fn decoded(reference: UriReference): Variables? where Variables: Decode
The fields of reference read back into a Variables, where the reference is an expansion of this template: the
text of each variable is read as whatever its field asks for, and a variable the reference leaves out is a field
that is absent, so its default applies. None where UriTemplate.matched answers None or a field cannot be read.
fn variables
fn variables(): List<String>
The names of the variables, in the order they first appear.
fn level
fn level(): Int
The lowest of RFC 6570's four levels that has every expression of this template.
fn expandedText
fn expandedText(values: TemplateValues): Result<String, UriError>
The template expanded with values, as RFC 6570 section 3 writes it. A variable that is not in values is
undefined and expands to nothing.
Errors
UriError.InvalidTemplatefor a prefix modifier on a list or on pairs, which RFC 6570 section 2.4.1 does not apply to.
fn expanded
fn expanded(values: TemplateValues): Result<UriReference, UriError>
The template expanded with values and read as the URI reference it is.
Errors
UriError.InvalidTemplateas forUriTemplate.expandedText.- Any refusal of
UriReference.tryFrom, where the literal parts of the template do not make a URI reference with the values in them ({x}:ywithx=1a). A template whose literal parts are a path never fails here.
fn isMatchable
fn isMatchable(): Bool
Whether UriTemplate.matched can read this template backwards: its expressions are simple ones ({name},
{a,b}), path segments ({/name}, {/name*} last in the path) and query parameters ({?a,b}, {&c}), no
prefix is used, and no two expressions of the path stand side by side without a literal between them.
fn matched
fn matched(reference: UriReference): TemplateValues?
The values that expand this template into reference, decoded: a simple or path variable as Text, an exploded
path variable as Items, a query variable as Text where the query has it. None where the reference is not an
expansion of the template, and for every template that is not UriTemplate.isMatchable. Query parameters the
template does not name are ignored, and a name that appears twice takes its first value.
Examples
const template: UriTemplate<TemplateValues> = "/orders/{id}{?fields}"
const reference: UriReference = "/orders/7?fields=total"
print template.matched(reference)
fn show
fn show(): String
The template as it was written.
alias TemplateValues
type TemplateValues = Map<String, TemplateValue>
The variables of a template read at run time: whatever the map holds, by name. UriTemplate<TemplateValues> is
the untyped template.
extend String with From<UriTemplate<TemplateValues>>
extend String with From<UriTemplate<TemplateValues>>
The way back out of an untyped UriTemplate, and with UriTemplate.tryFrom its conversion pair. A typed one has
none: an extension cannot be generic, so show() is its text.
fn from
static fn from(value: UriTemplate<TemplateValues>): String
type TemplateVariable
type TemplateVariable with Show, Equals, Hash
One variable of a template, as a value that fills it sees it (UriTemplate.templateVariables).
field name
name: String
The name, as the template writes it.
field isOptional
isOptional: Bool
Whether it stands in a query expression ({?a}, {&b}), so that a matched reference may leave it out.
field isExploded
isExploded: Bool
Whether it is exploded ({/path*}), so that its value is a list.