Utils: add Data_encoding.delayed

This allows a better representation for `Error_monad.error_encoding`,
capturing the side-effect of new error registration.
This commit is contained in:
Grégoire Henry 2017-10-27 18:41:59 +02:00 committed by Benjamin Canou
parent 79f2dca33a
commit dc2cd4db1c
8 changed files with 23 additions and 8 deletions

View File

@ -16,7 +16,7 @@ type error = ..
val pp : Format.formatter -> error -> unit val pp : Format.formatter -> error -> unit
(** A JSON error serializer *) (** A JSON error serializer *)
val error_encoding : unit -> error Data_encoding.t val error_encoding : error Data_encoding.t
val json_of_error : error -> Data_encoding.json val json_of_error : error -> Data_encoding.json
val error_of_json : Data_encoding.json -> error val error_of_json : Data_encoding.json -> error

View File

@ -152,6 +152,7 @@ type 'a desc =
{ encoding : 'a t ; { encoding : 'a t ;
json_encoding : 'a Json_encoding.encoding } -> 'a desc json_encoding : 'a Json_encoding.encoding } -> 'a desc
| Dynamic_size : 'a t -> 'a desc | Dynamic_size : 'a t -> 'a desc
| Delayed : (unit -> 'a t) -> 'a desc
and _ field = and _ field =
| Req : string * 'a t -> 'a field | Req : string * 'a t -> 'a field
@ -209,6 +210,7 @@ let rec classify : type a l. a t -> Kind.t = fun e ->
| Def { encoding } -> classify encoding | Def { encoding } -> classify encoding
| Splitted { encoding } -> classify encoding | Splitted { encoding } -> classify encoding
| Dynamic_size _ -> `Dynamic | Dynamic_size _ -> `Dynamic
| Delayed f -> classify (f ())
let make ?json_encoding encoding = { encoding ; json_encoding } let make ?json_encoding encoding = { encoding ; json_encoding }
@ -357,6 +359,7 @@ module Json = struct
| Union (_tag_size, _, cases) -> union (List.map case_json cases) | Union (_tag_size, _, cases) -> union (List.map case_json cases)
| Splitted { json_encoding } -> json_encoding | Splitted { json_encoding } -> json_encoding
| Dynamic_size e -> get_json e | Dynamic_size e -> get_json e
| Delayed f -> get_json (f ())
and field_json and field_json
: type a l. a field -> a Json_encoding.field = : type a l. a field -> a Json_encoding.field =
@ -434,6 +437,9 @@ module Encoding = struct
let dynamic_size e = let dynamic_size e =
make @@ Dynamic_size e make @@ Dynamic_size e
let delayed f =
make @@ Delayed f
let null = make @@ Null let null = make @@ Null
let empty = make @@ Empty let empty = make @@ Empty
let unit = make @@ Ignore let unit = make @@ Ignore
@ -838,6 +844,7 @@ let rec length : type x. x t -> x -> int = fun e ->
| Dynamic_size e -> | Dynamic_size e ->
let length = length e in let length = length e in
fun v -> Size.int32 + length v fun v -> Size.int32 + length v
| Delayed f -> length (f ())
(** Writer *) (** Writer *)
@ -1000,6 +1007,7 @@ let rec length : type x. x t -> x -> int = fun e ->
and write = write_rec e in and write = write_rec e in
fun v buf ofs -> fun v buf ofs ->
int32 (Int32.of_int @@ length v) buf ofs |> write v buf int32 (Int32.of_int @@ length v) buf ofs |> write v buf
| Delayed f -> write_rec (f ())
let write t v buf ofs = let write t v buf ofs =
try Some (write_rec t v buf ofs) try Some (write_rec t v buf ofs)
@ -1217,6 +1225,7 @@ let rec length : type x. x t -> x -> int = fun e ->
let sz = Int32.to_int sz in let sz = Int32.to_int sz in
if sz < 0 then raise (Invalid_size sz); if sz < 0 then raise (Invalid_size sz);
read buf ofs sz read buf ofs sz
| Delayed f -> read_rec (f ())
let read t buf ofs len = let read t buf ofs len =
try Some (read_rec t buf ofs len) try Some (read_rec t buf ofs len)
@ -1513,6 +1522,8 @@ let rec length : type x. x t -> x -> int = fun e ->
if sz < 0 then raise (Invalid_size sz) ; if sz < 0 then raise (Invalid_size sz) ;
data_checker path e buf sz data_checker path e buf sz
| Delayed f -> data_checker path (f ()) buf len
with Need_more_data -> with Need_more_data ->
P_await { path ; encoding = e ; data_len = len }, buf P_await { path ; encoding = e ; data_len = len }, buf

View File

@ -64,6 +64,8 @@ end
val dynamic_size : 'a encoding -> 'a encoding val dynamic_size : 'a encoding -> 'a encoding
val delayed : (unit -> 'a encoding) -> 'a encoding
val json : json encoding val json : json encoding
val json_schema : json_schema encoding val json_schema : json_schema encoding

View File

@ -427,7 +427,7 @@ let build_rpc_directory node =
let dir = let dir =
let implementation () = let implementation () =
RPC.Answer.return RPC.Answer.return
Data_encoding.Json.(schema (Error_monad.error_encoding ())) in Data_encoding.Json.(schema Error_monad.error_encoding) in
RPC.register0 dir Services.Error.service implementation in RPC.register0 dir Services.Error.service implementation in
let dir = let dir =
RPC.register1 dir Services.complete RPC.register1 dir Services.complete

View File

@ -183,7 +183,7 @@ module WrapProtocol
"@[<v 2>Economic error:@ %a@]" "@[<v 2>Economic error:@ %a@]"
(Format.pp_print_list Env.Error_monad.pp)) (Format.pp_print_list Env.Error_monad.pp))
Data_encoding.(obj1 (req "ecoproto" Data_encoding.(obj1 (req "ecoproto"
(list (Env.Error_monad.error_encoding ())))) (list Env.Error_monad.error_encoding)))
(function Ecoproto_error ecoerrors -> Some ecoerrors (function Ecoproto_error ecoerrors -> Some ecoerrors
| _ -> None ) | _ -> None )
(function ecoerrors -> Ecoproto_error ecoerrors) (function ecoerrors -> Ecoproto_error ecoerrors)

View File

@ -139,7 +139,7 @@ let () =
let () = let () =
register1_noctxt Services.Constants.errors register1_noctxt Services.Constants.errors
(fun () -> (fun () ->
Lwt.return (Data_encoding.Json.(schema (error_encoding ())))) Lwt.return (Data_encoding.Json.(schema error_encoding)))
(*-- Context -----------------------------------------------------------------*) (*-- Context -----------------------------------------------------------------*)

View File

@ -117,10 +117,12 @@ module Make() = struct
encoding encoding
| Some encoding -> encoding | Some encoding -> encoding
let error_encoding = Data_encoding.delayed error_encoding
let json_of_error error = let json_of_error error =
Data_encoding.Json.(construct (error_encoding ())) error Data_encoding.Json.construct error_encoding error
let error_of_json json = let error_of_json json =
Data_encoding.Json.(destruct (error_encoding ())) json Data_encoding.Json.destruct error_encoding json
let classify_error error = let classify_error error =
let rec find e = function let rec find e = function
@ -166,7 +168,7 @@ module Make() = struct
let open Data_encoding in let open Data_encoding in
let errors_encoding = let errors_encoding =
describe ~title: "An erroneous result" @@ describe ~title: "An erroneous result" @@
obj1 (req "error" (list (error_encoding ()))) in obj1 (req "error" (list error_encoding)) in
let t_encoding = let t_encoding =
describe ~title: "A successful result" @@ describe ~title: "A successful result" @@
obj1 (req "result" t_encoding) in obj1 (req "result" t_encoding) in

View File

@ -22,7 +22,7 @@ module type S = sig
val pp_print_error: Format.formatter -> error list -> unit val pp_print_error: Format.formatter -> error list -> unit
(** An error serializer *) (** An error serializer *)
val error_encoding : unit -> error Data_encoding.t val error_encoding : error Data_encoding.t
val json_of_error : error -> Data_encoding.json val json_of_error : error -> Data_encoding.json
val error_of_json : Data_encoding.json -> error val error_of_json : Data_encoding.json -> error