ligo/vendors/ocplib-resto/lib_resto-json/resto_json.ml
2017-12-11 17:53:49 +00:00

182 lines
6.1 KiB
OCaml

(**************************************************************************)
(* ocplib-resto *)
(* Copyright (C) 2016, OCamlPro. *)
(* *)
(* All rights reserved. This file is distributed under the terms *)
(* of the GNU Lesser General Public License version 2.1, with the *)
(* special exception on linking described in the file LICENSE. *)
(* *)
(**************************************************************************)
module Encoding = struct
include Json_encoding
type 'a t = 'a encoding
type schema = Json_schema.schema
let untyped = obj1 (req "untyped" string)
let conv f g t = conv ~schema:(schema t) f g t
module StringMap = Map.Make(String)
let arg_encoding =
let open Json_encoding in
conv
(fun {Resto.Arg.name; descr} -> (name, descr))
(fun (name, descr) -> {name; descr})
(obj2 (req "name" string) (opt "descr" string))
open Resto.Description
let meth_encoding =
Json_encoding.string_enum
[ "GET", `GET ;
"POST", `POST ;
"DELETE", `DELETE ;
"PUT", `PUT ;
"PATCH", `PATCH ]
let path_item_encoding =
let open Json_encoding in
union [
case string
(function PStatic s -> Some s | _ -> None)
(fun s -> PStatic s) ;
case arg_encoding
(function PDynamic s -> Some s | _ -> None)
(fun s -> PDynamic s) ;
]
let query_kind_encoding =
let open Json_encoding in
union [
case
(obj1 (req "single" arg_encoding))
(function Single s -> Some s | _ -> None)
(fun s -> Single s) ;
case
(obj1 (req "optional" arg_encoding))
(function Optional s -> Some s | _ -> None)
(fun s -> Optional s) ;
case
(obj1 (req "flag" empty))
(function Flag -> Some () | _ -> None)
(fun () -> Flag) ;
case
(obj1 (req "multi" arg_encoding))
(function Multi s -> Some s | _ -> None)
(fun s -> Multi s) ;
]
let query_item_encoding =
let open Json_encoding in
conv
(fun {name ; description ; kind} -> (name, description, kind))
(fun (name, description, kind) -> {name ; description ; kind})
(obj3
(req "name" string)
(opt "description" string)
(req "kind" query_kind_encoding))
let service_descr_encoding =
let open Json_encoding in
conv
(fun { meth ; path ; description ; query ; input ; output ; error } ->
(meth, path, description, query, input, output, error))
(fun (meth, path, description, query, input, output, error) ->
{ meth ; path ; description ; query ; input ; output ; error })
(obj7
(req "meth" meth_encoding)
(req "path" (list path_item_encoding))
(opt "description" string)
(req "query" (list query_item_encoding))
(opt "input" any_schema)
(req "output" any_schema)
(req "erro" any_schema))
let directory_descr_encoding =
let open Json_encoding in
mu "service_tree" @@ fun directory_descr_encoding ->
let static_subdirectories_descr_encoding =
union [
case (obj1 (req "suffixes"
(list (obj2 (req "name" string)
(req "tree" directory_descr_encoding)))))
(function Suffixes map ->
Some (Resto.StringMap.bindings map) | _ -> None)
(fun m ->
let add acc (n,t) = Resto.StringMap.add n t acc in
Suffixes (List.fold_left add Resto.StringMap.empty m)) ;
case (obj1 (req "dynamic_dispatch"
(obj2
(req "arg" arg_encoding)
(req "tree" directory_descr_encoding))))
(function Arg (ty, tree) -> Some (ty, tree) | _ -> None)
(fun (ty, tree) -> Arg (ty, tree))
] in
let static_directory_descr_encoding =
conv
(fun { services ; subdirs } ->
let find s =
try Some (Resto.MethMap.find s services) with Not_found -> None in
(find `GET, find `POST, find `DELETE,
find `PUT, find `PATCH, subdirs))
(fun (get, post, delete, put, patch, subdirs) ->
let add meth s services =
match s with
| None -> services
| Some s -> Resto.MethMap.add meth s services in
let services =
Resto.MethMap.empty
|> add `GET get
|> add `POST post
|> add `DELETE delete
|> add `PUT put
|> add `PATCH patch in
{ services ; subdirs })
(obj6
(opt "get_service" service_descr_encoding)
(opt "post_service" service_descr_encoding)
(opt "delete_service" service_descr_encoding)
(opt "put_service" service_descr_encoding)
(opt "patch_service" service_descr_encoding)
(opt "subdirs" static_subdirectories_descr_encoding)) in
union [
case (obj1 (req "static" static_directory_descr_encoding))
(function Static descr -> Some descr | _ -> None)
(fun descr -> Static descr) ;
case (obj1 (req "dynamic" (option string)))
(function Dynamic descr -> Some descr | _ -> None)
(fun descr -> Dynamic descr) ;
]
let description_request_encoding =
conv
(fun { recurse } -> recurse)
(function recurse -> { recurse })
(obj1 (dft "recursive" bool false))
let description_answer_encoding = directory_descr_encoding
end
module type VALUE = sig
type t
type 'a encoding
val construct: 'a encoding -> 'a -> t
val destruct: 'a encoding -> t -> 'a
end
module Ezjsonm = struct
type t = Json_repr.Ezjsonm.value
let construct = Json_encoding.construct
let destruct = Json_encoding.destruct
end
module Bson = struct
open Json_repr_bson
type t = Repr.value
let construct = Json_encoding.construct
let destruct = Json_encoding.destruct
end