// path - File path utilities for Lux // Get the last component of a path (filename) // basename("/foo/bar/baz.txt") => "baz.txt" // basename("file.txt") => "file.txt" pub fn basename(path: String): String = match String.lastIndexOf(path, "/") { Some(idx) => String.substring(path, idx + 1, String.length(path)), None => path, } // Get the directory portion of a path // dirname("/foo/bar/baz.txt") => "/foo/bar" // dirname("file.txt") => "." pub fn dirname(path: String): String = match String.lastIndexOf(path, "/") { Some(idx) => if idx == 0 then "/" else String.substring(path, 0, idx), None => ".", } // Get the file extension (without the dot) // extension("file.txt") => Some("txt") // extension("file") => None // extension("file.tar.gz") => Some("gz") pub fn extension(path: String): Option = { let name = basename(path) match String.lastIndexOf(name, ".") { Some(idx) => if idx == 0 then None else Some(String.substring(name, idx + 1, String.length(name))), None => None, } } // Remove the file extension // stripExtension("file.txt") => "file" // stripExtension("file") => "file" // stripExtension("/foo/bar.txt") => "/foo/bar" pub fn stripExtension(path: String): String = match String.lastIndexOf(path, ".") { Some(dotIdx) => match String.lastIndexOf(path, "/") { Some(slashIdx) => if dotIdx > slashIdx then String.substring(path, 0, dotIdx) else path, None => String.substring(path, 0, dotIdx), }, None => path, } // Join two path components with a separator // join("/foo", "bar") => "/foo/bar" // join("/foo/", "bar") => "/foo/bar" // join("", "bar") => "bar" pub fn join(a: String, b: String): String = if a == "" then b else if b == "" then a else if String.endsWith(a, "/") then if String.startsWith(b, "/") then a + String.substring(b, 1, String.length(b)) else a + b else if String.startsWith(b, "/") then a + b else a + "/" + b // Check if a path has a given extension // hasExtension("file.txt", "txt") => true // hasExtension("file.md", "txt") => false pub fn hasExtension(path: String, ext: String): Bool = String.endsWith(path, "." + ext) // Replace the file extension // replaceExtension("file.txt", "md") => "file.md" // replaceExtension("file", "md") => "file.md" pub fn replaceExtension(path: String, newExt: String): String = stripExtension(path) + "." + newExt // Get the filename without extension (stem) // stem("file.txt") => "file" // stem("/foo/bar.txt") => "bar" // stem("file") => "file" pub fn stem(path: String): String = { let name = basename(path) match String.lastIndexOf(name, ".") { Some(idx) => if idx == 0 then name else String.substring(name, 0, idx), None => name, } } // Check if a path is absolute (starts with /) pub fn isAbsolute(path: String): Bool = String.startsWith(path, "/") // Check if a path is relative (does not start with /) pub fn isRelative(path: String): Bool = if path == "" then true else if String.startsWith(path, "/") then false else true