module path

module lib/path.mu

import "path"

path is a collection of path manipulation functions.

Imports

Functions

basename#

fn basename(path)

basename extracts the final component of path, returning "/" for root.

Source lib/path.mu:60
fn basename(path) {
  if !typing.is_str(path) {
    return error("path.basename expects string path, got " + type(path))
  }
  value := path
  if value == "" {
    return ""
  }
  trimmed := trim_trailing_slashes(value)
  if trimmed == "" {
    return "/"
  }
  if trimmed == "/" {
    return "/"
  }
  idx := len(trimmed) - 1
  while idx >= 0 && trimmed[idx] != "/" {
    idx = idx - 1
  }
  return strings.substring(trimmed, idx+1, len(trimmed))
}

dirname#

fn dirname(path)

dirname returns the directory portion of path, defaulting to "." or "/".

Source lib/path.mu:83
fn dirname(path) {
  if !typing.is_str(path) {
    return error("path.dirname expects string path, got " + type(path))
  }
  value := path
  if value == "" {
    return "."
  }
  trimmed := trim_trailing_slashes(value)
  if trimmed == "" {
    return "/"
  }
  idx := len(trimmed) - 1
  while idx >= 0 && trimmed[idx] != "/" {
    idx = idx - 1
  }
  if idx < 0 {
    return "."
  }
  if idx == 0 {
    return "/"
  }
  return strings.substring(trimmed, 0, idx)
}

ext#

fn ext(path)

ext returns the file extension (including the dot) of the basename, or empty if none.

Source lib/path.mu:109
fn ext(path) {
  base := basename(path)
  if is_error(base) {
    return base
  }
  i := len(base) - 1
  while i >= 0 && base[i] != "." {
    i = i - 1
  }
  if i <= 0 {
    return ""
  }
  return strings.substring(base, i, len(base))
}

join#

fn join(parts...)

join joins path fragments using "/" semantics, collapsing redundant slashes and root resets.

Source lib/path.mu:7
fn join(parts...) {
  result := ""
  i := 0
  while i < len(parts) {
    part := parts[i]
    if !typing.is_str(part) {
      return error("path.join(): part must be a string")
    }
    if len(part) == 0 {
      i = i + 1
      continue
    }
    if part[0] == "/" {
      result = part
    } else if result == "" {
      result = part
    } else if result == "/" || strings.ends_with(result, "/") {
      result = result + part
    } else {
      result = result + "/" + part
    }
    i = i + 1
  }
  if len(result) == 0 {
    return "."
  }
  return result
}

split#

fn split(path)

split returns the non-empty components of path, ignoring leading/trailing slashes.

Source lib/path.mu:37
fn split(path) {
  if !typing.is_str(path) {
    return error("path.split(): path must be a string")
  }
  value := path
  parts := []
  i := 0
  total := len(value)
  while i < total {
    if value[i] == "/" {
      i = i + 1
      continue
    }
    start := i
    while i < total && value[i] != "/" {
      i = i + 1
    }
    append(parts, strings.substring(value, start, i))
  }
  return parts
}

trim_trailing_slashes#

fn trim_trailing_slashes(path)

trim_trailing_slashes removes redundant trailing "/" characters but leaves root intact.

Source lib/path.mu:125
fn trim_trailing_slashes(path) {
  if !typing.is_str(path) {
    return error("path.trim_trailing_slashes expects string path, got " + type(path))
  }
  end := len(path)
  if end == 0 {
    return ""
  }
  while end > 1 && path[end-1] == "/" {
    end = end - 1
  }
  return strings.substring(path, 0, end)
}