Url.ParserParse URLs.
type url = tval string : (string -> 'a, 'a) tstring will parse a segment of the path as string.
The segment will be percent-decoded automatically.
input | parse result |
|---|---|
|
|
|
|
|
|
|
|
|
|
val int : (int -> 'a, 'a) tint will parse a segment of the path as integer.
input | parse result |
|---|---|
|
|
|
|
|
|
|
|
val s : string -> ('a, 'a) ts str will parse a segment of the path if it matches the given string str.
The segment will be percent-decoded automatically.
For example, the parser s "blog" </> int will behave as follows:
input | parse result |
|---|---|
|
|
|
|
val custom : (string -> 'a option) -> ('a -> 'b, 'b) tcustom f will parse a segment of the path by applying the function f to the raw segment.
Example:
let positive_int: (int -> 'a, 'a) Parser.t =
Parser.custom @@
fun s ->
match int_of_string_opt s with
| Some i when i > 0 ->
Some i
| _ ->
NoneThe example parser produces the following results:
input | parse result |
|---|---|
|
|
|
|
|
|
p1 </> p2 combines the segment parsers p1 and p2 and returns a new parser which will parse two path segments.
Example:
let blog: (int -> 'a, 'a) Parser.t =
let open Parser in
s "blog" </> intThe example parser will behave like this:
input | parse result |
|---|---|
|
|
|
|
|
|
map f parser transforms the parser via f.
f can be a function taking as many values as the parser produces (see example 1) or, in case the parser produces no values at all, f can be a variant constructor or a variant tag (see example 2).
Examples 1:
type date = {year: int; month: int; day: int}
let date_parser: (date -> 'a, 'a) Parser.t =
let open Parser in
map
(fun year month day -> {year; month; day})
(int </> int </> int)The parser in example 1 will produce the following results:
input | parse result |
|---|---|
|
|
|
|
Example 2:
let language = Haskell | Ocaml | Rust
let language_parser: (language -> 'a, 'a) Parser.t =
let open Parser in
one_of
[
map Haskell (s "hs");
map OCaml (s "ml");
map Rust (s "rs");
]The parser in example 2 will produce the following results:
input | parse result |
|---|---|
|
|
|
|
|
|
|
|
one_of parsers runs the given parsers in the order they are provided. The result is the result of the first succeeding parser or None if all of them fail.
Example:
type route =
| Index
| Article of int
| Comment of {id: int; article_id: int}
let route_parser: (route -> 'a, 'a) Parser.t =
let open Parser in
one_of
[
map Index top;
map (fun id -> Article id) (s "blog" </> int);
map
(fun article_id id -> Comment {id; article_id})
(s "blog" </> int </> s "comment" </> int)
]The example parser will behave like this:
input | parse result |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
val top : ('a, 'a) ttop creates a parser that does not consume any path segment.
It can be used together with one_of in order to use a common prefix for multiple parsers:
type route = Overview | Post of int
let blog: (route -> 'a, 'a) Parser.t =
let open Parser in
s "blog" </>
one_of
[
map Overview top;
map (fun id -> Post id) (s "post" </> int);
]The example parser produces the following results:
input | parse result |
|---|---|
|
|
|
|
|
|
|
|
module Query : sig ... endParse query parameters
url_parser </?> query_parser combines a url_parser with a query_parser.
For example, the parser s "blog" <?> Query.string "search" produces the following results:
input | parse result |
|---|---|
|
|
|
|
|
|
|
|
query query_parser converts query_parser to a URL parser.
This is useful if a URL has an empty path and we want to parse query parameters.
Example:
(* The following parsers are equivalent *)
let search_term_parser1: (string -> 'a, 'a) Parser.t =
let open Parser in
query (Query.string "search")
let search_term_parser2: (string -> 'a, 'a) Parser.t =
let open Parser in
top <?> Query.string "search"The example parsers behave as follows:
input | parse result |
|---|---|
|
|
|
|
|
|
|
|
val fragment : (string option -> 'a) -> ('a -> 'b, 'b) tfragment f creates a fragment parser that produces a value by calling f on the fragment part of the URL.
The fragment part is percent-decoded automatically.
For example. the parser s "excercises" </> fragment Fun.id produces the folloing results:
input | parse result |
|---|---|
|
|
|
|
|
|
parse parser url runs the given parser on the given url.
Example:
type route = Home | Blog of int | Not_found
let route_parser: (route -> 'a, 'a) Parser.t =
let open Parser in
one_of
[
map Home top;
map (fun id -> Blog id) (s "blog" </> int);
]
let route_of_string (str: string): route =
match of_string str with
| None ->
Not_found
| Some url ->
Option.value ~default:Not_found (parse route_parser url)The route_of_string function above produces the following results:
input | parse result |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|