dirtree
Types
The basic type encoding a directory tree.
A diretory tree either consists of a path to a file, possibly non-simple, or of a path to a recursively given list of DirTree.
Note that a filepath name should be nonempty, but a dirpath, as a relative path from the current working directory, may be empty.
Examples
Filepath("examples/pngs/logo.png")Dirpath("../src", [])Dirpath("", [])Dirpath("examples", [Filepath("pngs/logo.png")])
pub type DirTree {
Filepath(name: String)
Dirpath(name: String, contents: List(DirTree))
}
Constructors
-
Filepath(name: String) -
Dirpath(name: String, contents: List(DirTree))
Values
pub fn collapse(tree: DirTree) -> DirTree
Concatenates names of directories containing a single child with that of their child.
Examples
Dirpath("a", [Dirpath("b", [Filepath("foo.png")])])
|> collapse
// -> Filepath("a/b/foo.png")
pub fn expand(tree: DirTree) -> DirTree
Expands compound filepaths and dirpaths into nested sequences of atomic directories.
Examples
Dirpath("a/b/c", [Filepath("z")])
|> expand
// ->
//
// Dirpath("a", [Dirpath("b", [Dirpath("c", [Filepath("z")])])])
pub fn files(tree: DirTree) -> List(String)
Returns a list of files in the DirTree in the same order as they appear in the tree.
pub fn filter(
tree: DirTree,
condition: fn(DirTree) -> Bool,
) -> Result(DirTree, Nil)
Recursively filters a DirTree using a boolean condition
applied in depth-first fashion,
Returns an Error(Nil) if the root of the tree is filtered
out.
Does not filter out empty directories. See also prune
and prune_and_filter.
pub fn filter_and_prune(
tree: DirTree,
condition: fn(DirTree) -> Bool,
) -> Result(DirTree, Nil)
Recursively filters a DirTree using a boolean condition
applied in depth-first fashion while removing empty directories
as well.
Returns an Error(Nil) if the root of the root resolves to an
empty directory or to a filepath that does not meet the condition.
pub fn flat_map(
tree: DirTree,
m: fn(DirTree) -> List(DirTree),
) -> List(DirTree)
Recursively map a DirTree using a 1-to-many transform.
Maps children before parents.
pub fn from_terminals(
dirpath: String,
terminals: List(String),
) -> DirTree
A function that constructs a DirTree from a path to a
directory, forming the dirpath, and a list of relative paths
from within that directory to either files or empty directories,
i.e., to the “terminal elements” of the directory tree. Terminals
that end in / are interpreted as empty directories, others are
interpreted as filepaths. The given set of terminals should be
prefix-free, but the order of terminals is arbitrary and will
be ignored.
In particular, intermediate directories contained within the paths of other terminals should NOT be listed separately, lest they be confused with files or empty directories!
Examples
let tree = dirtree.from_terminals(
"../examples",
[
"futuristic/pngs/png2.png",
"futuristic/svgs/svg2.png",
"futuristic/svgs/svg1.png",
"notes/README.md",
"futuristic/pngs/png1.png",
"empty-directory/",
],
)
tree
|> dt.pretty_print(1)
|> string.join("\n")
|> io.println
// ->
//
// ../examples
// ├─ empty-directory
// ├─ futuristic
// │ ├─ pngs
// │ │ ├─ png1.png
// │ │ └─ png2.png
// │ └─ svgs
// │ ├─ svg1.png
// │ └─ svg2.png
// └─ notes
// ├─ README.md
// └─ old-README.md
pub fn map(tree: DirTree, m: fn(DirTree) -> DirTree) -> DirTree
Recursively map a DirTree using a 1-to-1 transform. Maps children before parents.
pub fn pretty_print(
tree: DirTree,
indentation: Int,
) -> List(String)
Pretty-print a DirTree using a given level of indentation.
The result is given as a List(String) to allow a possible
consumer to more easily add extra margin or embed the tree
in a larger ASCII graphic.
Examples
let tree = dt.from_terminals(
"/",
[
"futuristic/pngs/png1.png",
"futuristic/svgs/svg1.png",
"empty-directory/",
"notes/README.md",
"futuristic/pngs/png2.png",
"notes/old-README.md",
"futuristic/svgs/svg2.png",
]
)
tree
|> dt.sort(my_sort)
|> dt.pretty_print(10)
|> string.join("\n")
|> io.println
// ->
//
// /
// ├────────── empty-directory
// ├────────── futuristic
// │ ├────────── pngs
// │ │ ├────────── png1.png
// │ │ └────────── png2.png
// │ └────────── svgs
// │ ├────────── svg1.png
// │ └────────── svg2.png
// └────────── notes
// ├────────── README.md
// └────────── old-README.md
pub fn prune(tree: DirTree) -> Result(DirTree, Nil)
Recursively removes empty directories in depth-first fashion. Returns Error(Nil) if the root resolves to an empty directory.
pub fn sort(
tree: DirTree,
order: fn(DirTree, DirTree) -> order.Order,
) -> DirTree
Sorts a DirTree recursively from a given order
function.
Examples
let tree = dt.from_terminals(
"../examples",
[
"futuristic/pngs/png1.png",
"futuristic/svgs/svg1.png",
"empty-directory/",
".DS_store",
"notes/README.md",
"futuristic/pngs/png2.png",
"notes/old-README.md",
"futuristic/svgs/svg2.png",
".latter",
]
)
// puts dotfiles last instead of first
let my_sort = fn(d1: DirTree, d2: DirTree) -> order.Order {
case d1.name, d2.name {
"." <> _, "." <> _ -> string.compare(d1.name, d2.name)
"." <> _, _ -> order.Gt
_, "." <> _ -> order.Lt
_, _ -> string.compare(d1.name, d2.name)
}
}
tree
|> dt.sort(my_sort)
|> dt.pretty_print(1)
|> string.join("\n")
|> io.println
// ->
//
// ../examples
// ├─ empty-directory
// ├─ futuristic
// │ ├─ pngs
// │ │ ├─ png1.png
// │ │ └─ png2.png
// │ └─ svgs
// │ ├─ svg1.png
// │ └─ svg2.png
// ├─ notes
// │ ├─ README.md
// │ └─ old-README.md
// ├─ .DS_store
// └─ .latter