+ type 'a t =
+ 'a S.t
+
+ let rec_file_paths ~root =
+ let dirs = Queue.create () in
+ let files = Queue.create () in
+ Queue.add root dirs;
+ let explore parent =
+ Array.iter (Sys.readdir parent) ~f:(fun child ->
+ let path = Filename.concat parent child in
+ let {Unix.st_kind = file_kind; _} = Unix.lstat path in
+ match file_kind with
+ | Unix.S_REG ->
+ Queue.add path files
+ | Unix.S_DIR ->
+ Queue.add path dirs
+ | Unix.S_CHR
+ | Unix.S_BLK
+ | Unix.S_LNK
+ | Unix.S_FIFO
+ | Unix.S_SOCK ->
+ ()
+ )
+ in
+ let next_dir () =
+ match Queue.take dirs with
+ | exception Queue.Empty ->
+ ()
+ | dir ->
+ explore dir
+ in
+ let next_file () =
+ match Queue.take files with
+ | exception Queue.Empty ->
+ None
+ | file_path ->
+ Some file_path
+ in
+ S.from (fun _ ->
+ next_dir ();
+ next_file ()
+ )
+
+ let lines ic =