path.ha (1734B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use bytes; 5 use strings; 6 7 export type path = struct { 8 buf: [MAX]u8, 9 end: size, 10 }; 11 12 // Initializes a new [[path]] 13 export fn init(items: str...) (path | error) = { 14 let p = path { ... }; 15 push(&p, items...)?; 16 return p; 17 }; 18 19 // Sets the value of a [[path]] to a list of components, overwriting any 20 // previous value. Returns the new string value of the path. 21 export fn set(p: *path, items: str...) (str | error) = { 22 p.end = 0; 23 return push(p, items...); 24 }; 25 26 // Returns the current path stored in this [[path]]'s buffer 27 // The return value is borrowed from the [[path]]. 28 // Use [[strings::dup]] to extend the lifetime of the string. 29 export fn string(p: *path) str = { 30 if (p.end == 0) return "."; 31 return strings::fromutf8_unsafe(p.buf[..p.end]); 32 }; 33 34 // Checks if a [[path]] is an absolute path. 35 export fn abs(p: (*path | str)) bool = match (p) { 36 case let s: str => return strings::hasprefix(s, sepstr); 37 case let p: *path => return 0 < p.end && p.buf[0] == SEP; 38 }; 39 40 // Checks if a [[path]] is the root directory. 41 export fn isroot(p: (*path | str)) bool = match (p) { 42 case let s: str => return s == sepstr; 43 case let p: *path => return p.end == 1 && p.buf[0] == SEP; 44 }; 45 46 // Replaces all instances of '/' in a string with [[SEP]]. The result is 47 // statically-allocated. 48 export fn local(path: str) str = { 49 static let buf: [MAX]u8 = [0...]; 50 return _local(path, &buf); 51 }; 52 53 fn _local(path: str, buf: *[MAX]u8) str = { 54 let buf = buf[..0]; 55 const path = strings::toutf8(path); 56 for (let i = 0z; i < len(path); i += 1) { 57 if (path[i] == '/') { 58 static append(buf, SEP)!; 59 } else { 60 static append(buf, path[i])!; 61 }; 62 }; 63 return strings::fromutf8(buf)!; 64 };