Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file csv.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345open!CoremoduleHelper=structletprepend_nameaccfield=(Field.namefield)::accletaddxacc_field=x+acc(*let separator = ","
let newline = "\n"*)letwrite~is_first:_~is_last:_~writer~to_string__field=writer(to_stringfield);endmoduletypeStringable=sigtypetvalto_string:t->stringvalof_string:string->tendmoduleSpec=structexceptionIllegal_csv_filetypet=Leafofstring|Treeof(string*tlist)letrecdepth(t:t)=matchtwith|Leaf_->1|Tree(_,children)->List.fold_left~f:(funaccchild->maxacc((depthchild)+1))~init:0childrenletdeptht=(List.fold_left~f:(funacct->maxacc(deptht))~init:0t)letrecmatches'(parent_rows,current_header,children_rows)(t:t)=matcht,current_headerwith|(Tree_|Leaf_),[]->raiseIllegal_csv_file|Leafspec_title,(real_title::rest_of_header)->ifreal_title<>spec_titlethenraiseIllegal_csv_fileelseList.map~f:List.tl_exnparent_rows,rest_of_header,List.map~f:List.tl_exnchildren_rows|(Tree(spec_title,children)),(real_title::_)->ifspec_title=real_titlethenmatchchildren_rowswith|[]->raiseIllegal_csv_file|h::children_rows->letinit=(current_header::parent_rows),h,children_rowsinletparent_rows,current_header,children_rows=List.fold_left~f:matches'~initchildreninmatchparent_rowswith|h::parent_rows->parent_rows,h,(current_header::children_rows)|[]->raiseIllegal_csv_fileelseraiseIllegal_csv_fileletmatchesheader_of_csvt=matchheader_of_csvwith|[]->raiseIllegal_csv_file|current_header::children_rows->letinit=([],current_header,children_rows)intry([],[],[])=List.fold_left~f:matches'~inittwith|_exn->falseletcheck~csv~header:t~f=letdepth=depthtinletrecauxdepthacccsv=ifdepth=0thenifmatches(List.revacc)tthenfcsvelseraiseIllegal_csv_fileelsematchcsvwith|h::csv->aux(depth-1)(h::acc)csv|[]->raiseIllegal_csv_fileinauxdepth[]csvletprependresultdepthheaders=letlen=Array.lengthresultinfori=len-1downto0doletto_prepend=ifi>depth||Stack.is_emptyheadersthen""elseStack.pop_exnheadersinresult.(i)<-to_prepend::result.(i);doneletstr_to_human_readablestr=letstr=String.mapstr~f:(function|'_'->' '|c->c)inString.capitalizestrletrecheader_of_t~depth~result~parentst=matchtwith|Leafstr->letstr=str_to_human_readablestrinStack.pushparentsstr;prependresultdepthparents|Tree(str,children)->letstr=str_to_human_readablestrinletdepth=depth+1inStack.pushparentsstr;header_of_list~depth~result~parentschildrenandheader_of_list~depth~result~parentslst=matchlstwith|[]->assertfalse|h::t->List.iter~f:(funx->header_of_t~depth~result~parents:(Stack.create())x)(List.revt);header_of_t~depth~result~parentshletheaderlst=letdepth=depthlstinletresult=Array.create~len:depth[]inheader_of_list~depth:0~result~parents:(Stack.create())lst;Array.to_listresultendmoduletypeCsvable_simple=sigtypetvalis_csv_atom:boolvalrev_csv_header':stringlist->_->_->stringlistvalrev_csv_header_spec':Spec.tlist->_->_->Spec.tlistvalt_of_row':_->stringlist->(unit->t)*(stringlist)valwrite_row_of_t':is_first:bool->is_last:bool->writer:(string->unit)->_->_->t->unitendmoduletypeCsvable=sigincludeCsvable_simplevalcsv_header:stringlistvalcsv_header_spec:Spec.tlistvalt_of_row:stringlist->tvalrow_of_t:t->stringlistvalcsv_load:?separator:char->string->tlistvalcsv_load_in:?separator:char->In_channel.t->tlistvalcsv_save_fn:?separator:char->(string->unit)->tlist->unitvalcsv_save_out:?separator:char->Out_channel.t->tlist->unitvalcsv_save:?separator:char->string->tlist->unitendexceptionExcess_of_elements_in_rowofstringlistmoduleRecord(S:Csvable_simple):Csvablewithtypet=S.t=structincludeSletrev_csv_header'reverse_headers__=ifS.is_csv_atomthenreverse_headerselseS.rev_csv_header'reverse_headers()()letrev_csv_header_spec'specs__=ifS.is_csv_atomthenspecselseS.rev_csv_header_spec'specs()()letcsv_header=List.rev(rev_csv_header'[]()())letrecaux_csv_header_spec(t:Spec.t)=matchtwith|Spec.Leaf_->t|Spec.Tree(name,children)->Spec.Tree(name,aux_csv_header_spec'children)andaux_csv_header_spec'lst=List.rev_map~f:aux_csv_header_speclstletcsv_header_spec=aux_csv_header_spec'(rev_csv_header_spec'[]()())letof_list_without_tailauxstrings=matchaux()stringswith|f,[]->f()|_,lst->raise(Excess_of_elements_in_rowlst)lett_of_rowstrings=of_list_without_tailS.t_of_row'strings(* This is not being used anymore really *)(*let write_row_of_t ~writer csvable =
S.write_row_of_t' ~is_first:true ~is_last:true ~writer () () csvable*)letrow_of_tcsvable=letlist=ref[]inletwriterstr=list:=str::!listinS.write_row_of_t'~is_first:true~is_last:true~writer()()csvable;List.rev!listletcsv_save_fn?separatorwritercsvable=Csvlib.Csv.save_fn?separatorwriter(List.map~f:row_of_tcsvable)letcsv_save_out?separatorchannelcsvable=Csvlib.Csv.save_out?separatorchannel(List.map~f:row_of_tcsvable)letcsv_save?separatorchannelcsvable=Csvlib.Csv.save?separatorchannel(List.map~f:row_of_tcsvable)letcsv_load_in?separatorchannel=letlist=Csvlib.Csv.load_in?separatorchannelinList.map~f:t_of_rowlistletcsv_load?separatorfile=letlist=Csvlib.Csv.load?separatorfileinList.map~f:t_of_rowlistendexceptionIncomplete_rowmoduleMake_csvable_simple(S:Stringable):Csvable_simplewithtypet=S.t=structtypet=S.tletis_csv_atom=trueletrev_csv_header'acc__=accletrev_csv_header_spec'acc__=acclett_of_row'_strings=matchstringswith|[]->raiseIncomplete_row|value::csvable->(fun()->S.of_stringvalue),csvableletwrite_row_of_t'~is_first~is_last~writer__csvable=Helper.write~is_first~is_last~writer~to_string:S.to_string()()csvableendmoduleAtom(S:Stringable):Csvablewithtypet=S.t=Record(Make_csvable_simple(S))letuse_headflst=matchlstwith|[]->raiseIncomplete_row|h::t->(fun_->(fh)),texceptionIllegal_atomofstring(** All the conversion functions *)letunit_of_row_strings=use_head(funstring->ifstring=""then()elseraise(Illegal_atomstring))stringsletbool_of_row_strings=use_head(funh->leth=String.uppercasehinh="TRUE")stringsletstring_of_row_strings=use_head(funh->h)stringsletchar_of_row_strings=use_head(funstring->if(String.lengthstring)=1thenString.getstring0elseraise(Illegal_atomstring))stringsletint_of_row_strings=use_headint_of_stringstringsletfloat_of_row_strings=use_headfloat_of_stringstringsletint32_of_row_strings=use_headInt32.of_stringstringsletint64_of_row_strings=use_headInt64.of_stringstringsletnativeint_of_row_strings=use_headNativeint.of_stringstringsletbig_int_of_row_strings=use_headBig_int.big_int_of_stringstringsletnat_of_row_strings=use_headNat.nat_of_stringstringsletnum_of_row_strings=use_headNum.num_of_stringstringsletratio_of_row_strings=use_headRatio.ratio_of_stringstringstype('a,'b,'c)row_of=is_first:bool->is_last:bool->writer:(string->unit)->'b->'c->'a->unitletwriteis_firstis_lastwriterto_stringt=Helper.write~is_first~is_last~writer~to_string()()tletrow_of_unit~is_first~is_last~writer__t=letf()=""inwriteis_firstis_lastwriterftletrow_of_bool~is_first~is_last~writer__t=letfbool=ifboolthen"true"else"false"inwriteis_firstis_lastwriterftletrow_of_string~is_first~is_last~writer__t=letfstring=stringinwriteis_firstis_lastwriterftletrow_of_char~is_first~is_last~writer__t=letfchar=String.make1charinwriteis_firstis_lastwriterftletrow_of_int~is_first~is_last~writer__t=writeis_firstis_lastwriterstring_of_inttletrow_of_float~is_first~is_last~writer__t=writeis_firstis_lastwriterstring_of_floattletrow_of_int32~is_first~is_last~writer__t=writeis_firstis_lastwriterInt32.to_stringtletrow_of_int64~is_first~is_last~writer__t=writeis_firstis_lastwriterInt64.to_stringtletrow_of_nativeint~is_first~is_last~writer__t=writeis_firstis_lastwriterNativeint.to_stringtletrow_of_big_int~is_first~is_last~writer__t=writeis_firstis_lastwriterBig_int.string_of_big_inttletrow_of_nat~is_first~is_last~writer__t=writeis_firstis_lastwriterNat.string_of_nattletrow_of_num~is_first~is_last~writer__t=writeis_firstis_lastwriterNum.string_of_numtletrow_of_ratio~is_first~is_last~writer__t=writeis_firstis_lastwriterRatio.string_of_ratiot