Documentation
¶
Overview ¶
Package pathspec parses and renders forge route path patterns.
It is the single source of truth for path syntax. Adapters and the OpenAPI generator consume a parsed Pattern instead of re-deriving "what is a parameter" from a raw string, which is what four separate implementations used to do, disagreeing with each other about wildcards.
This package is a leaf. It must not import anything else in this repository.
Index ¶
Constants ¶
const DefaultWildcardName = "filepath"
DefaultWildcardName is the name given to an unnamed wildcard.
The value matters beyond aesthetics. internal/router/bunrouter.go maps a param literally named "filepath" onto the "*" lookup key, and extras/httprouter.go mounts sub-handlers on "*filepath". Changing it breaks wildcard parameter lookup in both.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Constraint ¶
type Constraint uint8
Constraint restricts which segment values a parameter matches. The type is declared here so Segment can name it; the vocabulary, ordering and match predicates live in constraint.go.
const ( // ConstraintNone matches any non-empty segment. ConstraintNone Constraint = iota ConstraintAlnum ConstraintAlpha ConstraintInt ConstraintUint ConstraintUUID // ConstraintEnum matches a fixed list carried on Segment.Enum. ConstraintEnum )
The Constraint vocabulary is closed by design: there is no regex form and no registration hook. A constraint runs on the matcher's hot path, and the OpenAPI generator has to infer a schema from it, neither of which survives arbitrary user predicates.
A constraint is not validation. It affects matching, so "/users/{id:int}" failing to match falls through to "/users/me". Validation affects responding, and produces a 400 on a route that already matched.
The type itself is declared in pathspec.go, because Segment names it.
func (Constraint) Match ¶
func (c Constraint) Match(value string, enum []string) bool
Match reports whether value satisfies the constraint. enum is consulted only for ConstraintEnum and is otherwise ignored.
func (Constraint) Rank ¶
func (c Constraint) Rank() int
Rank orders constraints from most specific to least.
The matcher tries parameter edges in descending rank, so "/users/{id:uuid}" is attempted before "/users/{name:alpha}". Two constraints of equal rank on the same segment are ambiguous, and the matcher reports that as a conflict at registration.
func (Constraint) String ¶
func (c Constraint) String() string
String returns the name used in path syntax, or "" for ConstraintNone.
type Pattern ¶
type Pattern struct {
// Raw is the path exactly as registered, kept for diagnostics. It is not
// normalized, so it may differ from Render output.
Raw string
// Segments is empty for the root path "/".
Segments []Segment
// Params holds parameter and wildcard names in the order they appear.
// The matcher relies on this order to bind captured values to names.
Params []string
}
Pattern is a parsed route path.
func Parse ¶
Parse converts a raw forge path into a Pattern.
Trailing slashes are normalized away on non-root paths, so "/users/" and "/users" parse identically. This matches what the router already does to incoming request paths, and makes a route registered with a trailing slash reachable instead of dead.
type Segment ¶
type Segment struct {
Kind Kind
// Literal is set for KindStatic only.
Literal string
// Name is set for KindParam and KindWildcard. An unnamed wildcard is
// given DefaultWildcardName at parse time, so this is never empty for
// those kinds.
Name string
// Constraint is set for KindParam only. ConstraintNone means the
// parameter matches any non-empty segment.
Constraint Constraint
// Enum holds the permitted values for ConstraintEnum, and is nil
// otherwise.
Enum []string
}
Segment is one "/"-delimited piece of a pattern.
type Syntax ¶
type Syntax uint8
Syntax selects the dialect Render emits.
const ( // SyntaxColon is the bunrouter and httprouter dialect: "/users/:id", with // a NAMED terminal wildcard, "/files/*filepath". bunrouter panics on an // unnamed wildcard, so the name is not optional here. SyntaxColon Syntax = iota // SyntaxBrace is the chi dialect: "/users/{id}", with a bare terminal // wildcard, "/files/*". SyntaxBrace // SyntaxOpenAPI is the OpenAPI path template: "/users/{id}". The wildcard // is rendered as a named parameter so the document can carry a parameter // object for it, which is what the old generator failed to do. SyntaxOpenAPI )