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}