1#include "include/pw.h"
 2#include "include/pwlib/path.h"
 3
 4[[nodiscard]] bool pw_path_as_string(PwValuePtr path, PwValuePtr result)
 5{
 6    if (pw_is_array(path)) {
 7        return pw_path_join(path, result);
 8    } else {
 9        pw_assert(pw_is_string(path));
10        pw_clone2(result, path);
11        return true;
12    }
13}
14
15[[nodiscard]] bool pw_path_join(PwValuePtr parts, PwValuePtr result)
16{
17    pw_assert(pw_is_array(parts));
18
19    PwValue curated_parts = PW_NULL;
20    if (!pw_create(PwTypeId_BasicArray, &curated_parts)) {
21        return false;
22    }
23
24    unsigned n = pw_array_length(parts);
25    unsigned i = 0;
26
27    // check if parts is an absolute path
28    if (n) {
29        PwValue first = PW_NULL;
30        if (!pw_array_item(parts, 0, &first)) {
31            return false;
32        }
33        if (pw_equal(&first, "/")) {
34            // add empty element so the result would start with slash after joining
35            PwValue root = PW_STRING();
36            if (!pw_array_append(&curated_parts, &root)) {
37                return false;
38            }
39            i = 1;
40            if (n == 1) {
41                // the only element in `parts` is empty string, add yet another empty element for joining
42                if (!pw_array_append(&curated_parts, &root)) {
43                    return false;
44                }
45            }
46        }
47    }
48
49    // curate parts
50    for (; i < n; i++) {
51        PwValue item = PW_NULL;
52        if (!pw_array_item(parts, i, &item)) {
53            return false;
54        }
55        pw_assert(pw_is_string(&item));
56
57        if (pw_strlen(&item) != 0) {
58            if (!pw_array_append(&curated_parts, &item)) {
59                return false;
60            }
61        }
62    }
63
64    // join parts
65    return pw_array_join(&curated_parts, '/', result);
66}