Sign in

    moonuritemplate

    RFC 6570 Level 4 URI Template parser and expansion library

    uri-template
    rfc6570
    url
    api
    mcp
    Download zip
    Author
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    19 days ago
    Downloads
    18

    #MoonURITemplate

    Pure MoonBit RFC 6570 Level 4 URI Template parser and expander for wasm, wasm-gc, JavaScript, and native targets.

    Compile a template once, then expand it with typed scalar, list, or ordered associative values. The library supports all eight defined operators, prefix and explode modifiers, UTF-8 percent encoding, sparse composites, bounded processing, source-aware analysis, binding preflight, and a conservative JSON bridge.

    Reusable catalogs, partial bindings, batch rendering, source-to-output spans, variable profiles, and opt-in template policies support SDK generators and hypermedia services. Every API returns typed errors; network destination validation remains the caller's responsibility.

    Template::measure computes the exact expanded length without assembling the URI, and the positive conformance fixtures check that measurement agrees with rendering. Template::diff_contract reports selected static changes for API reviews; it does not prove URI equivalence.

    Run from a source checkout:

    moon check --target all --deny-warn moon build --target all --deny-warn moon test --target all --deny-warn moon run examples/api --target wasm-gc

    moon run examples/mcp --target wasm-gc and moon run examples/hypermedia --target wasm-gc demonstrate two further uses. The main README documents the API, security boundaries, and conformance scope.

    The runtime implementation is original. Apache-2.0 test fixtures from uri-templates/uritemplate-test are pinned and attributed in THIRD_PARTY.md. The project itself is Apache-2.0 licensed.

    #十月第二轮:目录迁移与请求审查

    TemplateCatalog::diff_catalog(next) 列出新增、删除和变更端点,连字面量路径变化也保留;每项变更附原有变量/运算符契约报告。inspect_requests 检查混合请求的全部诊断,限制请求、绑定及结果数量,返回请求索引和变量名,不包含绑定值。缺失变量属于提示,普通 RFC 展开允许省略。

    expand_requests 现在先调用精确计量,再构造输出,确保总预算超限在生成 URI 数组前被拒绝。计量仍有输入编码的临时分配,展开需额外遍历一次。运行 moon run examples/maintenance --target wasm-gc。详见 本轮审查与复杂度 和 十月申报资料稿。

    BatchError

    pub(all) enum BatchError {
    TooManyInputs
    TotalOutputTooLong
    InvalidItem(Int, ExpandError)
    }

    A bounded batch expansion failed before returning a partial result.

    BatchError::code

    fn BatchError::code(self : BatchError) -> String

    BatchError::index

    fn BatchError::index(self : BatchError) -> Int?

    Return the zero-based row number for a per-row expansion failure.

    BindingIssue

    pub(all) enum BindingIssue {
    Missing(String)
    Unused(String)
    Duplicate(String)
    CompositePrefix(String)
    }

    A preflight observation about the supplied bindings. Missing variables are informational: RFC 6570 deliberately permits undefined variables.

    BindingIssue::code

    fn BindingIssue::code(self : BindingIssue) -> String

    BindingIssue::name

    fn BindingIssue::name(self : BindingIssue) -> String

    BindingReport

    pub struct BindingReport {
    issues : Array[BindingIssue]
    }

    BindingReport::is_clean

    fn BindingReport::is_clean(self : BindingReport) -> Bool

    BindingReport::issues

    BindingReport::missing_count

    fn BindingReport::missing_count(self : BindingReport) -> Int

    BoundTemplate

    pub struct BoundTemplate {
    template : Template
    fixed : Array[(String, Value)]
    fixed_names : Map[String, Bool]
    }

    A template with some values fixed in advance. Useful for per-client base paths or per-tenant URI prefixes that recur across many requests.

    BoundTemplate::expand

    fn BoundTemplate::expand(self : BoundTemplate, dynamic : Array[(String, Value)], max_output? : Int, max_bindings? : Int, max_value_length? : Int, max_items? : Int) -> Result[String, ExpandError]

    Supply request-local bindings to a partially bound template. Fixed values are never overridden. The usual expansion budgets apply to the combined set.

    BoundTemplate::fixed_names

    fn BoundTemplate::fixed_names(self : BoundTemplate) -> Array[String]

    BoundTemplate::measure

    fn BoundTemplate::measure(self : BoundTemplate, dynamic : Array[(String, Value)], max_output? : Int, max_bindings? : Int, max_value_length? : Int, max_items? : Int) -> Result[Int, ExpandError]

    Measure a partially bound expansion before constructing its URI text.

    CatalogAudit

    pub struct CatalogAudit {
    entries : Array[CatalogEntryAudit]
    total_findings : Int
    }

    Policy findings for every catalog entry, preserving catalog order.

    CatalogAudit::entries

    CatalogAudit::is_clean

    fn CatalogAudit::is_clean(self : CatalogAudit) -> Bool

    CatalogAudit::total_findings

    fn CatalogAudit::total_findings(self : CatalogAudit) -> Int

    CatalogBatchError

    pub(all) enum CatalogBatchError {
    TooManyRequests
    TotalOutputTooLong
    InvalidRequest(Int, CatalogExpandError)
    }

    CatalogBatchError::code

    fn CatalogBatchError::code(self : CatalogBatchError) -> String

    CatalogBatchError::index

    fn CatalogBatchError::index(self : CatalogBatchError) -> Int?

    Zero-based request index when a catalog batch failed on one row.

    CatalogDiff

    pub struct CatalogDiff {
    added : Array[String]
    removed : Array[String]
    changed : Array[CatalogTemplateChange]
    }

    CatalogDiff::added

    fn CatalogDiff::added(self : CatalogDiff) -> Array[String]

    CatalogDiff::changed

    CatalogDiff::is_empty

    fn CatalogDiff::is_empty(self : CatalogDiff) -> Bool

    CatalogDiff::removed

    fn CatalogDiff::removed(self : CatalogDiff) -> Array[String]

    CatalogEntryAudit

    pub struct CatalogEntryAudit {
    name : String
    variable_count : Int
    expression_count : Int
    max_level : Int
    findings : Array[PolicyFinding]
    }

    Static analysis of one named template in a catalog.

    CatalogEntryAudit::expression_count

    fn CatalogEntryAudit::expression_count(self : CatalogEntryAudit) -> Int

    CatalogEntryAudit::findings

    CatalogEntryAudit::max_level

    fn CatalogEntryAudit::max_level(self : CatalogEntryAudit) -> Int

    CatalogEntryAudit::name

    fn CatalogEntryAudit::name(self : CatalogEntryAudit) -> String

    CatalogEntryAudit::variable_count

    fn CatalogEntryAudit::variable_count(self : CatalogEntryAudit) -> Int

    CatalogError

    pub(all) enum CatalogError {
    TooManyTemplates
    EmptyName
    DuplicateName(String)
    InvalidTemplate(String, ParseError)
    }

    Catalog compilation failure. Template syntax errors retain the entry name.

    CatalogError::code

    fn CatalogError::code(self : CatalogError) -> String

    CatalogError::name

    fn CatalogError::name(self : CatalogError) -> String?

    The offending catalog key when an error belongs to a specific entry.

    CatalogError::parse_error

    fn CatalogError::parse_error(self : CatalogError) -> ParseError?

    The underlying RFC 6570 syntax error, including its source offset.

    CatalogExpandError

    pub(all) enum CatalogExpandError {
    UnknownTemplate(String)
    InvalidBinding(String, ExpandError)
    }

    Expansion failure retains the catalog entry name when one was selected.

    CatalogExpandError::code

    fn CatalogExpandError::code(self : CatalogExpandError) -> String

    CatalogExpandError::expand_error

    CatalogExpandError::name

    fn CatalogExpandError::name(self : CatalogExpandError) -> String

    CatalogJsonError

    pub(all) enum CatalogJsonError {
    RootMustBeObject
    TemplateMustBeString(String)
    Compilation(CatalogError)
    }

    A JSON catalog manifest must map each endpoint name to one URI Template string. Key order is sorted for reproducible TemplateCatalog::names.

    CatalogJsonError::code

    fn CatalogJsonError::code(self : CatalogJsonError) -> String

    CatalogJsonError::path

    fn CatalogJsonError::path(self : CatalogJsonError) -> String

    CatalogJsonRenderError

    pub(all) enum CatalogJsonRenderError {
    BindingConversion(JsonBridgeError)
    CatalogExpansion(CatalogExpandError)
    }

    CatalogJsonRenderError::code

    CatalogRequest

    pub(all) struct CatalogRequest {
    name : String
    bindings : Array[(String, Value)]
    }

    One named link request in a mixed catalog batch.

    CatalogTemplateChange

    pub struct CatalogTemplateChange {
    name : String
    contract : TemplateDiff
    }

    A changed endpoint retains its contract comparison, including literal-only changes that a variable/operator comparison alone would not detect.

    CatalogTemplateChange::contract

    CatalogTemplateChange::name

    fn CatalogTemplateChange::name(self : CatalogTemplateChange) -> String

    ExpandError

    pub(all) enum ExpandError {
    DuplicateVariable(String)
    MissingVariable(String)
    UnusedVariable(String)
    InvalidValue(String)
    TooManyBindings
    ValueTooLong(String)
    TooManyItems(String)
    InvalidLimit(String)
    OutputTooLong
    }

    An expansion failure. The requested output limit is enforced before return.

    ExpandError::code

    fn ExpandError::code(self : ExpandError) -> String

    Stable machine-readable code for an expansion error.

    ExpandError::message

    fn ExpandError::message(self : ExpandError) -> String

    Human-readable explanation without embedding variable values.

    ExpressionInfo

    pub(all) struct ExpressionInfo {
    start : Int
    end : Int
    operator : String
    level : Int
    variable_count : Int
    permits_reserved : Bool
    }

    One brace expression in the source template. Offsets are UTF-16 code units.

    JsonBridgeError

    pub(all) enum JsonBridgeError {
    RootMustBeObject
    UnsupportedValue(String)
    }

    A JSON tree cannot be converted to URI Template values under this adapter. Only strings, null, arrays of strings/null, and objects of strings/null are accepted. Numeric and boolean coercion is deliberately left to callers.

    JsonBridgeError::code

    fn JsonBridgeError::code(self : JsonBridgeError) -> String

    JsonBridgeError::path

    fn JsonBridgeError::path(self : JsonBridgeError) -> String

    JsonRenderError

    pub(all) enum JsonRenderError {
    Conversion(JsonBridgeError)
    Expansion(ExpandError)
    }

    The JSON adapter distinguishes conversion failures from URI expansion failures. A JSON number is never silently coerced to text.

    JsonRenderError::code

    fn JsonRenderError::code(self : JsonRenderError) -> String

    JsonTemplateError

    pub(all) enum JsonTemplateError {
    TemplateParse(ParseError)
    TemplateRender(JsonRenderError)
    }

    A single-call JSON expansion failed during syntax compilation or render.

    JsonTemplateError::code

    fn JsonTemplateError::code(self : JsonTemplateError) -> String

    Operator

    pub enum Operator {
    Simple
    Reserved
    Fragment
    Label
    Path
    PathParameter
    Query
    QueryContinuation
    }

    OutputSpan

    pub(all) struct OutputSpan {
    source_start : Int
    source_end : Int
    output_start : Int
    output_end : Int
    is_expression : Bool
    }

    A source segment and the exact UTF-16 range it contributed to the output. Empty expressions still have a zero-width output range.

    ParseError

    pub(all) enum ParseError {
    InputTooLong
    InvalidUnicode(Int)
    InvalidLiteral(Int)
    UnclosedExpression(Int)
    NestedExpression(Int)
    EmptyExpression(Int)
    InvalidOperator(Int)
    InvalidVariable(Int)
    InvalidModifier(Int)
    TooManyExpressions
    TooManyVariables
    }

    A parse failure with a UTF-16 code-unit offset into the template.

    ParseError::code

    fn ParseError::code(self : ParseError) -> String

    Stable machine-readable code for a parse error.

    ParseError::message

    fn ParseError::message(self : ParseError) -> String

    Human-readable explanation without embedding the source text.

    ParseError::offset

    fn ParseError::offset(self : ParseError) -> Int?

    Return the UTF-16 code-unit offset of a parse error, if applicable.

    PolicyError

    pub(all) enum PolicyError {
    InvalidFeatureLevel
    InvalidReferenceLimit
    }

    PolicyError::code

    fn PolicyError::code(self : PolicyError) -> String

    PolicyFinding

    pub(all) struct PolicyFinding {
    kind : PolicyFindingKind
    start : Int
    end : Int
    }

    UTF-16 source range of a static policy finding.

    PolicyFindingKind

    pub(all) enum PolicyFindingKind {
    ReservedExpansion
    FragmentExpansion
    FeatureLevelExceeded(Int)
    ReferenceLimitExceeded
    RepeatedVariable(String)
    }

    PolicyFindingKind::code

    fn PolicyFindingKind::code(self : PolicyFindingKind) -> String

    RenderedUri

    pub struct RenderedUri {
    text : String
    spans : Array[OutputSpan]
    }

    Expanded URI text with a source-to-output map for diagnostics and tooling.

    RenderedUri::spans

    fn RenderedUri::spans(self : RenderedUri) -> Array[OutputSpan]

    RenderedUri::text

    fn RenderedUri::text(self : RenderedUri) -> String

    RequestAudit

    pub struct RequestAudit {
    index : Int
    name : String
    unknown_template : Bool
    issues : Array[BindingIssue]
    }

    No values or expanded URIs are included in a request audit.

    RequestAudit::index

    fn RequestAudit::index(self : RequestAudit) -> Int

    RequestAudit::issues

    RequestAudit::name

    fn RequestAudit::name(self : RequestAudit) -> String

    RequestAudit::unknown_template

    fn RequestAudit::unknown_template(self : RequestAudit) -> Bool

    RequestAuditError

    pub(all) enum RequestAuditError {
    RequestLimit
    BindingLimit
    FindingLimit
    }

    Segment

    pub enum Segment {
    Literal(String)
    Expression(Operator, Array[VarSpec], Int, Int)
    }

    Template

    pub struct Template {
    source : String
    segments : Array[Segment]
    variables : Array[String]
    }

    A compiled template. Reuse it for many value sets.

    Template::analyze

    fn Template::analyze(self : Template) -> TemplateAnalysis

    Template::bind

    fn Template::bind(self : Template, bindings : Array[(String, Value)], max_bindings? : Int, max_value_length? : Int, max_items? : Int) -> Result[BoundTemplate, ExpandError]

    Capture validated bindings without retaining caller-owned mutable arrays. A bound name cannot be supplied again at expansion time.

    Template::check_policy

    fn Template::check_policy(self : Template, policy : TemplatePolicy) -> Result[Array[PolicyFinding], PolicyError]

    Check a compiled template without bindings. All findings are returned in source order; a single expression may produce several distinct findings.

    Template::composite_capable_variables

    fn Template::composite_capable_variables(self : Template) -> Array[String]

    Names that can accept a list or association value in every occurrence. This does not imply a composite is required; scalar values also work.

    Template::diff_contract

    fn Template::diff_contract(self : Template, next : Template) -> TemplateDiff

    Compare variable and operator requirements before replacing a deployed template. Added variables matter to expand_required; newly scalar-only variables can reject previously valid composite bindings.

    Template::expand

    fn Template::expand(self : Template, bindings : Array[(String, Value)], max_output? : Int, max_bindings? : Int, max_value_length? : Int, max_items? : Int) -> Result[String, ExpandError]

    Expand a precompiled template. The binding array rejects duplicate names so one name cannot silently change value during an expansion.

    Template::expand_detailed

    fn Template::expand_detailed(self : Template, bindings : Array[(String, Value)], max_output? : Int, max_bindings? : Int, max_value_length? : Int, max_items? : Int) -> Result[RenderedUri, ExpandError]

    Expand while recording which source segment produced each output range. This has O(number of segments) additional memory compared with expand.

    Template::expand_json

    fn Template::expand_json(self : Template, values : Json, max_output? : Int, max_bindings? : Int, max_value_length? : Int, max_items? : Int) -> Result[String, JsonRenderError]

    Convert a JSON object to ordered bindings and expand a compiled template. This is suitable for clients that already have a decoded JSON tree. It does not parse JSON text or validate a resulting network destination.

    Template::expand_many

    fn Template::expand_many(self : Template, inputs : Array[Array[(String, Value)]], max_inputs? : Int, max_total_output? : Int, max_each_output? : Int) -> Result[Array[String], BatchError]

    Expand one compiled template for many independent value sets. The call is fail-fast and atomic: no partial result escapes on error. An aggregate output limit prevents an unbounded result even when each row is small.

    Template::expand_required

    fn Template::expand_required(self : Template, bindings : Array[(String, Value)], reject_unused? : Bool, max_output? : Int, max_bindings? : Int, max_value_length? : Int, max_items? : Int) -> Result[String, ExpandError]

    Expand only when every referenced variable is bound. This opt-in policy is useful for fixed SDK operations; ordinary RFC 6570 expansion allows missing variables and remains available through Template::expand.

    Template::inspect_bindings

    fn Template::inspect_bindings(self : Template, bindings : Array[(String, Value)]) -> BindingReport

    Inspect variable presence, duplicate bindings, and prefix/type conflicts without expanding or exposing any bound value in the report.

    Template::measure

    fn Template::measure(self : Template, bindings : Array[(String, Value)], max_output? : Int, max_bindings? : Int, max_value_length? : Int, max_items? : Int) -> Result[Int, ExpandError]

    Return the exact UTF-16 length of the expanded URI without constructing its output string. This performs the same binding checks as expand.

    Template::reference_count

    fn Template::reference_count(self : Template, name : String) -> Int

    Count how often a variable occurs in this template.

    Template::source

    fn Template::source(self : Template) -> String

    Return the original template text.

    Template::variable_profiles

    fn Template::variable_profiles(self : Template) -> Array[VariableProfile]

    Derive an SDK-oriented variable schema from a compiled template. Profiles retain first-appearance order. A prefix modifier on any occurrence forces a scalar binding for that variable under this implementation.

    Template::variables

    fn Template::variables(self : Template) -> Array[String]

    Return unique variable names in first-appearance order.

    TemplateAnalysis

    pub struct TemplateAnalysis {
    expressions : Array[ExpressionInfo]
    uses : Array[VariableUse]
    max_level : Int
    has_reserved_expansion : Bool
    }

    Static summary of a compiled template. It does not inspect bound values.

    TemplateAnalysis::expressions

    TemplateAnalysis::has_reserved_expansion

    fn TemplateAnalysis::has_reserved_expansion(self : TemplateAnalysis) -> Bool

    True if '+' or '#' allows reserved characters from a value into the URI.

    TemplateAnalysis::max_level

    fn TemplateAnalysis::max_level(self : TemplateAnalysis) -> Int

    Highest RFC 6570 feature level required by the template (1–4).

    TemplateAnalysis::uses

    TemplateCatalog

    pub struct TemplateCatalog {
    names : Array[String]
    templates : Map[String, Template]
    }

    A named set of precompiled templates for API endpoints or link relations.

    TemplateCatalog::audit

    Audit every named template for SDK or server startup checks. The audit never reads values or produces URI text. An invalid policy is rejected even when the catalog contains no templates.

    TemplateCatalog::contains

    fn TemplateCatalog::contains(self : TemplateCatalog, name : String) -> Bool

    TemplateCatalog::diff_catalog

    fn TemplateCatalog::diff_catalog(self : TemplateCatalog, next : TemplateCatalog) -> CatalogDiff

    Compare two endpoint catalogs before deploying a new API/link definition. Additions and changes follow the next catalog order; removals follow the old. A report is structural evidence, not a proof of backward compatibility.

    TemplateCatalog::expand

    fn TemplateCatalog::expand(self : TemplateCatalog, name : String, bindings : Array[(String, Value)], max_output? : Int) -> Result[String, CatalogExpandError]

    Expand one named template with a supplied value set. The catalog itself is immutable after compilation and can be reused across requests.

    TemplateCatalog::expand_json

    fn TemplateCatalog::expand_json(self : TemplateCatalog, name : String, values : Json, max_output? : Int) -> Result[String, CatalogJsonRenderError]

    Render a named URI using a conservative JSON binding object. This method shares the same string/null/array/object conversion as expand_json.

    TemplateCatalog::expand_requests

    fn TemplateCatalog::expand_requests(self : TemplateCatalog, requests : Array[CatalogRequest], max_requests? : Int, max_total_output? : Int, max_each_output? : Int) -> Result[Array[String], CatalogBatchError]

    Expand a mixed set of catalog entries in request order. A failure returns the failing request index; no partial collection is returned to the caller.

    TemplateCatalog::get

    fn TemplateCatalog::get(self : TemplateCatalog, name : String) -> Template?

    Look up the original compiled template for analysis or specialized limits.

    TemplateCatalog::inspect_requests

    fn TemplateCatalog::inspect_requests(self : TemplateCatalog, requests : Array[CatalogRequest], max_requests? : Int, max_bindings? : Int, max_findings? : Int) -> Result[Array[RequestAudit], RequestAuditError]

    Inspect every mixed request without stopping at the first unknown endpoint or binding issue. Missing variables are informational under RFC 6570. Limits apply to the complete input and result; failures return no partial audit.

    TemplateCatalog::measure

    fn TemplateCatalog::measure(self : TemplateCatalog, name : String, bindings : Array[(String, Value)], max_output? : Int) -> Result[Int, CatalogExpandError]

    Measure the exact output size of a named template without rendering it.

    TemplateCatalog::measure_requests

    fn TemplateCatalog::measure_requests(self : TemplateCatalog, requests : Array[CatalogRequest], max_requests? : Int, max_total_output? : Int, max_each_output? : Int) -> Result[Int, CatalogBatchError]

    Measure a mixed catalog batch without constructing the URI outputs. The result is the exact total output length under the same per-request and aggregate limits used by expand_requests.

    TemplateCatalog::names

    fn TemplateCatalog::names(self : TemplateCatalog) -> Array[String]

    TemplateCatalog::templates_using

    fn TemplateCatalog::templates_using(self : TemplateCatalog, variable : String) -> Array[String]

    List templates that reference one variable, in catalog order. API schema tooling can use this reverse lookup to identify which links may need new bindings when a field is renamed or removed.

    TemplateDiff

    pub struct TemplateDiff {
    added_variables : Array[String]
    removed_variables : Array[String]
    became_scalar_only : Array[String]
    new_repeated_variables : Array[String]
    old_level : Int
    new_level : Int
    reserved_added : Bool
    fragment_added : Bool
    }

    Structural changes between two compiled templates. This is a source-level report for API reviews, not a proof that two templates render equivalent URIs or that a deployment is backward compatible.

    TemplateDiff::added_variables

    fn TemplateDiff::added_variables(self : TemplateDiff) -> Array[String]

    TemplateDiff::became_scalar_only

    fn TemplateDiff::became_scalar_only(self : TemplateDiff) -> Array[String]

    TemplateDiff::fragment_added

    fn TemplateDiff::fragment_added(self : TemplateDiff) -> Bool

    TemplateDiff::has_flagged_changes

    fn TemplateDiff::has_flagged_changes(self : TemplateDiff) -> Bool

    TemplateDiff::new_level

    fn TemplateDiff::new_level(self : TemplateDiff) -> Int

    TemplateDiff::new_repeated_variables

    fn TemplateDiff::new_repeated_variables(self : TemplateDiff) -> Array[String]

    TemplateDiff::old_level

    fn TemplateDiff::old_level(self : TemplateDiff) -> Int

    TemplateDiff::removed_variables

    fn TemplateDiff::removed_variables(self : TemplateDiff) -> Array[String]

    TemplateDiff::reserved_added

    fn TemplateDiff::reserved_added(self : TemplateDiff) -> Bool

    TemplateError

    pub(all) enum TemplateError {
    Parse(ParseError)
    Expand(ExpandError)
    }

    A single-use expansion failed while parsing or while applying values.

    TemplatePolicy

    pub(all) struct TemplatePolicy {
    allow_reserved : Bool
    allow_fragment : Bool
    max_level : Int
    max_references : Int
    forbid_repeated_variables : Bool
    }

    Static restrictions for an application that consumes URI templates. This checks template structure only; it cannot validate a final URI host.

    Value

    pub(all) enum Value {
    Scalar(String)
    List(Array[String])
    Assoc(Array[(String, String)])
    SparseList(Array[String?])
    SparseAssoc(Array[(String, String?)])
    }

    A value supplied to an RFC 6570 variable. Associative entries retain order.

    VarSpec

    pub struct VarSpec {
    name : String
    prefix : Int?
    explode : Bool
    start : Int
    end : Int
    }

    VariableProfile

    pub(all) struct VariableProfile {
    name : String
    occurrences : Int
    first_start : Int
    last_end : Int
    scalar_only : Bool
    uses_explode : Bool
    uses_reserved : Bool
    uses_query : Bool
    maximum_prefix : Int?
    }

    Aggregate requirements for one variable across all uses in a template. RFC 6570 variables remain optional unless the caller uses expand_required.

    VariableUse

    pub(all) struct VariableUse {
    name : String
    start : Int
    end : Int
    expression_index : Int
    operator : String
    prefix : Int?
    explode : Bool
    }

    One occurrence of a variable specification, including its modifier.

    bindings_from_json

    fn bindings_from_json(input : Json) -> Result[Array[(String, Value)], JsonBridgeError]

    Convert a JSON object to ordered bindings. Object keys are sorted so associative expansion is deterministic across MoonBit backends.

    compile_catalog

    fn compile_catalog(entries : Array[(String, String)], max_templates? : Int, max_template_length? : Int) -> Result[TemplateCatalog, CatalogError]

    Compile every catalog entry once. Names remain in caller order. Duplicate names are rejected so a later template cannot silently replace an earlier endpoint or link relation.

    compile_catalog_json

    fn compile_catalog_json(input : Json, max_templates? : Int, max_template_length? : Int) -> Result[TemplateCatalog, CatalogJsonError]

    Build a named catalog from an already-decoded JSON object. JSON parsers may have discarded duplicate object keys before this method is called; callers that reject duplicates must enforce that while reading JSON text.

    expand

    fn expand(source : String, bindings : Array[(String, Value)], max_output? : Int) -> Result[String, TemplateError]

    Parse and expand a template once. Use parse and Template::expand when the same template is expanded repeatedly.

    expand_json

    fn expand_json(source : String, values : Json, max_output? : Int) -> Result[String, JsonTemplateError]

    Parse a template and expand it from a JSON object in a single call.

    parse

    fn parse(input : String, max_length? : Int, max_expressions? : Int, max_variables? : Int, strict_literals? : Bool) -> Result[Template, ParseError]

    Compile an RFC 6570 Level 4 URI Template. Limits and error offsets are measured in UTF-16 code units.

    permissive_policy

    fn permissive_policy() -> TemplatePolicy

    Policy matching the syntactic capabilities of this library.

    value_from_json

    fn value_from_json(input : Json, path? : String) -> Result[Value?, JsonBridgeError]

    Convert one JSON value. JSON null is an undefined variable or member.

    version

    fn version() -> String

    Semantic version of this source checkout.