Data_encoding: add names to union cases

This commit is contained in:
Milo Davis 2018-03-10 10:27:40 -05:00 committed by Grégoire Henry
parent de006f4be3
commit f5cc599ae6
3 changed files with 15 additions and 7 deletions

View File

@ -174,7 +174,8 @@ and _ field =
| Dft : string * 'a t * 'a -> 'a field
and 'a case =
| Case : { encoding : 'a t ;
| Case : { name : string option ;
encoding : 'a t ;
proj : ('t -> 'a option) ;
inj : ('a -> 't) ;
tag : case_tag } -> 't case
@ -326,8 +327,9 @@ module Json = struct
make @@
Union (kind, tag,
List.map
(fun (Case { encoding ; proj = proj' ; inj = inj' ; tag }) ->
(fun (Case { name ; encoding ; proj = proj' ; inj = inj' ; tag }) ->
Case { encoding ;
name ;
proj = (fun x -> proj' (proj x));
inj = (fun x -> inj (inj' x)) ;
tag })
@ -352,8 +354,9 @@ module Json = struct
make @@
Union (`Dynamic (* ignored *), tag,
List.map
(fun (Case { encoding = e2 ; proj ; inj ; tag }) ->
(fun (Case { name ; encoding = e2 ; proj ; inj ; tag }) ->
Case { encoding = lift_union_in_pair b p e1 e2 ;
name ;
proj = (fun (x, y) ->
match proj y with
| None -> None
@ -365,8 +368,9 @@ module Json = struct
make @@
Union (`Dynamic (* ignored *), tag,
List.map
(fun (Case { encoding = e1 ; proj ; inj ; tag }) ->
(fun (Case { name ; encoding = e1 ; proj ; inj ; tag }) ->
Case { encoding = lift_union_in_pair b p e1 e2 ;
name ;
proj = (fun (x, y) ->
match proj x with
| None -> None
@ -821,14 +825,16 @@ module Encoding = struct
List.map (fun (Case { encoding }) -> classify encoding) cases in
let kind = Kind.merge_list tag_size kinds in
make @@ Union (kind, tag_size, cases)
let case tag encoding proj inj = Case { encoding ; proj ; inj ; tag }
let case ?name tag encoding proj inj = Case { name ; encoding ; proj ; inj ; tag }
let option ty =
union
~tag_size:`Uint8
[ case (Tag 1) ty
~name:"Some"
(fun x -> x)
(fun x -> Some x) ;
case (Tag 0) empty
~name:"None"
(function None -> Some () | Some _ -> None)
(fun () -> None) ;
]

View File

@ -357,8 +357,10 @@ type case_tag = Tag of int | Json_only
An optional tag gives a name to a case and should be used to maintain
compatibility.
If no tag is specified, tags are assigned by the union combinator. *)
An optional name for the case can be provided,
which is used in the binary documentation. *)
val case :
?name:string ->
case_tag ->
'a encoding -> ('t -> 'a option) -> ('a -> 't) -> 't case

View File

@ -164,7 +164,7 @@ type case_tag = Tag of int | Json_only
type 't case
val case :
case_tag -> 'a encoding -> ('t -> 'a option) -> ('a -> 't) -> 't case
?name:string -> case_tag -> 'a encoding -> ('t -> 'a option) -> ('a -> 't) -> 't case
val union :
?tag_size:[ `Uint8 | `Uint16 ] -> 't case list -> 't encoding