Skip to content

Commit

Permalink
sexp converters
Browse files Browse the repository at this point in the history
Signed-off-by: Rudi Grinberg <[email protected]>
  • Loading branch information
rgrinberg committed Nov 14, 2020
1 parent 66647e5 commit 11e01a0
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 39 deletions.
66 changes: 35 additions & 31 deletions opium/src/router.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ module Route = struct
| Literal of string * t
| Param of string option * t

let rec sexp_of_t (t : t) : Sexplib0.Sexp.t =
match t with
| Nil -> Atom "Nil"
| Literal (x, y) -> List [ Atom x; sexp_of_t y ]
| Param (x, y) ->
let x : Sexplib0.Sexp.t =
match x with
| Some x -> Atom (":" ^ x)
| None -> Atom "*"
in
List [ x; sexp_of_t y ]
;;

exception E of string

let rec parse_tokens params tokens =
Expand Down Expand Up @@ -55,30 +68,15 @@ module Params = struct
; unnamed : string list
}

let pp fmt { named; unnamed } =
let pp_sep fmt () = Format.fprintf fmt ";@ " in
let pp_named fmt named =
Format.fprintf
fmt
"@[[%a]@]"
(Format.pp_print_list ~pp_sep (fun fmt (name, value) ->
Format.fprintf fmt "(%s,@ %s)" name value))
named
in
let pp_unnamed fmt unnamed =
Format.fprintf
fmt
"@[[%a]@]"
(Format.pp_print_list ~pp_sep (fun fmt unnamed -> Format.fprintf fmt "%s" unnamed))
unnamed
in
Format.fprintf
fmt
"@[{ named@ = %a @ ;@ unnamed = %a@ }@]"
pp_named
named
pp_unnamed
unnamed
let sexp_of_t { named; unnamed } =
let open Sexplib0.Sexp_conv in
Sexplib0.Sexp.List
[ List
[ Atom "named"
; sexp_of_list (sexp_of_pair sexp_of_string sexp_of_string) named
]
; List [ Atom "unnamed"; sexp_of_list sexp_of_string unnamed ]
]
;;

let named t name = List.assoc name t.named
Expand Down Expand Up @@ -112,13 +110,19 @@ type 'a t =
; param : 'a t option
}

let rec pp f fmt { data; literal; param } =
ignore (data, param);
Format.pp_open_box fmt 0;
Format.fprintf fmt "{@ ";
Smap.iter (fun lit node -> Format.fprintf fmt "@[(%S,@ %a)@ @]" lit (pp f) node) literal;
Format.fprintf fmt "@ }";
Format.pp_close_box fmt ()
let sexp_of_smap f smap : Sexplib0.Sexp.t =
List
(Smap.bindings smap
|> ListLabels.map ~f:(fun (k, v) -> Sexplib0.Sexp.List [ Atom k; f v ]))
;;

let rec sexp_of_t f { data; literal; param } =
let open Sexplib0.Sexp_conv in
Sexplib0.Sexp.List
[ List [ Atom "data"; sexp_of_option (sexp_of_pair f Route.sexp_of_t) data ]
; List [ Atom "literal"; sexp_of_smap (sexp_of_t f) literal ]
; List [ Atom "param"; sexp_of_option (sexp_of_t f) param ]
]
;;

let empty = { data = None; literal = Smap.empty; param = None }
Expand Down
5 changes: 3 additions & 2 deletions opium/src/router.mli
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ module Route : sig

val of_string : string -> (t, string) result
val of_string_exn : string -> t
val sexp_of_t : t -> Sexplib0.Sexp.t
end

module Params : sig
type t

val named : t -> string -> string
val unnamed : t -> string list
val pp : Format.formatter -> t -> unit
val sexp_of_t : t -> Sexplib0.Sexp.t
end

type 'a t

val empty : 'a t
val add : 'a t -> Route.t -> 'a -> 'a t
val match_url : 'a t -> string -> ('a * Params.t) option
val pp : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit
val sexp_of_t : ('a -> Sexplib0.Sexp.t) -> 'a t -> Sexplib0.Sexp.t
17 changes: 11 additions & 6 deletions opium/test/opium_router_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ let%expect_test "duplicate paramters" =
let test_match_url router url =
match Router.match_url router url with
| None -> print_endline "no match"
| Some (_, p) -> Format.printf "matched with params: %a@." Params.pp p
| Some (_, p) ->
Format.printf "matched with params: %a@." Sexplib0.Sexp.pp_hum (Params.sexp_of_t p)
;;

let%expect_test "dummy router matches nothing" =
Expand All @@ -55,7 +56,7 @@ let%expect_test "we can add & match literal routes" =
let router = add empty route () in
test_match_url router url;
[%expect {|
matched with params: { named = [] ; unnamed = [] } |}]
matched with params: ((named ()) (unnamed ())) |}]
;;

let%expect_test "we can extract parameter after match" =
Expand All @@ -66,7 +67,7 @@ let%expect_test "we can extract parameter after match" =
test_match_url router "/foo/100/200/300";
[%expect
{|
matched with params: { named = [(bar, 100)] ; unnamed = [baz] }
matched with params: ((named ((bar 100))) (unnamed (baz)))
no match
no match |}]
;;
Expand All @@ -92,7 +93,7 @@ let%expect_test "ambiguity in routes" =
(Failure "duplicate routes")
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Called from Stdlib__list.fold_left in file "list.ml", line 121, characters 24-34
Called from Opium_tests__Opium_router_tests.(fun) in file "opium/test/opium_router_tests.ml", line 84, characters 2-49
Called from Opium_tests__Opium_router_tests.(fun) in file "opium/test/opium_router_tests.ml", line 85, characters 2-49
Called from Expect_test_collector.Make.Instance.exec in file "collector/expect_test_collector.ml", line 244, characters 12-19 |}]
;;

Expand All @@ -108,7 +109,7 @@ let%expect_test "ambiguity in routes 2" =
(Failure "duplicate routes")
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Called from Stdlib__list.fold_left in file "list.ml", line 121, characters 24-34
Called from Opium_tests__Opium_router_tests.(fun) in file "opium/test/opium_router_tests.ml", line 100, characters 2-43
Called from Opium_tests__Opium_router_tests.(fun) in file "opium/test/opium_router_tests.ml", line 101, characters 2-43
Called from Expect_test_collector.Make.Instance.exec in file "collector/expect_test_collector.ml", line 244, characters 12-19 |}]
;;

Expand All @@ -117,7 +118,11 @@ let%expect_test "nodes are matched correctly" =
let test url expected_value =
match match_url router url with
| Some (s, _) -> assert (s = expected_value)
| None -> Format.printf "%a@." (Router.pp Format.pp_print_string) router
| None ->
Format.printf
"%a@."
Sexplib0.Sexp.pp_hum
(Router.sexp_of_t Sexplib0.Sexp_conv.sexp_of_string router)
in
test "/foo/bar" "Wrong";
test "/foo/baz" "Right";
Expand Down

0 comments on commit 11e01a0

Please sign in to comment.