hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };