Rill v0.13 Reference

Standard library · Text

text/path

Imported as import "text/path" as path, its names are then path.…. Every signature below is the one the checker infers.

File paths as text: joining, taking apart, tidying. Bytes, / between the parts, no touching the file system — a path here is a string with a shape, and what is at it is the program's business.

The prelude's dir_of reads a directory; this never does.

path.join_path("etc", "rill/conf.yaml")     # => etc/rill/conf.yaml
path.dir_name("/a/b/c.rill")                 # => /a/b
path.base_name("/a/b/c.rill")                # => c.rill
path.extension("archive.tar.gz")             # => gz
path.stem("archive.tar.gz")                  # => archive.tar
path.normalize("a/./b/../c//d/")             # => a/c/d
path.with_extension("notes.md", "html")      # => notes.html

Functions

fn is_absolute(p: Str) -> Bool

path.is_absolute("/etc")   # => true
path.is_absolute("etc")    # => false

fn join_path(a: Str, b: Str) -> Str

a/b, with one separator between however the two were written; an absolute b is the answer on its own, as it would be at a shell.

path.join_path("a/", "/b")   # => /b
path.join_path("a/", "b")    # => a/b

fn dir_name(p: Str) -> Str

Everything before the last /: /a/b/c -> /a/b, c -> ., /c -> /.

path.dir_name("/a/b/c")   # => /a/b
path.dir_name("c")        # => .
path.dir_name("/c")       # => /

fn base_name(p: Str) -> Str

Everything after the last /.

path.base_name("/a/b/c.rill")   # => c.rill

fn extension(p: Str) -> Str

What follows the last . of the base name, or ""; a leading dot is a hidden file's name, not an extension.

path.extension("main.rill")   # => rill
path.extension(".bashrc")     # =>

fn stem(p: Str) -> Str

The base name without its extension.

path.stem("/a/main.rill")   # => main

fn with_extension(p: Str, ext: Str) -> Str

path.with_extension("main.rill", "o")   # => main.o
path.with_extension("main", "o")        # => main.o

fn parts(p: Str) -> List(Str)

The parts between separators, empty ones left out: /a//b/ -> [a, b].

path.parts("/a//b/")   # => Cons(a, Cons(b, Nil))

fn normalize(p: Str) -> Str

. dropped, .. folded into the part before it where there is one, repeated and trailing separators gone; an absolute path stays absolute. .. at the start of a relative path is kept, since there is nothing here to fold it into.

path.normalize("/a/b/../c/./d")   # => /a/c/d
path.normalize("../x")           # => ../x

fn relative_to(from: Str, to: Str) -> Str

b relative to a, both normalized first: relative_to("/a/b", "/a/b/c/d") is c/d, and relative_to("/a/b", "/a/x") is ../x.

path.relative_to("/a/b", "/a/b/c/d")   # => c/d
path.relative_to("/a/b", "/a/x")       # => ../x

Tests

  • test_join_and_split
  • test_extensions
  • test_normalize_and_relative