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_splittest_extensionstest_normalize_and_relative