Sourcemeta Core 0.0.0
Loading...
Searching...
No Matches
URI Template

A strict RFC 6570 URI Template implementation. More...

Classes

class  sourcemeta::core::URITemplate
class  sourcemeta::core::URITemplateParseError
class  sourcemeta::core::URITemplateExpansionError
class  sourcemeta::core::URITemplateRouterVariableMismatchError
class  sourcemeta::core::URITemplateRouterInvalidSegmentError
class  sourcemeta::core::URITemplateRouterInvalidOperationIdError
class  sourcemeta::core::URITemplateRouterDuplicateOperationIdError
class  sourcemeta::core::URITemplateRouterSaveError
class  sourcemeta::core::URITemplateRouterReadError
class  sourcemeta::core::URITemplateRouter
class  sourcemeta::core::URITemplateRouterView
struct  sourcemeta::core::URITemplateTokenLiteral
struct  sourcemeta::core::URITemplateVariableSpecification
struct  sourcemeta::core::URITemplateTokenVariable
struct  sourcemeta::core::URITemplateTokenReservedExpansion
struct  sourcemeta::core::URITemplateTokenFragmentExpansion
struct  sourcemeta::core::URITemplateTokenLabelExpansion
struct  sourcemeta::core::URITemplateTokenPathExpansion
struct  sourcemeta::core::URITemplateTokenPathParameterExpansion
struct  sourcemeta::core::URITemplateTokenQueryExpansion
struct  sourcemeta::core::URITemplateTokenQueryContinuationExpansion

Typedefs

using sourcemeta::core::URITemplateValue
using sourcemeta::core::URITemplateParseResult
using sourcemeta::core::URITemplateToken

Enumerations

enum class  sourcemeta::core::URITemplateExpansionMode : std::uint8_t { URITemplateExpansionMode::URI , URITemplateExpansionMode::IRI }

Detailed Description

A strict RFC 6570 URI Template implementation.

This functionality is included as follows:

#include <sourcemeta/core/uritemplate.h>

Class Documentation

◆ sourcemeta::core::URITemplate

class sourcemeta::core::URITemplate

A parsed URI Template per RFC 6570. This class behaves like a view. The source string must outlive the template

Public Member Functions

 URITemplate (const std::string_view source)
auto size () const noexcept -> std::uint64_t
 Get the number of tokens in the template.
auto empty () const noexcept -> bool
 Check if the template is empty.
auto at (std::size_t index) const &-> const URITemplateToken &
 Get the token at the given index.
auto at (std::size_t index) &&-> URITemplateToken
 Get the token at the given index (move overload).
auto expand (const std::function< URITemplateValue(std::string_view)> &callback, URITemplateExpansionMode mode=URITemplateExpansionMode::URI) const -> std::string
template<typename Container, typename = std::void_t<typename Container::key_type>>
auto expand (const Container &variables, const URITemplateExpansionMode mode=URITemplateExpansionMode::URI) const -> std::string
 Expand the template using an associative container (string values only).

Static Public Member Functions

static auto is_uritemplate (std::string_view input) noexcept -> bool

Constructor & Destructor Documentation

◆ URITemplate()

sourcemeta::core::URITemplate::URITemplate ( const std::string_view source)

Parse a URI Template from a string view. For example:

#include <sourcemeta/core/uritemplate.h>
const std::string source{"http://example.com/~{username}/"};
const sourcemeta::core::URITemplate uri_template{source};
Definition uritemplate.h:65

Member Function Documentation

◆ expand()

auto sourcemeta::core::URITemplate::expand ( const std::function< URITemplateValue(std::string_view)> & callback,
URITemplateExpansionMode mode = URITemplateExpansionMode::URI ) const -> std::string
nodiscard

Expand the template by looking up variable values via a callback. The callback is called repeatedly for composite values

◆ is_uritemplate()

auto sourcemeta::core::URITemplate::is_uritemplate ( std::string_view input) -> bool
staticnodiscardnoexcept

Check whether the given string is a valid RFC 6570 URI Template without building the parsed representation. For example:

#include <sourcemeta/core/uritemplate.h>
#include <cassert>
"http://example.com/~{username}/"));
static auto is_uritemplate(std::string_view input) noexcept -> bool

◆ sourcemeta::core::URITemplateParseError

class sourcemeta::core::URITemplateParseError

An error that represents a URI Template parsing failure

Inheritance diagram for sourcemeta::core::URITemplateParseError:

Public Member Functions

 URITemplateParseError (const std::uint64_t column)
 Construct an error given the column number where parsing failed.
auto column () const noexcept -> std::uint64_t
 Get the column number of the error.

◆ sourcemeta::core::URITemplateExpansionError

class sourcemeta::core::URITemplateExpansionError

An error that represents a URI Template expansion failure

Inheritance diagram for sourcemeta::core::URITemplateExpansionError:

Public Member Functions

 URITemplateExpansionError (const std::string &message)
 Construct an error with a descriptive message.

◆ sourcemeta::core::URITemplateRouterVariableMismatchError

class sourcemeta::core::URITemplateRouterVariableMismatchError

An error that represents a variable name mismatch when adding routes

Inheritance diagram for sourcemeta::core::URITemplateRouterVariableMismatchError:

Public Member Functions

 URITemplateRouterVariableMismatchError (const std::string_view left, const std::string_view right)
 Construct an error given the existing and conflicting variable names.
auto left () const noexcept -> const std::string &
 Get the existing variable name.
auto right () const noexcept -> const std::string &
 Get the conflicting variable name.

◆ sourcemeta::core::URITemplateRouterInvalidSegmentError

class sourcemeta::core::URITemplateRouterInvalidSegmentError

An error for invalid segments when adding routes

Inheritance diagram for sourcemeta::core::URITemplateRouterInvalidSegmentError:

Public Member Functions

 URITemplateRouterInvalidSegmentError (const char *message, const std::string_view segment)
 Construct an error given a descriptive message and the offending segment.
auto segment () const noexcept -> const std::string &
 Get the offending segment.

◆ sourcemeta::core::URITemplateRouterInvalidOperationIdError

class sourcemeta::core::URITemplateRouterInvalidOperationIdError

An error that represents an operation identifier that does not match the permitted format

Inheritance diagram for sourcemeta::core::URITemplateRouterInvalidOperationIdError:

Public Member Functions

 URITemplateRouterInvalidOperationIdError (const std::string_view operation_id)
 Construct an error given the offending operation identifier.
auto operation_id () const noexcept -> const std::string &
 Get the offending operation identifier.

◆ sourcemeta::core::URITemplateRouterDuplicateOperationIdError

class sourcemeta::core::URITemplateRouterDuplicateOperationIdError

An error that represents an operation identifier that conflicts with a previously registered route

Inheritance diagram for sourcemeta::core::URITemplateRouterDuplicateOperationIdError:

Public Member Functions

 URITemplateRouterDuplicateOperationIdError (const std::string_view operation_id)
 Construct an error given the conflicting operation identifier.
auto operation_id () const noexcept -> const std::string &
 Get the conflicting operation identifier.

◆ sourcemeta::core::URITemplateRouterSaveError

class sourcemeta::core::URITemplateRouterSaveError

An error that represents a failure to save the router to disk

Inheritance diagram for sourcemeta::core::URITemplateRouterSaveError:

Public Member Functions

 URITemplateRouterSaveError (std::filesystem::path path, const char *message)
 Construct an error given the target path and a descriptive message.
auto path () const noexcept -> const std::filesystem::path &
 Get the path that could not be saved.

◆ sourcemeta::core::URITemplateRouterReadError

class sourcemeta::core::URITemplateRouterReadError

An error that represents a failure to read the router from disk

Inheritance diagram for sourcemeta::core::URITemplateRouterReadError:

Public Member Functions

 URITemplateRouterReadError (std::filesystem::path path)
 Construct an error given the target path.
auto path () const noexcept -> const std::filesystem::path &
 Get the path that could not be read.

◆ sourcemeta::core::URITemplateRouter

class sourcemeta::core::URITemplateRouter

A URI Template path router. Keep in mind that the URI Template specification DOES NOT define matching, only expansion. So this is an opinionated non-standard adaptation of URI Template for path routing purposes. The supported operators are:

  • {var} for a single path segment (RFC 6570 Level 1 simple expansion)
  • {+var} for greedy capture to the end of the path, requiring at least one trailing segment (RFC 6570 Level 2 reserved expansion)
  • {/var*} for optional greedy capture to the end of the path, where zero trailing segments are also allowed (RFC 6570 Level 3 path-segment operator with Level 4 explode modifier). Must be the last component of the template. The captured value is empty when no trailing segments are present

Public Types

enum class  NodeType : std::uint8_t {
  Root = 0 , Literal = 1 , Variable = 2 , Expansion = 3 ,
  OptionalExpansion = 4
}
 The type of a node in the router trie. More...
using Identifier = std::uint16_t
 A handler identifier 0 means "no handler".
using Index = std::uint8_t
 The variable index type.
using Callback
 The match callback (index, name, value).
using ArgumentValue = std::variant<std::string_view, std::int64_t, bool>
 The value of a route argument.
using Argument = std::pair<std::string_view, ArgumentValue>
 A named route argument.
using ArgumentCallback
 The argument callback (name, value).

Public Member Functions

 URITemplateRouter ()=default
 Construct an empty router.
 URITemplateRouter (std::string_view base_path, std::string_view base_url={})
 URITemplateRouter (const URITemplateRouter &)=delete
 URITemplateRouter (URITemplateRouter &&)=delete
auto add (const std::string_view uri_template, const std::string_view operation_id, const Identifier identifier, const Identifier context=0, const std::span< const Argument > arguments={}) -> void
auto otherwise (const Identifier context, const std::span< const Argument > arguments={}) -> void
auto match (const std::string_view path, const Callback &callback) const -> std::pair< Identifier, Identifier >
auto describes (const std::string_view path, const std::string_view base_path={}) const noexcept -> bool
auto root () const noexcept -> const Node &
 Access the root node of the trie.
auto arguments (const Identifier identifier, const ArgumentCallback &callback) const -> void
 Access the stored arguments for a given route identifier.
auto arguments () const noexcept -> const std::vector< std::pair< Identifier, std::vector< Argument > > > &
 Access all stored route arguments.
auto base_path () const noexcept -> std::string_view
 Access the base path prefix.
auto base_url () const noexcept -> std::string_view
 Access the base URL associated with the router.
auto size () const noexcept -> std::size_t
 Get the number of registered routes.
auto at (const std::size_t index) const -> Identifier
 Get the identifier of the route at the given positional index.
auto context (const Identifier identifier) const -> Identifier
auto path (const Identifier identifier) const -> std::string
auto operation (const std::string_view operation_id) const -> std::pair< Identifier, Identifier >
auto operation_id (const Identifier identifier) const -> std::string_view

Friends

class URITemplateRouterView

Member Typedef Documentation

◆ ArgumentCallback

Initial value:
std::function<void(std::string_view, const ArgumentValue &)>
std::variant< std::string_view, std::int64_t, bool > ArgumentValue
The value of a route argument.
Definition uritemplate_router.h:60

The argument callback (name, value).

◆ Callback

Initial value:
std::function<void(Index, std::string_view, std::string_view)>
std::uint8_t Index
The variable index type.
Definition uritemplate_router.h:53

The match callback (index, name, value).

Member Enumeration Documentation

◆ NodeType

enum class sourcemeta::core::URITemplateRouter::NodeType : std::uint8_t
strong

The type of a node in the router trie.

Enumerator
Root 

The root of the trie.

Literal 

A fixed literal path segment.

Variable 

A single path segment capture.

Expansion 

A greedy capture requiring at least one trailing segment.

OptionalExpansion 

A greedy capture allowing zero trailing segments.

Constructor & Destructor Documentation

◆ URITemplateRouter()

sourcemeta::core::URITemplateRouter::URITemplateRouter ( std::string_view base_path,
std::string_view base_url = {} )
explicit

Construct a router with a base path prefix. During matching, the base path is stripped from incoming request paths before matching. An optional base URL can be associated with the router as opaque metadata, never used for matching

Member Function Documentation

◆ add()

auto sourcemeta::core::URITemplateRouter::add ( const std::string_view uri_template,
const std::string_view operation_id,
const Identifier identifier,
const Identifier context = 0,
const std::span< const Argument > arguments = {} ) -> void

Add a route to the router. Make sure the string lifetime survives the router. The operation identifier must match the regular expression ^[a-zA-Z][a-zA-Z0-9_-]{0,63}$ and must be unique across all routes registered on this router

◆ context()

auto sourcemeta::core::URITemplateRouter::context ( const Identifier identifier) const -> Identifier
nodiscard

Get the context identifier associated with a registered route identifier

◆ describes()

auto sourcemeta::core::URITemplateRouter::describes ( const std::string_view path,
const std::string_view base_path = {} ) const -> bool
nodiscardnoexcept

Determine whether a path lies within the space described by the explicitly registered routes, as a whole-segment prefix of one or more routes, as an exact route, or as a path captured by a route expansion. The fallback registered through the catch-all is never considered. Like matching, the path is not normalized before evaluation. When a base path is given, it is evaluated as if prepended to the path, avoiding a concatenation at the call site

◆ match()

auto sourcemeta::core::URITemplateRouter::match ( const std::string_view path,
const Callback & callback ) const -> std::pair< Identifier, Identifier >
nodiscard

Match a path against the router. Note the callback might fire for initial matches even though the entire match might still fail

◆ operation()

auto sourcemeta::core::URITemplateRouter::operation ( const std::string_view operation_id) const -> std::pair< Identifier, Identifier >
nodiscard

Resolve an operation identifier to its registered route. Returns (identifier, context) on hit and (0, 0) if no route is registered under the given operation identifier

◆ operation_id()

auto sourcemeta::core::URITemplateRouter::operation_id ( const Identifier identifier) const -> std::string_view
nodiscard

Get the operation identifier associated with a registered route identifier

◆ otherwise()

auto sourcemeta::core::URITemplateRouter::otherwise ( const Identifier context,
const std::span< const Argument > arguments = {} ) -> void

Register a fallback context and arguments to be returned when matching a path that does not correspond to any registered route

◆ path()

auto sourcemeta::core::URITemplateRouter::path ( const Identifier identifier) const -> std::string
nodiscard

Reconstruct and return the URI Template path string originally registered for the given identifier

◆ sourcemeta::core::URITemplateRouterView

class sourcemeta::core::URITemplateRouterView

A read-only view of a serialized URI Template router

Public Member Functions

 URITemplateRouterView (const std::filesystem::path &path)
 Construct a view by loading a serialized router from a file.
 URITemplateRouterView (const std::uint8_t *data, std::size_t size)
 URITemplateRouterView (const URITemplateRouterView &)=delete
 URITemplateRouterView (URITemplateRouterView &&)=delete
auto match (const std::string_view path, const URITemplateRouter::Callback &callback) const -> std::pair< URITemplateRouter::Identifier, URITemplateRouter::Identifier >
auto describes (const std::string_view path, const std::string_view base_path={}) const noexcept -> bool
auto arguments (const URITemplateRouter::Identifier identifier, const URITemplateRouter::ArgumentCallback &callback) const -> void
 Access the stored arguments for a given route identifier.
auto base_path () const noexcept -> std::string_view
 Access the base path prefix.
auto base_url () const noexcept -> std::string_view
 Access the base URL associated with the router.
auto size () const noexcept -> std::size_t
 Get the number of registered routes.
auto operation (const std::string_view operation_id) const -> std::pair< URITemplateRouter::Identifier, URITemplateRouter::Identifier >
auto at (const std::size_t index) const -> URITemplateRouter::Identifier
 Get the identifier of the route at the given positional index.
auto context (const URITemplateRouter::Identifier identifier) const -> URITemplateRouter::Identifier
auto path (const URITemplateRouter::Identifier identifier) const -> std::string
auto operation_id (const URITemplateRouter::Identifier identifier) const -> std::string_view

Static Public Member Functions

static auto save (const URITemplateRouter &router, const std::filesystem::path &path) -> void
 Save a router to a binary file.

Constructor & Destructor Documentation

◆ URITemplateRouterView()

sourcemeta::core::URITemplateRouterView::URITemplateRouterView ( const std::uint8_t * data,
std::size_t size )

Construct a view over an externally-owned buffer. The buffer must outlive the view

Member Function Documentation

◆ context()

auto sourcemeta::core::URITemplateRouterView::context ( const URITemplateRouter::Identifier identifier) const -> URITemplateRouter::Identifier
nodiscard

Get the context identifier associated with a registered route identifier

◆ describes()

auto sourcemeta::core::URITemplateRouterView::describes ( const std::string_view path,
const std::string_view base_path = {} ) const -> bool
nodiscardnoexcept

Determine whether a path lies within the space described by the explicitly registered routes, as a whole-segment prefix of one or more routes, as an exact route, or as a path captured by a route expansion. The fallback registered through the catch-all is never considered. Like matching, the path is not normalized before evaluation. When a base path is given, it is evaluated as if prepended to the path, avoiding a concatenation at the call site

◆ match()

auto sourcemeta::core::URITemplateRouterView::match ( const std::string_view path,
const URITemplateRouter::Callback & callback ) const -> std::pair< URITemplateRouter::Identifier, URITemplateRouter::Identifier >
nodiscard

Match a path against the router. Note the callback might fire for initial matches even though the entire match might still fail

◆ operation()

auto sourcemeta::core::URITemplateRouterView::operation ( const std::string_view operation_id) const -> std::pair< URITemplateRouter::Identifier, URITemplateRouter::Identifier >
nodiscard

Resolve an operation identifier to its registered route. Returns (identifier, context) on hit and (0, 0) if no route is registered under the given operation identifier

◆ operation_id()

auto sourcemeta::core::URITemplateRouterView::operation_id ( const URITemplateRouter::Identifier identifier) const -> std::string_view
nodiscard

Get the operation identifier associated with a registered route identifier

◆ path()

auto sourcemeta::core::URITemplateRouterView::path ( const URITemplateRouter::Identifier identifier) const -> std::string
nodiscard

Reconstruct and return the URI Template path string originally registered for the given identifier

◆ sourcemeta::core::URITemplateTokenLiteral

struct sourcemeta::core::URITemplateTokenLiteral

A literal string segment in a URI Template

Public Attributes

std::string_view value
 The literal string content.

◆ sourcemeta::core::URITemplateVariableSpecification

struct sourcemeta::core::URITemplateVariableSpecification

A variable specification within a URI Template expression

Public Attributes

std::string_view name
 The variable name.
std::uint16_t length {0}
 The maximum prefix length to apply to the value.
bool explode {false}
 Whether the variable is exploded into multiple values.

◆ sourcemeta::core::URITemplateTokenVariable

struct sourcemeta::core::URITemplateTokenVariable

A simple string variable expansion {var} in a URI Template (Level 1)

Public Attributes

std::vector< URITemplateVariableSpecificationvariables
 The variable specifications to expand.

Static Public Attributes

static constexpr char separator = ','
 The character that separates expanded values.
static constexpr bool named = false
 Whether the expansion includes variable names.
static constexpr bool allow_reserved = false
 Whether reserved characters are preserved unencoded.

◆ sourcemeta::core::URITemplateTokenReservedExpansion

struct sourcemeta::core::URITemplateTokenReservedExpansion

A reserved expansion {+var} in a URI Template (Level 2)

Public Attributes

std::vector< URITemplateVariableSpecificationvariables
 The variable specifications to expand.

Static Public Attributes

static constexpr char op = '+'
 The operator character that introduces the expression.
static constexpr char separator = ','
 The character that separates expanded values.
static constexpr bool named = false
 Whether the expansion includes variable names.
static constexpr bool allow_reserved = true
 Whether reserved characters are preserved unencoded.

◆ sourcemeta::core::URITemplateTokenFragmentExpansion

struct sourcemeta::core::URITemplateTokenFragmentExpansion

A fragment expansion {#var} in a URI Template (Level 2)

Public Attributes

std::vector< URITemplateVariableSpecificationvariables
 The variable specifications to expand.

Static Public Attributes

static constexpr char op = '#'
 The operator character that introduces the expression.
static constexpr char separator = ','
 The character that separates expanded values.
static constexpr char prefix = '#'
 The character prepended to the expansion output.
static constexpr bool named = false
 Whether the expansion includes variable names.
static constexpr bool allow_reserved = true
 Whether reserved characters are preserved unencoded.

◆ sourcemeta::core::URITemplateTokenLabelExpansion

struct sourcemeta::core::URITemplateTokenLabelExpansion

A label expansion {.var} in a URI Template (Level 3)

Public Attributes

std::vector< URITemplateVariableSpecificationvariables
 The variable specifications to expand.

Static Public Attributes

static constexpr char op = '.'
 The operator character that introduces the expression.
static constexpr char separator = '.'
 The character that separates expanded values.
static constexpr char prefix = '.'
 The character prepended to the expansion output.
static constexpr bool named = false
 Whether the expansion includes variable names.
static constexpr bool allow_reserved = false
 Whether reserved characters are preserved unencoded.

◆ sourcemeta::core::URITemplateTokenPathExpansion

struct sourcemeta::core::URITemplateTokenPathExpansion

A path expansion {/var} in a URI Template (Level 3)

Public Attributes

std::vector< URITemplateVariableSpecificationvariables
 The variable specifications to expand.

Static Public Attributes

static constexpr char op = '/'
 The operator character that introduces the expression.
static constexpr char separator = '/'
 The character that separates expanded values.
static constexpr char prefix = '/'
 The character prepended to the expansion output.
static constexpr bool named = false
 Whether the expansion includes variable names.
static constexpr bool allow_reserved = false
 Whether reserved characters are preserved unencoded.

◆ sourcemeta::core::URITemplateTokenPathParameterExpansion

struct sourcemeta::core::URITemplateTokenPathParameterExpansion

A path parameter expansion {;var} in a URI Template (Level 3)

Public Attributes

std::vector< URITemplateVariableSpecificationvariables
 The variable specifications to expand.

Static Public Attributes

static constexpr char op = ';'
 The operator character that introduces the expression.
static constexpr char separator = ';'
 The character that separates expanded values.
static constexpr char prefix = ';'
 The character prepended to the expansion output.
static constexpr bool named = true
 Whether the expansion includes variable names.
static constexpr bool allow_reserved = false
 Whether reserved characters are preserved unencoded.

◆ sourcemeta::core::URITemplateTokenQueryExpansion

struct sourcemeta::core::URITemplateTokenQueryExpansion

A query expansion {?var} in a URI Template (Level 3)

Public Attributes

std::vector< URITemplateVariableSpecificationvariables
 The variable specifications to expand.

Static Public Attributes

static constexpr char op = '?'
 The operator character that introduces the expression.
static constexpr char separator = '&'
 The character that separates expanded values.
static constexpr char prefix = '?'
 The character prepended to the expansion output.
static constexpr bool named = true
 Whether the expansion includes variable names.
static constexpr bool allow_reserved = false
 Whether reserved characters are preserved unencoded.
static constexpr char empty_suffix = '='
 The character appended to names with empty values.

◆ sourcemeta::core::URITemplateTokenQueryContinuationExpansion

struct sourcemeta::core::URITemplateTokenQueryContinuationExpansion

A query continuation expansion {&var} in a URI Template (Level 3)

Public Attributes

std::vector< URITemplateVariableSpecificationvariables
 The variable specifications to expand.

Static Public Attributes

static constexpr char op = '&'
 The operator character that introduces the expression.
static constexpr char separator = '&'
 The character that separates expanded values.
static constexpr char prefix = '&'
 The character prepended to the expansion output.
static constexpr bool named = true
 Whether the expansion includes variable names.
static constexpr bool allow_reserved = false
 Whether reserved characters are preserved unencoded.
static constexpr char empty_suffix = '='
 The character appended to names with empty values.

Typedef Documentation

◆ URITemplateParseResult

Initial value:
std::optional<std::pair<URITemplateToken, std::size_t>>

The result of parsing a token: the token and how many characters were consumed

◆ URITemplateToken

◆ URITemplateValue

Initial value:
std::optional<
std::tuple<std::string_view, std::optional<std::string_view>, bool>>

The return type for URI Template variable callbacks (value, key?, has_more)

Enumeration Type Documentation

◆ URITemplateExpansionMode

enum class sourcemeta::core::URITemplateExpansionMode : std::uint8_t
strong

The alphabet that expansion encodes variable values against

Enumerator
URI 

Encode against the URI alphabet as defined by RFC 6570.

IRI 

Encode against the IRI alphabet, passing internationalized characters through unencoded rather than percent encoding them. RFC 6570 Section 1.1 acknowledges that "a URI Template is also an IRI template", but only by expanding to a URI and converting the result per RFC 3987 Section 3.2, a conversion that also decodes percent encoded triplets already present in variable values, whereas this mode never decodes anything. Passed through characters are not validated against the RFC 3987 grammar, which is left to the caller