123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261typehow=[`Parallel|`Sequential|`Max_concurrent_jobsofint]moduleDeferred=structtype'at='aLwt.tincludeMonad.Make(structtype'at='aLwt.tletreturn=Lwt.returnletbindx~f=Lwt.bindxfletmap=`Custom(funm~f->Lwt.mapfm)end)letunit=Lwt.return_unitmoduleResult=structtype('a,'b)t=('a,'b)Result.tLwt.tincludeMonad.Make2(structtype('a,'b)t=('a,'b)Result.tLwt.tletreturnx=Lwt.return(Okx)letbindm~f=Lwt.bindm(function|Okx->fx|Error_asx->Lwt.returnx)letmap=`Custom(funm~f->Lwt.map(function|Okx->Ok(fx)|Error_asx->x)m)end)endmoduleList=structletfoldl~init~f=Lwt_list.fold_left_sfinitlletiter?(how=`Sequential)l~f=matchhowwith|`Sequential->Lwt_list.iter_sfl|`Max_concurrent_jobs_|`Parallel->Lwt_list.iter_pflletmap?(how=`Sequential)l~f=matchhowwith|`Sequential->Lwt_list.map_sfl|`Max_concurrent_jobs_|`Parallel->Lwt_list.map_pflletfilter?(how=`Sequential)l~f=matchhowwith|`Sequential->Lwt_list.filter_sfl|`Max_concurrent_jobs_|`Parallel->Lwt_list.filter_pflendmoduleOr_error=structmoduleList=structletmap?(how=`Sequential)l~f=letmap=matchhowwith|`Sequential->Lwt_list.map_s|`Max_concurrent_jobs_|`Parallel->Lwt_list.map_pinletmoduleM=structexceptionEofError.tlethelper()=map(funx->fx>>|function|Okx->x|Errore->raise(Ee))lendintry(M.helper()>>|funx->Okx)withM.Ee->return(Errore)letiter?(how=`Sequential)l~f=letiter=matchhowwith|`Sequential->Lwt_list.iter_s|`Max_concurrent_jobs_|`Parallel->Lwt_list.iter_pinletmoduleM=structexceptionEofError.tlethelper()=iter(funx->fx>>|function|Ok()->()|Errore->raise(Ee))lendintry(M.helper()>>|fun()->Ok())withM.Ee->return(Errore)endendendletreturn=Deferred.returnlet(>>=)=Deferred.(>>=)let(>>|)=Deferred.(>>|)let(>>=?)=Deferred.Result.(>>=)let(>>|?)=Deferred.Result.(>>|)letfail=Lwt.failletraise=`Use_fail_insteadlettry_withf=Lwt.catch(fun()->f()>>|funx->Okx)(funexn->return(Errorexn))moduleIn_thread=structletrunf=Lwt_preemptive.detachf()endmodulePipe=structmoduleReader=structtype'at='aLwt_stream.tendletreadr=Lwt_stream.getr>>|function|Somex->`Okx|None->`Eofletjunk=Lwt_stream.junkletpeek_deferredr=Lwt_stream.peekr>>|function|Somex->`Okx|None->`Eofletmapr~f=Lwt_stream.mapfrletfoldr~init~f=Lwt_stream.fold_s(funaaccum->faccuma)rinitletiterr~f=Lwt_stream.iter_sfrendmoduleReader=structmoduleRead_result=structtype'at=[`Eof|`Okof'a]endtypet=Lwt_io.input_channelletopen_file?buf_lenfile=letbuffer=Option.mapbuf_len~f:Lwt_bytes.createinLwt_io.open_file?buffer~mode:Lwt_io.inputfileletclose=Lwt_io.closeletwith_file?buf_lenfile~f=letbuffer=Option.mapbuf_len~f:Lwt_bytes.createinLwt_io.with_file?buffer~mode:Lwt_io.inputfilefletread_lineic=Lwt_io.read_line_optic>>|function|Somex->`Okx|None->`Eofletread_allicread_one=Lwt_stream.from(fun()->read_oneic>>=function|`Okx->Lwt.return(Somex)|`Eof->Lwt_io.closeic>>=fun()->Lwt.returnNone)letlinesic=read_allicread_lineletcontentsic=Lwt_io.readic>>=funans->Lwt_io.closeic>>=fun()->returnansletfile_contentsfile=with_filefile~f:Lwt_io.readletfile_linesfile=Lwt_io.lines_of_filefile|>Lwt_stream.to_listendmoduleWriter=structtypet=Lwt_io.output_channelletwith_file?perm?(append=false)file~f=letflags=matchappendwith|true->Caml_unix.([O_WRONLY;O_CREAT;O_APPEND])|false->Caml_unix.([O_WRONLY;O_CREAT;O_TRUNC])inLwt_io.with_file~flags?perm~mode:Lwt_io.outputfilefletwrite=Lwt_io.writeletwrite_char=Lwt_io.write_charletwrite_line=Lwt_io.write_lineend(* module Sys = struct *)(* include Sys *)(* let file_exists x = Lwt_preemptive.detach file_exists x *)(* let is_file ?follow_symlinks x = *)(* Lwt_preemptive.detach (is_file ?follow_symlinks) x *)(* let is_directory ?follow_symlinks x = *)(* Lwt_preemptive.detach (is_directory ?follow_symlinks) x *)(* end *)(* module Unix = struct *)(* type file_perm = Caml_unix.file_perm *)(* Lwt doesn't provide a non-blocking version of getcwd because
presumably it is doesn't block. However, Async does because it
claims it could block. See
https://sympa.inria.fr/sympa/arc/ocsigen/2013-09/msg00003.html.
If we agreed it is non-blocking, then could implement as:
let getcwd () = return (Unix.getcwd())
However, I think Async is right, so I wrap it in Lwt's
detach. *)(* let getcwd () = Lwt_preemptive.detach Caml_unix.getcwd () *)(* let rename ~src ~dst = Lwt_unix.rename src dst *)(* let getpid = Unix.getpid *)(* module Stats = struct *)(* type t = Unix.stats = { *)(* st_dev : int; *)(* st_ino : int; *)(* st_kind : Unix.file_kind; *)(* st_perm : file_perm; *)(* st_nlink : int; *)(* st_uid : int; *)(* st_gid : int; *)(* st_rdev : int; *)(* st_size : int64; *)(* st_atime : float; *)(* st_mtime : float; *)(* st_ctime : float; *)(* } *)(* end *)(* (\** We don't call Lwt_unix's [stat] and [lstat] because they don't *)(* support large file sizes. *\) *)(* let stat x = Lwt_preemptive.detach Unix.stat x *)(* let lstat x = Lwt_preemptive.detach Unix.lstat x *)(* end *)