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
pub fn terminals(tree: DirTree) -> List(String)

Returns a list of paths to terminal elements of a DirTree, these being either files or empty directories.

Empty directories are encoded by strings terminated with a /.

Search Document