route

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2021 License: MIT Imports: 10 Imported by: 0

README

Route definition and parser

Flamego's routing syntax is defined using the following BNF:

/* FIXME: `[]:,` are not allowed, since it may affect the binding processing */
<char> ::= [a-z] | [A-Z] | [0-9] | "-" | "." |  "_" |  "~" | "@" | "!" | "&" | "'" | "(" | ")" | "*" | "+" | ";" | "%" | "="
<any> ::= <char> | "[" | "]" | "+" | "," | "?" | "{" | "}" | " " | "\\" | "|"

<ident> ::= <char>+

<bind_parameter_value> ::= <ident> | "/" <any>+ "/"
<bind_parameter> ::= <ident> ":" " "* <bind_parameter_value>
<bind_parameters> ::= <bind_parameter> | <bind_parameters> "," " "* <bind_parameter>

<segment_element> ::= <ident> | "{" <ident> "}" | "{" <bind_parameters> "}"
<segment> ::= "/" "?"? <segment_element>*
<route> ::= <segment>+

The above BNF is generated and validated using https://bnfplayground.pauliankline.com/.

Converting the BNF to Go structs (definition.go) that can be understood by alecthomas/participle is currently a painful manual process. We're looking for a robust and automated code generation solution.

The EBNF generated by the parser is as follows:

Route = Segment+ .
Segment = "/" "?"? SegmentElement* .
SegmentElement = <ident> | ("{" <ident> "}") | ("{" BindParameters "}") .
BindParameters = (BindParameter ("," " "* BindParameter)*)+ .
BindParameter = <ident> ":" " "* BindParameterValue .
BindParameterValue = <ident> | ("/" <regex> "/") .

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BindParameter

type BindParameter struct {
	Ident string             `parser:"@Ident ':' ' '*"`
	Value BindParameterValue `parser:"@@"`
}

BindParameter is a single pair of bind parameter containing identifier and value that are separated by the colon (":").

type BindParameterValue

type BindParameterValue struct {
	Literal *string `parser:"  @Ident"`
	Regex   *string `parser:"| '/' @Regex '/'"`
}

BindParameterValue is a single bind parameter value containing either literal or regex, the latter is surrounded by slashes ("/").

type BindParameters

type BindParameters struct {
	Parameters []BindParameter `parser:"( @@ ( ',' ' '* @@ )* )+"`
}

BindParameters is a set of bind parameters that are separated by commas (",").

type Handler

type Handler func(http.ResponseWriter, *http.Request, Params)

Handler is a function that can be registered to a route for handling HTTP requests.

type Leaf

type Leaf interface {
	// URLPath fills in bind parameters with given values to build the "path"
	// portion of the URL. If `withOptional` is true, the path will include the
	// current leaf when it is optional; otherwise, the current leaf is excluded.
	URLPath(vals map[string]string, withOptional bool) string
	// Route returns the string representation of the original route.
	Route() string
	// Handler the Handler that is associated with the leaf.
	Handler() Handler
	// Static returns true if the leaf and all ancestors are static routes.
	Static() bool
	// contains filtered or unexported methods
}

Leaf is a leaf derived from a segment.

func AddRoute

func AddRoute(t Tree, r *Route, h Handler) (Leaf, error)

AddRoute adds a new route to the tree and associates the given handler.

type MatchStyle

type MatchStyle int8

MatchStyle is the match style of a tree or leaf.

type Params

type Params map[string]string

Params is a set of bind parameters with their values that are extracted from the request path.

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser is a BNF-based route syntax parser using stateful lexer.

func NewParser

func NewParser() (*Parser, error)

NewParser creates and returns a new Parser.

func (*Parser) Parse

func (p *Parser) Parse(s string) (*Route, error)

Parse parses and returns a single route.

type Route

type Route struct {
	Segments []*Segment `parser:"@@+"`
	// contains filtered or unexported fields
}

Route is a single route containing segments that are separated by slashes ("/").

func (*Route) String

func (r *Route) String() string

String returns the string representation of the Route, which basically traverses the Route AST to reconstruct the original route string.

type Segment

type Segment struct {
	Pos      lexer.Position
	Slash    string           `parser:"'/'"`
	Optional bool             `parser:"@'?'?"`
	Elements []SegmentElement `parser:"@@*"`
	// contains filtered or unexported fields
}

Segment is a single segment containing multiple elements.

func (*Segment) String

func (s *Segment) String() string

String returns the string representation of the Segment, which basically traverses the Segment AST to reconstruct the original string.

type SegmentElement

type SegmentElement struct {
	Pos            lexer.Position
	EndPos         lexer.Position
	Ident          *string         `parser:"  @Ident"`
	BindIdent      *string         `parser:"| '{' @Ident '}'"`
	BindParameters *BindParameters `parser:"| '{' @@ '}'"`
}

SegmentElement is a single segment element containing either identifier, bind identifier or a list of bind parameters. Bind identifier and the list of bind parameters are surrounded by brackets ("{}").

type Tree

type Tree interface {
	// Match matches a leaf for the given request path, values of bind parameters
	// are stored in the `Params`. The `Params` may contain extra values that do not
	// belong to the final leaf due to backtrace.
	Match(path string) (Leaf, Params, bool)
	// contains filtered or unexported methods
}

Tree is a tree derived from a segment.

func NewTree

func NewTree() Tree

NewTree creates and returns a root tree.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL