/*---------------------------------------------------------------------------
  Copyright 2020-2021, Microsoft Research, Daan Leijen.

  This is free software; you can redistribute it and/or modify it under the
  terms of the Apache License, Version 2.0. A copy of the License can be
  found in the LICENSE file at the root of this distribution.
---------------------------------------------------------------------------*/

/* Directory operations.
*/
module std/os/dirstd/os/dir

import std/os/pathstd/os/path

extern import
  c file "dir-inline.c"

// Recursively list all the entries under a directory.
pub fun list-directory-recursivestd/os/dir/list-directory-recursive: (dir : path, max-depth : ? int) -> <div,fsys> list<path>( dirdir: path : pathstd/os/path/path: V, max-depthmax-depth: ? int : intstd/core/types/int: V = 1000literal: int
dec = 1000
hex16= 0x03E8
bit16= 0b0000001111101000
)result: -> <fsys,div> list<path> : <std/core/types/total: Efsysstd/core/fsys: X,divstd/core/types/div: X> liststd/core/types/list: V -> V<pathstd/os/path/path: V> if max-depthmax-depth: int <std/core/int/(<): (x : int, y : int) -> <div,fsys> bool 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
returnreturn: list<path> [std/core/types/Nil: forall<a> list<a>]std/core/types/Nil: forall<a> list<a> val allall: list<path> = list-directorystd/os/dir/list-directory: (dir : path) -> <fsys,div> list<path>(dirdir: path) val dirsdirs: list<path> = allall: list<path>.filterstd/core/list/filter: (xs : list<path>, pred : (path) -> <fsys,div> bool) -> <fsys,div> list<path>(is-directorystd/os/dir/is-directory: (dir : path) -> <fsys,div> bool) allall: list<path> ++std/core/list/(++): (xs : list<path>, ys : list<path>) -> <div,fsys> list<path> dirsdirs: list<path>.flatmapstd/core/list/flatmap: (xs : list<path>, f : (path) -> <div,fsys> list<path>) -> <div,fsys> list<path>(fnfn: (sub : path) -> <div,fsys> list<path>(subsub: path){ list-directory-recursivestd/os/dir/list-directory-recursive: (dir : path, max-depth : ? int) -> <div,fsys> list<path>(subsub: path,(max-depthmax-depth: int -std/core/int/(-): (x : int, y : int) -> <div,fsys> int 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
)) }
) pub fun copy-directorystd/os/dir/copy-directory: (dir : path, to : path) -> <pure,fsys> ()( dirdir: path : pathstd/os/path/path: V, toto: path : pathstd/os/path/path: V )result: -> <fsys,pure> () : <std/core/types/total: Efsysstd/core/fsys: X,purestd/core/pure: E> (std/core/types/unit: V)std/core/types/unit: V ensure-dirstd/os/dir/ensure-dir: (dir : path) -> <exn,fsys,div> ()(toto: path) val allall: list<path> = list-directorystd/os/dir/list-directory: (dir : path) -> <fsys,div,exn> list<path>(dirdir: path) val (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)dirsdirs: list<path>,filesfiles: list<path>)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) = allall: list<path>.partitionstd/core/list/partition: (xs : list<path>, pred : (path) -> <fsys,div,exn> bool) -> <fsys,div,exn> (list<path>, list<path>)(is-directorystd/os/dir/is-directory: (dir : path) -> <fsys,div,exn> bool) filesfiles: list<path>.foreachstd/core/list/foreach: (xs : list<path>, action : (path) -> <exn,fsys,div> ()) -> <exn,fsys,div> ()( fnfn: (f : path) -> <exn,fsys,div> ()(ff: path){ copy-filestd/os/dir/copy-file: (from : path, to : path, preserve-mtime : ? bool) -> <exn,fsys,div> ()( ff: path, toto: path /std/os/path/(/): (p1 : path, p2 : path) -> <exn,fsys,div> path ff: path.nodirstd/os/path/nodir: (p : path) -> <exn,fsys,div> path ) } ) dirsdirs: list<path>.foreachstd/core/list/foreach: (xs : list<path>, action : (path) -> <div,exn,fsys> ()) -> <div,exn,fsys> ()( fnfn: (d : path) -> <div,exn,fsys> ()(dd: path){ copy-directorystd/os/dir/copy-directory: (dir : path, to : path) -> <div,exn,fsys> ()( dd: path, toto: path /std/os/path/(/): (p1 : path, p2 : path) -> <div,exn,fsys> path dd: path.nodirstd/os/path/nodir: (p : path) -> <div,exn,fsys> path ) } ) // Ensure a directory path exists pub fun ensure-dirstd/os/dir/ensure-dir: (dir : path) -> <exn,fsys> ()( dirdir: path : pathstd/os/path/path: V )result: -> <exn,fsys> () : <std/core/types/total: Efsysstd/core/fsys: X,exnstd/core/exn/exn: (E, V) -> V> (std/core/types/unit: V)std/core/types/unit: V match ensure-dir-errstd/os/dir/ensure-dir-err: (path : string, mode : int) -> <fsys,exn> error<()>(dirdir: path.stringstd/os/path/string: (p : path) -> <fsys,exn> string, -1literal: int
dec = -1
hex8 = 0xFF
bit8 = 0b11111111
) Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a>(exnexn: exception) -> throw-exnstd/core/exn/throw-exn: (exn : exception) -> <exn,fsys> ()(exnexn: exception.prependstd/os/dir/prepend: (exn : exception, pre : string) -> <exn,fsys> exception("unable to create directory "literal: string
count= 27
++std/core/types/(++): (x : string, y : string) -> <exn,fsys> string dirdir: path.showstd/os/path/show: (p : path) -> <exn,fsys> string)) Okstd/core/exn/Ok: forall<a> (result : a) -> error<a> -> (std/core/types/Unit: ()
)std/core/types/Unit: () // List directory contents (excluding `.` and `..`). // Returns a list of full paths (not just the names in the directory). pub fun list-directorystd/os/dir/list-directory: (dir : path) -> fsys list<path>( dirdir: path : pathstd/os/path/path: V )result: -> fsys list<path> : fsysstd/core/fsys: X liststd/core/types/list: V -> V<pathstd/os/path/path: V> match prim-list-dirstd/os/dir/prim-list-dir: (dir : string) -> fsys error<vector<string>>(dirdir: path.stringstd/os/path/string: (p : path) -> fsys string) Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a>() -> [std/core/types/Nil: forall<a> list<a>]std/core/types/Nil: forall<a> list<a> Okstd/core/exn/Ok: forall<a> (result : a) -> error<a>(contentscontents: vector<string>) -> contentscontents: vector<string>.liststd/core/vector/list: (v : vector<string>) -> fsys list<string>.mapstd/core/list/map: (xs : list<string>, f : (string) -> fsys path) -> fsys list<path>(fnfn: (name : string) -> fsys path(namename: string){ dirdir: path /std/os/path/(/): (p1 : path, p2 : path) -> fsys path namename: string.pathstd/os/path/path: (s : string) -> fsys path }) // Is the path a valid directory? pub fun is-directorystd/os/dir/is-directory: (dir : path) -> fsys bool( dirdir: path : pathstd/os/path/path: V )result: -> fsys bool : fsysstd/core/fsys: X boolstd/core/types/bool: V prim-is-dirstd/os/dir/prim-is-dir: (dir : string) -> fsys bool(dirdir: path.stringstd/os/path/string: (p : path) -> fsys string) // Is the path a valid file? pub fun is-filestd/os/dir/is-file: (path : path) -> fsys bool( pathpath: path : pathstd/os/path/path: V )result: -> fsys bool : fsysstd/core/fsys: X boolstd/core/types/bool: V prim-is-filestd/os/dir/prim-is-file: (path : string) -> fsys bool(pathpath: path.stringstd/os/path/string: (p : path) -> fsys string) // Copy a file to a directory pub fun copy-file-to-dirstd/os/dir/copy-file-to-dir: (from : path, dir : path) -> <exn,fsys> ()( fromfrom: path : pathstd/os/path/path: V, dirdir: path : pathstd/os/path/path: V )result: -> <exn,fsys> () : <std/core/types/total: Efsysstd/core/fsys: X,exnstd/core/exn/exn: (E, V) -> V> (std/core/types/unit: V)std/core/types/unit: V copy-filestd/os/dir/copy-file: (from : path, to : path, preserve-mtime : ? bool) -> <exn,fsys> ()(fromfrom: path, dirdir: path /std/os/path/(/): (p1 : path, p2 : path) -> <exn,fsys> path fromfrom: path.nodirstd/os/path/nodir: (p : path) -> <exn,fsys> path) // Copy a file. pub fun copy-filestd/os/dir/copy-file: (from : path, to : path, preserve-mtime : ? bool) -> <exn,fsys> ()( fromfrom: path : pathstd/os/path/path: V, toto: path : pathstd/os/path/path: V, preserve-mtimepreserve-mtime: ? bool : boolstd/core/types/bool: V = Truestd/core/types/True: bool )result: -> <exn,fsys> () : <std/core/types/total: Efsysstd/core/fsys: X,exnstd/core/exn/exn: (E, V) -> V> (std/core/types/unit: V)std/core/types/unit: V match prim-copy-filestd/os/dir/prim-copy-file: (from : string, to : string, preserve-mtime : bool) -> <fsys,exn> error<()>(fromfrom: path.stringstd/os/path/string: (p : path) -> <fsys,exn> string, toto: path.stringstd/os/path/string: (p : path) -> <fsys,exn> string, preserve-mtimepreserve-mtime: bool ) Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a>(exnexn: exception) -> throw-exnstd/core/exn/throw-exn: (exn : exception) -> <exn,fsys> ()(exnexn: exception.prependstd/os/dir/prepend: (exn : exception, pre : string) -> <exn,fsys> exception("unable to copy "literal: string
count= 15
++std/core/types/(++): (x : string, y : string) -> <exn,fsys> string fromfrom: path.showstd/os/path/show: (p : path) -> <exn,fsys> string ++std/core/types/(++): (x : string, y : string) -> <exn,fsys> string " to "literal: string
count= 4
++std/core/types/(++): (x : string, y : string) -> <exn,fsys> string toto: path.showstd/os/path/show: (p : path) -> <exn,fsys> string)) _ -> (std/core/types/Unit: ()
)std/core/types/Unit: () fun prependstd/os/dir/prepend: (exn : exception, pre : string) -> exception( exnexn: exception : exceptionstd/core/exn/exception: V, prepre: string : stringstd/core/types/string: V )result: -> total exception : exceptionstd/core/exn/exception: V Exceptionstd/core/exn/Exception: (message : string, info : exception-info) -> exception(prepre: string ++std/core/types/(++): (x : string, y : string) -> string ": "literal: string
count= 2
++std/core/types/(++): (x : string, y : string) -> string exnexn: exception.messagestd/core/exn/exception/message: (exception : exception) -> string, exnexn: exception.infostd/core/exn/exception/info: (exception : exception) -> exception-info
) extern ensure-dir-errstd/os/dir/ensure-dir-err: (path : string, mode : int) -> fsys error<()>( pathpath: string : stringstd/core/types/string: V, modemode: int : intstd/core/types/int: V ) : fsysstd/core/fsys: X errorstd/core/exn/error: V -> V<(std/core/types/unit: V)std/core/types/unit: V> c "kk_os_ensure_dir_error" extern prim-copy-filestd/os/dir/prim-copy-file: (from : string, to : string, preserve-mtime : bool) -> fsys error<()>( fromfrom: string : stringstd/core/types/string: V, toto: string : stringstd/core/types/string: V, preserve-mtimepreserve-mtime: bool : boolstd/core/types/bool: V ) : fsysstd/core/fsys: X errorstd/core/exn/error: V -> V<(std/core/types/unit: V)std/core/types/unit: V> c "kk_os_copy_file_error" extern prim-list-dirstd/os/dir/prim-list-dir: (dir : string) -> fsys error<vector<string>>( dirdir: string : stringstd/core/types/string: V ) : fsysstd/core/fsys: X errorstd/core/exn/error: V -> V<vectorstd/core/types/vector: V -> V<stringstd/core/types/string: V>> c "kk_os_list_directory_prim" extern prim-is-dirstd/os/dir/prim-is-dir: (dir : string) -> fsys bool( dirdir: string : stringstd/core/types/string: V ) : fsysstd/core/fsys: X boolstd/core/types/bool: V c "kk_os_is_directory" extern prim-is-filestd/os/dir/prim-is-file: (path : string) -> fsys bool( pathpath: string : stringstd/core/types/string: V ) : fsysstd/core/fsys: X boolstd/core/types/bool: V c "kk_os_is_file"