123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264(* Basic type definitions *)openRpc.Typestypeerr=[`Msgofstring]lettailrec_mapfl=List.rev_mapfl|>List.revletrecunmarshal:typea.atyp->Rpc.t->(a,err)Result.t=funtv->letopenRpcinletopenResultinletopenRresult.RinletopenRpc.ResultUnmarshallersinletlist_helpertypl=List.fold_left(funaccv->matchacc,unmarshaltypvwith|Oka,Okv->Ok(v::a)|_,Error(`Msgs)->Error(Rresult.R.msg(Printf.sprintf"Failed to unmarshal array: %s (when unmarshalling: %s)"s(Rpc.to_stringv)))|x,_->x)(Ok[])l>>|List.revinmatchtwith|BasicInt->int_of_rpcv|BasicInt32->int32_of_rpcv|BasicInt64->int64_of_rpcv|BasicBool->bool_of_rpcv|BasicFloat->float_of_rpcv|BasicString->string_of_rpcv|BasicChar->int_of_rpcv>>|Char.chr|DateTime->dateTime_of_rpcv|Base64->base64_of_rpcv|Arraytyp->(matchvwith|Enumxs->list_helpertypxs>>|Array.of_list|_->Rresult.R.error_msg"Expecting Array")|List(Tuple(BasicString,typ))->(matchvwith|Dictxs->letkeys=tailrec_mapfstxsinletvs=tailrec_mapsndxsinlist_helpertypvs>>=funvs->return(List.combinekeysvs)|_->Rresult.R.error_msg"Unhandled")|Dict(basic,typ)->(matchvwith|Dictxs->(matchbasicwith|String->letkeys=tailrec_mapfstxsinletvs=tailrec_mapsndxsinlist_helpertypvs>>=funvs->return(List.combinekeysvs)|_->Rresult.R.error_msg"Expecting something other than a Dict type")|_->Rresult.R.error_msg"Unhandled")|Listtyp->(matchvwith|Enumxs->list_helpertypxs|_->Rresult.R.error_msg"Expecting array")|Unit->unit_of_rpcv|Optiont->(matchvwith|Enum[x]->unmarshaltx>>=funx->return(Somex)|Enum[]->returnNone|y->Rresult.R.error_msg(Printf.sprintf"Expecting an Enum value, got '%s'"(Rpc.to_stringy)))|Tuple(t1,t2)->(matchv,t2with|Rpc.Enumlist,Tuple(_,_)->unmarshalt1(List.hdlist)>>=funv1->unmarshalt2(Rpc.Enum(List.tllist))>>=funv2->Ok(v1,v2)|Rpc.Enum[x;y],_->unmarshalt1x>>=funv1->unmarshalt2y>>=funv2->Ok(v1,v2)|Rpc.Enum_,_->Rresult.R.error_msg"Too many items in a tuple!"|_,_->error_msg"Expecting Rpc.Enum when unmarshalling a tuple")|Tuple3(t1,t2,t3)->(matchvwith|Rpc.Enum[x;y;z]->unmarshalt1x>>=funv1->unmarshalt2y>>=funv2->unmarshalt3z>>=funv3->Ok(v1,v2,v3)|Rpc.Enum_->Rresult.R.error_msg"Expecting precisely 3 items when unmarshalling a Tuple3"|_->error_msg"Expecting Rpc.Enum when unmarshalling a tuple3")|Tuple4(t1,t2,t3,t4)->(matchvwith|Rpc.Enum[x;y;z;a]->unmarshalt1x>>=funv1->unmarshalt2y>>=funv2->unmarshalt3z>>=funv3->unmarshalt4a>>=funv4->Ok(v1,v2,v3,v4)|Rpc.Enum_->Rresult.R.error_msg"Expecting precisely 4 items in an Enum when unmarshalling a Tuple4"|_->error_msg"Expecting Rpc.Enum when unmarshalling a tuple4")|Struct{constructor;sname;_}->(matchvwith|Rpc.Dictkeys'->letkeys=List.map(fun(s,v)->String.lowercase_asciis,v)keys'inconstructor{field_get=(letx:typea.string->atyp->(a,Rresult.R.msg)Result.t=funsty->lets=String.lowercase_asciisinmatchtywith|Optionx->(tryList.assocskeys|>unmarshalx>>=funo->return(Someo)with|_->returnNone)|y->(tryList.assocskeys|>unmarshalywith|Not_found->error_msg(Printf.sprintf"No value found for key: '%s' when unmarshalling '%s'"ssname))inx)}|_->error_msg(Printf.sprintf"Expecting Rpc.Dict when unmarshalling a '%s'"sname))|Variant{vconstructor;_}->(matchvwith|Rpc.Stringname->ok(name,Rpc.Null)|Rpc.Enum[Rpc.Stringname;contents]->ok(name,contents)|_->error_msg"Expecting String or Enum when unmarshalling a variant")>>=fun(name,contents)->letconstr={tget=(funtyp->unmarshaltypcontents)}invconstructornameconstr|Abstract{of_rpc;_}->of_rpcvletrecmarshal:typea.atyp->a->Rpc.t=funtv->letopenRpcinletrpc_of_basic:typea.abasic->a->Rpc.t=funtv->matchtwith|Int->rpc_of_intv|Int32->rpc_of_int32v|Int64->rpc_of_int64v|Bool->rpc_of_boolv|Float->rpc_of_floatv|String->rpc_of_stringv|Char->rpc_of_int(Char.codev)inmatchtwith|Basict->rpc_of_basictv|DateTime->rpc_of_dateTimev|Base64->rpc_of_base64v|Arraytyp->Enum(tailrec_map(marshaltyp)(Array.to_listv))|List(Tuple(BasicString,typ))->Dict(tailrec_map(fun(x,y)->x,marshaltypy)v)|Listtyp->Enum(tailrec_map(marshaltyp)v)|Dict(String,typ)->Rpc.Dict(tailrec_map(fun(k,v)->k,marshaltypv)v)|Dict(basic,typ)->Rpc.Enum(tailrec_map(fun(k,v)->Rpc.Enum[rpc_of_basicbasick;marshaltypv])v)|Unit->rpc_of_unitv|Optionty->Rpc.Enum(matchvwith|Somex->[marshaltyx]|None->[])|Tuple(x,(Tuple(_,_)asy))->(matchmarshaly(sndv)with|Rpc.Enumxs->Rpc.Enum(marshalx(fstv)::xs)|_->failwith"Marshalling a tuple should always give an Enum")|Tuple(x,y)->Rpc.Enum[marshalx(fstv);marshaly(sndv)]|Tuple3(x,y,z)->letvx,vy,vz=vinRpc.Enum[marshalxvx;marshalyvy;marshalzvz]|Tuple4(x,y,z,a)->letvx,vy,vz,va=vinRpc.Enum[marshalxvx;marshalyvy;marshalzvz;marshalava]|Struct{fields;_}->letfields=List.fold_left(funaccf->matchfwith|BoxedFieldf->letvalue=marshalf.field(f.fgetv)in(matchf.field,valuewith|Option_,Rpc.Enum[]->acc|Option_,Rpc.Enum[x]->(f.fname,x)::acc|_,_->(f.fname,value)::acc))[]fieldsinRpc.Dictfields|Variant{variants;_}->List.fold_left(funacct->matchtwith|BoxedTagt->(matcht.tpreviewvwith|Somex->(matchmarshalt.tcontentsxwith|Rpc.Null->Rpc.Stringt.tname|y->Rpc.Enum[Rpc.Stringt.tname;y])|None->acc))Rpc.Nullvariants|Abstract{rpc_of;_}->rpc_ofvletocaml_of_basic:typea.abasic->string=function|Int64->"int64"|Int32->"int32"|Int->"int"|String->"string"|Float->"float"|Bool->"bool"|Char->"char"letrecocaml_of_t:typea.atyp->string=function|Basicb->ocaml_of_basicb|DateTime->"string"|Base64->"base64"|Arrayt->ocaml_of_tt^" list"|Listt->ocaml_of_tt^" list"|Dict(b,t)->Printf.sprintf"(%s * %s) list"(ocaml_of_basicb)(ocaml_of_tt)|Unit->"unit"|Optiont->ocaml_of_tt^" option"|Tuple(a,b)->Printf.sprintf"(%s * %s)"(ocaml_of_ta)(ocaml_of_tb)|Tuple3(a,b,c)->Printf.sprintf"(%s * %s * %s)"(ocaml_of_ta)(ocaml_of_tb)(ocaml_of_tc)|Tuple4(a,b,c,d)->Printf.sprintf"(%s * %s * %s * %s)"(ocaml_of_ta)(ocaml_of_tb)(ocaml_of_tc)(ocaml_of_td)|Struct{fields;_}->letfields=List.map(function|BoxedFieldf->Printf.sprintf"%s: %s;"f.fname(ocaml_of_tf.field))fieldsinPrintf.sprintf"{ %s }"(String.concat" "fields)|Variant{variants;_}->lettags=List.map(function|BoxedTagt->Printf.sprintf"| %s (%s) (** %s *)"t.tname(ocaml_of_tt.tcontents)(String.concat" "t.tdescription))variantsinString.concat" "tags|Abstract_->"<abstract>"