123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201(*
Mapping from ATD to JSON
*)typejson_float=|Floatofintoption(* max decimal places *)|Inttypejson_adapter={ocaml_adapter:stringoption;java_adapter:stringoption;}letno_adapter={ocaml_adapter=None;java_adapter=None;}typejson_list=Array|Objecttypejson_variant={json_cons:string}typejson_field={json_fname:string;(* <json name=...> *)json_unwrapped:bool;}typejson_record={json_keep_nulls:bool;(* { ... } <json keep_nulls> *)json_record_adapter:json_adapter;}typejson_sum={json_sum_adapter:json_adapter;json_open_enum:bool;json_lowercase_tags:bool;}(*
Note that json adapters are supported only by records and sums
at this time.
TODO: Support json adapters for all kinds of nodes rather than just
sums and records, preferably without major code duplication.
Maybe this can be achieved by turning json_repr
into (json_repr * json_adapter).
*)typejson_repr=|Bool|Cell|Def|External|Fieldofjson_field|Floatofjson_float|Int|Listofjson_list|Nullable|Option|Recordofjson_record|String|Sumofjson_sum|Tuple|Unit|Variantofjson_variant|Wrap(* should we add support for Base64 encoding of binary data? *)(*
This must hold all the valid annotations of the form
'<json ...>'.
*)letannot_schema_json:Annot.schema=[{section="json";fields=[Type_expr,"adapter.ocaml";Type_expr,"keep_nulls";Type_expr,"open_enum";Type_expr,"precision";Type_expr,"repr";Variant,"name";Field,"name";Field,"tag_field";]};{(* deprecated *)section="ocaml_json";fields=[Type_def,"from";Type_def,"module";Type_def,"predef";Type_def,"t";]};]letjson_float_of_strings:[`Float|`Int]option=matchswith"float"->Some`Float|"int"->Some`Int|_->Noneletjson_precision_of_strings=trySome(int_of_strings)with_->Noneletget_json_precisionan=Annot.get_opt_field~parse:json_precision_of_string~sections:["json"]~field:"precision"anletget_json_floatan:json_float=matchAnnot.get_field~parse:json_float_of_string~default:`Float~sections:["json"]~field:"repr"anwith`Float->Float(get_json_precisionan)|`Int->Intletjson_list_of_strings:json_listoption=matchswith|"array"->SomeArray|"object"->SomeObject|_->(* error *)None(*
<json adapter.ocaml="Foo.Bar">
--> { ocaml_adapter = Some "Foo.Bar";
java_adapter = None; }
*)letget_json_adapteran=letocaml_adapter=Annot.get_opt_field~parse:(funs->Somes)~sections:["json"]~field:"adapter.ocaml"aninletjava_adapter=Annot.get_opt_field~parse:(funs->Somes)~sections:["json"]~field:"adapter.java"anin{ocaml_adapter;java_adapter}letget_json_open_enuman=Annot.get_flag~sections:["json"]~field:"open_enum"anletget_json_lowercase_tagsan=Annot.get_flag~sections:["json"]~field:"lowercase_tags"anletget_json_suman={json_sum_adapter=get_json_adapteran;json_open_enum=get_json_open_enuman;json_lowercase_tags=get_json_lowercase_tagsan;}letget_json_listan=Annot.get_field~parse:json_list_of_string~default:Array~sections:["json"]~field:"repr"anletget_json_consdefaultan=Annot.get_field~parse:(funs->Somes)~default~sections:["json"]~field:"name"anletget_json_fnamedefaultan=Annot.get_field~parse:(funs->Somes)~default~sections:["json"]~field:"name"anletget_json_keep_nullsan=Annot.get_flag~sections:["json"]~field:"keep_nulls"anletget_json_recordan={json_keep_nulls=get_json_keep_nullsan;json_record_adapter=get_json_adapteran;}