123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364openBaseopenPpxlibopenAst_builder.Defaultletextension_name="csv"letunsupported_type_error_msg~name=Printf.sprintf"The type %s is not natively supported in the csv camlp4 extension"name;;letuseless_merge_recursive_log~field_name:_~tp:_ast=astletedot~locpath_optid=pexp_ident~loc(Located.mk~loc(matchpath_optwith|None->Longident.Lidentid|Somep->Longident.Ldot(p,id)));;(** Generate the list of fields contained in a flattened record type *)moduleRev_headers=Ppx_conv_func.Of_simple(structletunsupported_type_error_msg=unsupported_type_error_msgletconversion_name=extension_nameletfunction_name=function|None->"rev_csv_header'"|Someparam->Printf.sprintf"rev_csv_header_of_%s'"param;;letatomsloc~field_name=[%exprfunacc_->[%eestring~locfield_name]::acc]letmerge_recursive=useless_merge_recursiveletrecursiveloc~field_name~type_name:_~path=lettns=function_nameNoneinletrecursive=edot~locpathtnsinletis_csv_atom=edot~locpath"is_csv_atom"in[%exprfunacc_->if[%eis_csv_atom]then[%eestring~locfield_name]::accelse[%erecursive]acc()()];;end)(* Generate the specification of the headers as a tree. This is useful to generate headers
consisting of multiple rows, each field grouping those below. *)moduleSpec_of_headers=Ppx_conv_func.Of_simple(structletunsupported_type_error_msg=unsupported_type_error_msgletconversion_name=extension_nameletfunction_name=function|None->"rev_csv_header_spec'"|Someparam->Printf.sprintf"rev_csv_header_spec_of_%s'"param;;letatomsloc~field_name=[%exprfunacc_->Csvfields.Csv.Spec.Leaf[%eestring~locfield_name]::acc];;letmerge_recursive=useless_merge_recursiveletrecursiveloc~field_name~type_name:_~path=lettns=function_nameNoneinletrecursive=edot~locpathtnsinletis_csv_atom=edot~locpath"is_csv_atom"in[%exprfunacc_->if[%eis_csv_atom]thenCsvfields.Csv.Spec.Leaf[%eestring~locfield_name]::accelseCsvfields.Csv.Spec.Tree([%eestring~locfield_name],[%erecursive][]()())::acc];;end)(** Generate the some type using a csv row (a list of strings) *)moduleType_of_csv_row=Ppx_conv_func.Of_complete(structletunsupported_type_error_msg=unsupported_type_error_msgletconversion_name=extension_nameletfunction_name=function|None->failwith"Csv conversion of_row requires some name"|Someparam->Printf.sprintf"%s_of_row'"param;;letunitloc~field_name:_=[%exprCsvfields.Csv.unit_of_row]letboolloc~field_name:_=[%exprCsvfields.Csv.bool_of_row]letstringloc~field_name:_=[%exprCsvfields.Csv.string_of_row]letcharloc~field_name:_=[%exprCsvfields.Csv.char_of_row]letintloc~field_name:_=[%exprCsvfields.Csv.int_of_row]letfloatloc~field_name:_=[%exprCsvfields.Csv.float_of_row]letint32loc~field_name:_=[%exprCsvfields.Csv.int32_of_row]letint64loc~field_name:_=[%exprCsvfields.Csv.int64_of_row]letnativeintloc~field_name:_=[%exprCsvfields.Csv.nativeint_of_row]letbig_intloc~field_name:_=[%exprCsvfields.Csv.big_int_of_row]letnatloc~field_name:_=[%exprCsvfields.Csv.nat_of_row]letnumloc~field_name:_=[%exprCsvfields.Csv.num_of_row]letratioloc~field_name:_=[%exprCsvfields.Csv.ratio_of_row]letlistloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"list"letarrayloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"list"letoptionloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"option"letlazy_tloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"lazy_t"letrefloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"ref"letmerge_recursive=useless_merge_recursiveletrecursiveloc~field_name:_~type_name~path=lettns=function_name(Sometype_name)inedot~locpathtns;;end)moduletypeB=sigvalwriter:Location.t->arg_label*expressionvalis_first:Location.t->arg_label*expressionvalis_last:Location.t->arg_label*expressionendmoduleMake_row_of(S:B)=structletunsupported_type_error_msg=unsupported_type_error_msgletconversion_name=extension_nameletfunction_name=function|None->failwith"Csv conversion write_row_of_ requires some name"|Someparam->Printf.sprintf"write_row_of_%s'"param;;letadd_argumentsexprloc=pexp_apply~locexpr[S.is_firstloc;S.is_lastloc;S.writerloc];;letunitloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_unit]locletboolloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_bool]locletstringloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_string]locletcharloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_char]locletintloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_int]locletfloatloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_float]locletint32loc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_int32]locletint64loc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_int64]locletnativeintloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_nativeint]loc;;letbig_intloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_big_int]locletnatloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_nat]locletnumloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_num]locletratioloc~field_name:_=add_arguments[%exprCsvfields.Csv.row_of_ratio]locletmerge_recursive=useless_merge_recursiveletrecursiveloc~field_name:_~type_name~path=lettns=function_name(Sometype_name)inadd_arguments(edot~locpathtns)loc;;letlistloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"list"letarrayloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"array"letoptionloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"option"letlazy_tloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"lazy_t"letrefloc~field_name:_=Ppx_conv_func.raise_unsupported~loc"ref"endletfalseexprloc=[%exprfalse]moduleUnique_row_of=Ppx_conv_func.Of_complete(Make_row_of(structletwriterloc=Labelled"writer",[%exprwriter]letis_firstloc=Labelled"is_first",[%expris_first]letis_lastloc=Labelled"is_last",[%expris_last]end))moduleFirst_row_of=Ppx_conv_func.Of_complete(Make_row_of(structletwriterloc=Labelled"writer",[%exprwriter]letis_firstloc=Labelled"is_first",[%expris_first]letis_lastloc=Labelled"is_last",falseexprlocend))moduleMiddle_row_of=Ppx_conv_func.Of_complete(Make_row_of(structletwriterloc=Labelled"writer",[%exprwriter]letis_firstloc=Labelled"is_first",falseexprlocletis_lastloc=Labelled"is_last",falseexprlocend))moduleLast_row_of=Ppx_conv_func.Of_complete(Make_row_of(structletwriterloc=Labelled"writer",[%exprwriter]letis_firstloc=Labelled"is_first",falseexprlocletis_lastloc=Labelled"is_last",[%expris_last]end))letcsv_record_sigloc~record_name=letst=psig_include~loc(include_infos~loc(pmty_with~loc(pmty_ident~loc(Located.lident~loc"Csvfields.Csv.Csvable"))[Pwith_typesubst(Located.lident~loc"t",type_declaration~loc~name:(Located.mk~loc"t")~params:[]~manifest:(Some(ptyp_constr~loc(Located.lident~locrecord_name)[]))~cstrs:[]~kind:Ptype_abstract~private_:Public)]))in[st];;letrev_csv_header'~record_name~ldsloc=letname=[%pat?rev_csv_header']inletconversion_of_type=Rev_headers.conversion_of_typeinPpx_conv_func.Gen_struct.generate_using_fold~record_name~pass_acc:true~pass_anonymous:true~conversion_of_type~name~ldsloc;;letrev_csv_header_spec'~record_name~ldsloc=letname=[%pat?rev_csv_header_spec']inletconversion_of_type=Spec_of_headers.conversion_of_typeinPpx_conv_func.Gen_struct.generate_using_fold~record_name~pass_acc:true~pass_anonymous:true~conversion_of_type~name~ldsloc;;letfields_module~record_name~loc~suffix=Ast_helper.Exp.ident{loc;txt=Longident.parse(Printf.sprintf"%s.%s"(matchString.equalrecord_name"t"with|true->"Fields"|false->Printf.sprintf"Fields_of_%s"record_name)suffix)};;letrow_of_t'~record_name~ldsloc=letinit=[%expr[%efields_module~record_name~loc~suffix:"Direct.iter"]t]inletbody=Ppx_conv_func.Gen_struct.make_body~lds~initloc~unique_f:Unique_row_of.conversion_of_type~first_f:First_row_of.conversion_of_type~last_f:Last_row_of.conversion_of_typeMiddle_row_of.conversion_of_typeinletanonymous=Ppx_conv_func.Gen_struct.anonymouslocinletfunc=[%exprfun~is_first~is_last~writer[%panonymous][%panonymous]t->[%ebody]]in[%striletwrite_row_of_t'=[%efunc]];;lett_of_row'~record_name~ldsloc=letinit=[%expr[%efields_module~record_name~loc~suffix:"make_creator"]strings]inletbody=letf=Type_of_csv_row.conversion_of_typeinPpx_conv_func.Gen_struct.make_body~lds~initlocfinletfunc=Ppx_conv_func.lambdaloc[Ppx_conv_func.Gen_struct.anonymousloc;[%pat?strings]]bodyin[%strilett_of_row'=[%efunc]];;letcsv_record~tps:_~record_nameloclds=lett_of_row'=t_of_row'~record_name~ldslocinletis_csv_atom=[%striletis_csv_atom=false]inletrow_of_t'=row_of_t'~record_name~ldslocinletrev_csv_header'=rev_csv_header'~record_name~ldslocinletrev_csv_header_spec'=rev_csv_header_spec'~record_name~ldslocinlett=ifString.(<>)record_name"t"then[%strtypet=[%tptyp_constr~loc(Located.lident~locrecord_name)[]]]else[%strtype_t=ttypet=_t]inletwith_constraints=[Pwith_typesubst(Located.lident~loc"t",type_declaration~loc~name:(Located.mk~loc"t")~manifest:(Some(ptyp_constr~loc(Located.lident~locrecord_name)[]))~kind:Ptype_abstract~private_:Public~params:[]~cstrs:[])]inletapplied_functor=pmod_apply~loc(pmod_ident~loc(Located.lident~loc"Csvfields.Csv.Record"))(pmod_structure~loc(t@[is_csv_atom;rev_csv_header';rev_csv_header_spec';t_of_row';row_of_t']))inletst=pstr_include~loc(include_infos~loc(pmod_constraint~locapplied_functor(pmty_with~loc(pmty_ident~loc(Located.lident~loc"Csvfields.Csv.Csvable"))with_constraints)))in[st;[%strilet[%ppvar~loc(record_name^"_of_row")]=t_of_row];[%strilet[%ppvar~loc("row_of_"^record_name)]=row_of_t];[%strilet[%ppvar~loc(record_name^"_of_row'")]=t_of_row'];[%strilet[%ppvar~loc("write_row_of_"^record_name^"'")]=write_row_of_t']];;letcsv=letstr_type_decl=Deriving.Generator.makeDeriving.Args.empty(Ppx_conv_func.Gen_struct.generate~extension_name~record:csv_record)~deps:[Ppx_fields_conv.fields]inletsig_type_decl=Deriving.Generator.makeDeriving.Args.empty(Ppx_conv_func.Gen_sig.generate~extension_name~nil:(fun~tps:_~record_nameloc->csv_record_sigloc~record_name)~record:(fun~tps:_~record_nameloc_->csv_record_sigloc~record_name))inDeriving.addextension_name~str_type_decl~sig_type_decl;;