123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382openPrintfopenUtilletdefaultz=function|Somex->x|None->zmoduleStringSet=Set.Make(structtypet=stringletcompare=compareend)(* Unused types. *)[@@@ocaml.warning"-34"]typeparameter_or_reference=[`ParameterofSwagger_j.parameter|`ReferenceofSwagger_j.reference]typeresponse_or_reference=[`ResponseofSwagger_j.response|`ReferenceofSwagger_j.reference][@@@end]letmerge_params(ps1:Swagger_j.parameterlist)(ps2:Swagger_j.parameterlist)=letrecmergeacc=function|[]->acc|(p:Swagger_j.parameter)::ps->letsame_name(q:Swagger_j.parameter)=letopenSwagger_jinp.name=q.nameinifList.existssame_nameaccthenmergeaccpselsemerge(p::acc)psinmergeps2ps1letreference_module_and_type~reference_base~reference_rootr=letref_module=Mod.reference_module~reference_base~reference_rootrinletref_type=sprintf"%s.t"ref_modulein(Someref_module,ref_type)letparse_or_referencefjson=letopenYojson.Basic.Utilinletstr=Yojson.Safe.to_stringjsoninmatchjson|>Yojson.Safe.to_basic|>member"$ref"with|`Null->fstr|_->failwith"reference not supported"letparse_parameters=function|Someps->List.map(parse_or_referenceSwagger_j.parameter_of_string)ps|None->[]letparse_responser=parse_or_referenceSwagger_j.response_of_stringrletparse_responses=List.map(fun(s,r)->(s,parse_responser))letresp_type~reference_base~reference_root(resp:Swagger_j.response)=matchresp.schemawith|None->(None,"unit")|Somes->lets=Schema.create~reference_base~reference_rootsinmatchSchema.referenceswith|Somer->reference_module_and_type~reference_base~reference_rootr|None->(None,Schema.to_strings)letrecreturn_type~reference_root~reference_base(resps:Swagger_j.responses)=letis_errorcode=letcode=int_of_stringcodeincode<200||code>=300inletresponses_match(r1:Swagger_j.response)(r2:Swagger_j.response)=r1.schema=r2.schemainmatchrespswith|[]->None,"unit"|(code,_)::rswhenis_errorcode->(* ignore errors; assume strings *)return_type~reference_root~reference_basers|(_code,resp)::rs->(* check all 2xx responses return the same type *)letreccheckfirst=function|[]->()|(code,_)::reswhenis_errorcode->checkfirstres|(_code',resp')::rswhenresponses_matchfirstresp'->checkfirstrs|(_c,(_r:Swagger_j.response))::_->failwith"multiple response types are not supported"inletresp=parse_responserespincheckresp(parse_responsesrs);resp_type~reference_base~reference_rootrespletmake_dupsparams=List.fold_left(fundups(p:Swagger_j.parameter)->matchStringMap.find_optp.namedupswith|Somecount->StringMap.addp.name(count+1)dups|None->StringMap.addp.name1dups)StringMap.emptyparamsletoperation_val~root:_~reference_base~reference_rootname(params:Swagger_j.parameterlist)=function|Some(op:Swagger_j.operation)->letop_params=parse_parametersop.parametersinletparams=merge_paramsparamsop_paramsinletdups=make_dupsparamsinletparam_sigs,param_impls=params|>List.map(fun(p:Swagger_j.parameter)->letduplicate=StringMap.findp.namedups>1inParam.create~duplicate~reference_base~reference_rootp)|>List.splitinletreturn_module,return_type=return_type~reference_root~reference_baseop.responsesinletverb=Val.Impl.http_verb_of_stringnameinletsignature=letdescr=op.descriptioninVal.Sig.http_request?descrnameparam_sigsreturn_typeinletreturn=matchreturn_modulewith|Somemodule_name->Val.Impl.module_module_name|None->Val.Impl.type_return_typeinletimplementation=Val.Impl.http_requestverbnameparam_impls~returninSome(Val.createsignatureimplementation)|None->Noneletpath_valpath=Val.create(Val.Sig.constant"request_path_template")(Val.Impl.constant"request_path_template"path)letpath_item_vals~root~reference_base~reference_root~path(item:Swagger_j.path_item):Val.tlist=letparams=parse_parametersitem.parametersinletoperation_valname=operation_val~root~reference_base~reference_rootnameparamsinletget=operation_val"get"item.getinletput=operation_val"put"item.putinletpost=operation_val"post"item.postinletdelete=operation_val"delete"item.deleteinletoptions=operation_val"options"item.optionsinlethead=operation_val"head"item.headinletpatch=operation_val"patch"item.patchinpath_valpath::keep_some[get;put;post;delete;options;head;patch]letdefinition_module?(path=[])~root~reference_base~name(schema:Swagger_j.schema)=letrequired=default[]schema.requiredinletproperties=default[]schema.propertiesinletcreate_paramnametype_required_params=letn=Param.namenameinifList.memnamerequired_paramsthen(Val.Sig.namedntype_,Val.Impl.namedntype_)else(Val.Sig.optionalntype_,Val.Impl.optionalntype_)inletcreate_params=List.fold_left(funparams(name,schema)->lets=Schema.create~reference_base~reference_root:rootschemainletparam_type=Schema.to_stringsinletparam_sig,param_impl=create_paramnameparam_typerequiredin(param_sig,param_impl)::params)[]inletalias_type()=letparam_type=Schema.kind_to_string(Schema.create~reference_base~reference_root:rootschema)inletint_or_string=matchschema.formatwith|Some"int-or-string"->true|_->falseinlettyp=Type.create(Type.Sig.abstract"t")(Type.Impl.alias"t"param_type~int_or_string)inletcreate=Val.create(Val.Sig.(pure"make"[positionalparam_type]"t"))(Val.Impl.(identity"make"[positional"t""t"]))in([typ],[create])inletrecord_type()=letparams=create_paramspropertiesinletsig_params,impl_params=params|>List.splitinletcreate=Val.create(Val.Sig.pure"make"sig_params"t")(Val.Impl.record_constructor"make"impl_params)inletfields,values=List.fold_left(fun(fields,values)(name,schema)->lets=Schema.create~reference_base~reference_root:rootschemainlets=Schema.to_stringsinletsig_type,impl_type=ifList.memnamerequiredthenlettype_=sprintf"%s"sin(type_,type_)elselettype_=sprintf"%s option"sin(type_,sprintf"(%s [@default None])"type_)inletpname=Param.namenameinletfield=Type.Impl.record_field~name:pname~orig_name:name~type_:impl_typeinletvalue=letdescr=schema.descriptioninVal.create(Val.Sig.pure?descrpname[Val.Sig.positional"t"]sig_type)(Val.Impl.record_accessorpname[Val.Impl.positional"t""t"])in(field::fields,value::values))([],[])propertiesinletvalues=create::List.revvaluesinlettype_sig=Type.Sig.abstract"t"inlettype_impl=Type.Impl.record"t"fieldsinlettyp=Type.createtype_sigtype_implin([typ],values)inletunspec_type()=lettyp=Type.create(Type.Sig.unspecified"t")(Type.Impl.unspecified"t")in([typ],[])inlettypes,values=matchschema.kind,schema.propertieswith|Some_,_->alias_type()|None,Some_->record_type()|None,None->unspec_type()inletdescr=schema.descriptioninMod.create?descr~name~path~types~values()letrecinsert_modulemroot=function|[]->Mod.add_modmroot|p::ps->matchMod.find_submoduleprootwith|Somesubm->Mod.add_mod(insert_modulemsubmps)root|None->letsubm=Mod.emptyp~path:(Mod.qualified_pathroot)()inMod.add_mod(insert_modulemsubmps)root(* Unused values. *)[@@@ocaml.warning"-32"]letremove_basebasesegments=matchbase,segmentswith|Somebase,s::sswhenbase=s->ss|_->segments[@@@end]letrecbuild_paths~root~path_base~reference_base~reference_root=function|[]->root|(path,item)::paths->letparents_and_child=path|>Mod.strip_basepath_base|>String.split_on_char'/'|>List.filter((<>)"")|>unsnocinmatchparents_and_childwith|Some(parents,child)->letchild_values=path_item_vals~root~reference_base~reference_root~pathiteminletchild_module=Mod.with_values~path:parentschildchild_valuesinletroot=insert_modulechild_modulerootparentsinbuild_paths~root~path_base~reference_base~reference_rootpaths|None->letchild_values=path_item_vals~root~reference_base~reference_root~pathiteminletroot=Mod.add_valschild_valuesrootinbuild_paths~root~path_base~reference_base~reference_rootpathsletrecbuild_definitions~root~definition_base~reference_basel=matchlwith|[]->root|(name,(schema:Swagger_j.schema))::defswhenschema.ref=None->letparents_and_child=name|>Mod.strip_basedefinition_base|>Mod.split_ref|>unsnocin(matchparents_and_childwith|Some(parents,child)->letdef=definition_module~root~reference_base~path:parents~name:childschemainletroot=insert_moduledefrootparentsinbuild_definitions~root~definition_base~reference_basedefs|None->letroot=Mod.add_mod(definition_module~root~reference_base~nameschema)rootinbuild_definitions~root~definition_base~reference_basedefs)(* XXX Ignore schemas that are simply references? Just use the referenced
* module? In the kubernetes API this seems to be only for deprecated
* stuff. *)|(_name,(_schema:Swagger_j.schema))::defs->build_definitions~root~definition_base~reference_basedefsletof_swagger?(path_base="")?(definition_base="")?(reference_base="")~reference_roots=letopenSwagger_jinletdefinitions=default[]s.definitionsinlettitle=s.info.titleinletdefs=build_definitions~root:(Mod.emptyreference_root~path:[title]())~definition_base~reference_basedefinitionsinletroot=build_paths~root:(Mod.empty~recursive:truetitle())~path_base~reference_base~reference_root:defss.pathsinMod.add_moddefsrootletobject_module=String.trim{|
module Object = struct
module type Value = sig
type value
val value_of_yojson : Yojson.Safe.json -> (value, string) result
val value_to_yojson : value -> Yojson.Safe.json
end
module type S = sig
type value
type t = (string * value) list [@@deriving yojson]
end
module Make (V : Value) : S with type value := V.value = struct
type t = (string * V.value) list [@@deriving yojson]
let to_yojson obj =
`Assoc (List.map (fun (k, v) -> (k, V.value_to_yojson v)) obj)
let of_yojson (obj : Yojson.Safe.json) : (t, string) result =
let rec loop acc = function
| [] -> Ok (List.rev acc)
| (k, v) :: obj ->
match V.value_of_yojson v with
| Ok v -> loop ((k, v) :: acc) obj
| Error e -> Error ("invalid object:" ^ e) in
match obj with
| `Assoc obj -> loop [] obj
| _ -> Error "invalid object"
end
module Of_strings = Make (struct type value = string [@@deriving yojson] end)
module Of_floats = Make (struct type value = float [@@deriving yojson] end)
module Of_ints = Make (struct type value = int [@@deriving yojson] end)
module Of_bools = Make (struct type value = bool [@@deriving yojson] end)
end
|}letto_stringm=sprintf"%s\n\n%s"object_module(Mod.to_stringm)