.
This commit is contained in:
parent
b630012667
commit
7df281ec6e
5 changed files with 136 additions and 38 deletions
|
@ -1 +1,2 @@
|
||||||
module U = Vif_u
|
module U = Vif_u
|
||||||
|
module C = Vif_c
|
||||||
|
|
|
@ -1 +1,68 @@
|
||||||
module U = Vif_u
|
module U : sig
|
||||||
|
type 'a atom = 'a Tyre.t
|
||||||
|
type ('f, 'r) path
|
||||||
|
|
||||||
|
val rel : ('r, 'r) path
|
||||||
|
val host : string -> ('r, 'r) path
|
||||||
|
val ( / ) : ('f, 'r) path -> string -> ('f, 'r) path
|
||||||
|
val ( /% ) : ('f, 'a -> 'r) path -> 'a atom -> ('f, 'r) path
|
||||||
|
|
||||||
|
type ('f, 'r) query
|
||||||
|
|
||||||
|
val nil : ('r, 'r) query
|
||||||
|
val any : ('r, 'r) query
|
||||||
|
val ( ** ) : string * 'a atom -> ('f, 'r) query -> ('a -> 'f, 'r) query
|
||||||
|
|
||||||
|
type ('f, 'r) t
|
||||||
|
|
||||||
|
val ( /? ) : ('f, 'x) path -> ('x, 'r) query -> ('f, 'r) t
|
||||||
|
val ( //? ) : ('f, 'x) path -> ('x, 'r) query -> ('f, 'r) t
|
||||||
|
val ( /?? ) : ('f, 'x) path -> ('x, 'r) query -> ('f, 'r) t
|
||||||
|
val keval : ('f, 'r) t -> (string -> 'r) -> 'f
|
||||||
|
val eval : ('f, string) t -> 'f
|
||||||
|
end
|
||||||
|
|
||||||
|
module C : sig
|
||||||
|
(** Module [C] implements the {b c}lient part of the HTTP protocol. *)
|
||||||
|
|
||||||
|
type body
|
||||||
|
type response
|
||||||
|
|
||||||
|
type resolver =
|
||||||
|
[ `Happy of Happy_eyeballs_miou_unix.t
|
||||||
|
| `User of Httpcats.resolver
|
||||||
|
| `System ]
|
||||||
|
|
||||||
|
val request :
|
||||||
|
?config:[ `HTTP_1_1 of H1.Config.t | `H2 of H2.Config.t ]
|
||||||
|
-> ?tls_config:Tls.Config.client
|
||||||
|
-> ?authenticator:X509.Authenticator.t
|
||||||
|
-> ?meth:H1.Method.t
|
||||||
|
-> ?headers:(string * string) list
|
||||||
|
-> ?body:body
|
||||||
|
-> ?max_redirect:int
|
||||||
|
-> ?follow_redirect:bool
|
||||||
|
-> ?resolver:resolver
|
||||||
|
-> ('a, response) U.t
|
||||||
|
-> 'a
|
||||||
|
|
||||||
|
(** {3:example-client Examples.}
|
||||||
|
|
||||||
|
{[
|
||||||
|
open Vif
|
||||||
|
|
||||||
|
(* https://raw.githubusercontent.com/<org>/<repository>/refs/heads/<branch>/README.md *)
|
||||||
|
let readme =
|
||||||
|
let open U in
|
||||||
|
host "raw.githubusercontent.com"
|
||||||
|
/% Tyre.string
|
||||||
|
/% Tyre.string
|
||||||
|
/ "refs"
|
||||||
|
/ "heads"
|
||||||
|
/% Tyre.string
|
||||||
|
/ "README.md"
|
||||||
|
|
||||||
|
let get_readme ?(branch = "main") ~org ~repository () =
|
||||||
|
C.request ~meth:`GET readme org repository branch
|
||||||
|
]} *)
|
||||||
|
end
|
||||||
|
|
21
lib/vif/vif_c.ml
Normal file
21
lib/vif/vif_c.ml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
type body = |
|
||||||
|
type response = unit
|
||||||
|
|
||||||
|
exception Client_error of Httpcats.error
|
||||||
|
|
||||||
|
type resolver =
|
||||||
|
[ `Happy of Happy_eyeballs_miou_unix.t | `User of Httpcats.resolver | `System ]
|
||||||
|
|
||||||
|
let request ?config ?tls_config ?authenticator ?meth ?headers ?body:_
|
||||||
|
?max_redirect ?follow_redirect ?resolver t =
|
||||||
|
let f _meta _response a _chunk = a in
|
||||||
|
let fn uri =
|
||||||
|
let res =
|
||||||
|
Httpcats.request ?config ?tls_config ?authenticator ?meth ?headers
|
||||||
|
?max_redirect ?follow_redirect ?resolver ~f ~uri ()
|
||||||
|
in
|
||||||
|
match res with
|
||||||
|
| Ok (_response, ()) -> ()
|
||||||
|
| Error (#Httpcats.error as err) -> raise (Client_error err)
|
||||||
|
in
|
||||||
|
Vif_u.keval t fn
|
29
lib/vif/vif_r.ml
Normal file
29
lib/vif/vif_r.ml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
type 'a atom = 'a Tyre.Internal.wit
|
||||||
|
|
||||||
|
let atom re = Tyre.Internal.build re
|
||||||
|
let slash = Re.char '/'
|
||||||
|
let comma = Re.char ','
|
||||||
|
|
||||||
|
let list ?m ~component n re =
|
||||||
|
let open Re in
|
||||||
|
match component with
|
||||||
|
| `Path -> repn (seq [ slash; re ]) n m
|
||||||
|
| `Query_value ->
|
||||||
|
if n = 0 then alt [ epsilon; seq [ re; repn (seq [ comma; re ]) 0 m ] ]
|
||||||
|
else seq [ re; repn (seq [ comma; re ]) (n - 1) m ]
|
||||||
|
|
||||||
|
let atom_path : type a. int -> a Tyre.Internal.raw -> int * a atom * Re.t =
|
||||||
|
let open Re in
|
||||||
|
fun i -> function
|
||||||
|
| Rep e ->
|
||||||
|
let _, w, re = atom 1 e in
|
||||||
|
( i + 1
|
||||||
|
, Rep (i, w, Re.compile re)
|
||||||
|
, group (list ~component:`Path 0 (no_group re)) )
|
||||||
|
| Opt e ->
|
||||||
|
let i', w, re = atom i e in
|
||||||
|
let id, re = mark re in
|
||||||
|
(i', Opt (id, w), seq [ alt [ epsilon; seq [ slash; re ] ] ])
|
||||||
|
| e ->
|
||||||
|
let i', w, re = atom i e in
|
||||||
|
(i', w, seq [ slash; re ])
|
|
@ -1,34 +1,26 @@
|
||||||
type 'a atom = 'a Tyre.t
|
type 'a atom = 'a Tyre.t
|
||||||
|
|
||||||
module Types = struct
|
type ('fu, 'return) path =
|
||||||
type ('fu, 'return) path =
|
|
||||||
| Host : string -> ('r, 'r) path
|
| Host : string -> ('r, 'r) path
|
||||||
| Rel : ('r, 'r) path
|
| Rel : ('r, 'r) path
|
||||||
| Path_const : ('f, 'r) path * string -> ('f, 'r) path
|
| Path_const : ('f, 'r) path * string -> ('f, 'r) path
|
||||||
| Path_atom : ('f, 'a -> 'r) path * 'a atom -> ('f, 'r) path
|
| Path_atom : ('f, 'a -> 'r) path * 'a atom -> ('f, 'r) path
|
||||||
|
|
||||||
type ('fu, 'return) query =
|
type ('fu, 'return) query =
|
||||||
| Nil : ('r, 'r) query
|
| Nil : ('r, 'r) query
|
||||||
| Any : ('r, 'r) query
|
| Any : ('r, 'r) query
|
||||||
| Query_atom : string * 'a atom * ('f, 'r) query -> ('a -> 'f, 'r) query
|
| Query_atom : string * 'a atom * ('f, 'r) query -> ('a -> 'f, 'r) query
|
||||||
|
|
||||||
type slash = Slash | No_slash | Maybe_slash
|
type slash = Slash | No_slash | Maybe_slash
|
||||||
|
type ('f, 'r) t = Url : slash * ('f, 'x) path * ('x, 'r) query -> ('f, 'r) t
|
||||||
type ('f, 'r) url =
|
|
||||||
| Url : slash * ('f, 'x) path * ('x, 'r) query -> ('f, 'r) url
|
|
||||||
end
|
|
||||||
|
|
||||||
module Path = struct
|
module Path = struct
|
||||||
type ('f, 'r) t = ('f, 'r) Types.path
|
|
||||||
|
|
||||||
open Types
|
|
||||||
|
|
||||||
let host str = Host str
|
let host str = Host str
|
||||||
let relative = Rel
|
let relative = Rel
|
||||||
let add path str = Path_const (path, str)
|
let add path str = Path_const (path, str)
|
||||||
let add_atom path atom = Path_atom (path, atom)
|
let add_atom path atom = Path_atom (path, atom)
|
||||||
|
|
||||||
let rec _concat : type f r x. (f, x) t -> (x, r) t -> (f, r) t =
|
let rec _concat : type f r x. (f, x) path -> (x, r) path -> (f, r) path =
|
||||||
fun p1 p2 ->
|
fun p1 p2 ->
|
||||||
match p2 with
|
match p2 with
|
||||||
| Host _ -> p1
|
| Host _ -> p1
|
||||||
|
@ -38,20 +30,16 @@ module Path = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
module Query = struct
|
module Query = struct
|
||||||
type ('f, 'r) t = ('f, 'r) Types.query
|
let nil : _ query = Nil
|
||||||
|
|
||||||
open Types
|
|
||||||
|
|
||||||
let nil : _ t = Nil
|
|
||||||
let any = Any
|
let any = Any
|
||||||
let add n x query = Query_atom (n, x, query)
|
let add n x query = Query_atom (n, x, query)
|
||||||
|
|
||||||
let rec make_any : type f r. (f, r) t -> (f, r) t = function
|
let rec make_any : type f r. (f, r) query -> (f, r) query = function
|
||||||
| Nil -> Any
|
| Nil -> Any
|
||||||
| Any -> Any
|
| Any -> Any
|
||||||
| Query_atom (n, x, q) -> Query_atom (n, x, make_any q)
|
| Query_atom (n, x, q) -> Query_atom (n, x, make_any q)
|
||||||
|
|
||||||
let rec _concat : type f r x. (f, x) t -> (x, r) t -> (f, r) t =
|
let rec _concat : type f r x. (f, x) query -> (x, r) query -> (f, r) query =
|
||||||
fun q1 q2 ->
|
fun q1 q2 ->
|
||||||
match q1 with
|
match q1 with
|
||||||
| Nil -> q2
|
| Nil -> q2
|
||||||
|
@ -60,17 +48,9 @@ module Query = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
module Url = struct
|
module Url = struct
|
||||||
type ('f, 'r) t = ('f, 'r) Types.url
|
|
||||||
|
|
||||||
open Types
|
|
||||||
|
|
||||||
let make ?(slash = No_slash) path query : _ t = Url (slash, path, query)
|
let make ?(slash = No_slash) path query : _ t = Url (slash, path, query)
|
||||||
end
|
end
|
||||||
|
|
||||||
type ('f, 'r) path = ('f, 'r) Path.t
|
|
||||||
type ('f, 'r) query = ('f, 'r) Query.t
|
|
||||||
type ('f, 'r) t = ('f, 'r) Url.t
|
|
||||||
|
|
||||||
let nil = Query.nil
|
let nil = Query.nil
|
||||||
let any = Query.any
|
let any = Query.any
|
||||||
let ( ** ) (n, x) q = Query.add n x q
|
let ( ** ) (n, x) q = Query.add n x q
|
||||||
|
@ -89,7 +69,7 @@ let eval_top_atom : type a. a Tyre.Internal.raw -> a -> string list = function
|
||||||
| e -> fun x -> [ eval_atom e x ]
|
| e -> fun x -> [ eval_atom e x ]
|
||||||
|
|
||||||
let rec eval_path : type r f.
|
let rec eval_path : type r f.
|
||||||
(f, r) Path.t -> (string option -> string list -> r) -> f =
|
(f, r) path -> (string option -> string list -> r) -> f =
|
||||||
fun p k ->
|
fun p k ->
|
||||||
match p with
|
match p with
|
||||||
| Host str -> k (Some str) []
|
| Host str -> k (Some str) []
|
||||||
|
@ -100,7 +80,7 @@ let rec eval_path : type r f.
|
||||||
eval_path p fn
|
eval_path p fn
|
||||||
|
|
||||||
let rec eval_query : type r f.
|
let rec eval_query : type r f.
|
||||||
(f, r) Query.t -> ((string * string list) list -> r) -> f =
|
(f, r) query -> ((string * string list) list -> r) -> f =
|
||||||
fun q k ->
|
fun q k ->
|
||||||
match q with
|
match q with
|
||||||
| Nil -> k []
|
| Nil -> k []
|
||||||
|
|
Loading…
Reference in a new issue