@shd101wyy/yo 0.1.29 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/skills/yo-async-effects/SKILL.md +3 -3
- package/.github/skills/yo-async-effects/async-effects-recipes.md +19 -11
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +33 -13
- package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +1 -1
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +59 -21
- package/README.md +4 -3
- package/out/cjs/index.cjs +771 -676
- package/out/cjs/yo-cli.cjs +1003 -898
- package/out/cjs/yo-lsp.cjs +834 -739
- package/out/esm/index.mjs +716 -621
- package/out/types/src/codegen/exprs/async.d.ts +2 -0
- package/out/types/src/codegen/exprs/await.d.ts +1 -0
- package/out/types/src/codegen/exprs/closures.d.ts +4 -0
- package/out/types/src/codegen/functions/context.d.ts +6 -0
- package/out/types/src/env.d.ts +2 -0
- package/out/types/src/evaluator/builtins/pragma.d.ts +9 -0
- package/out/types/src/evaluator/builtins/unsafe.d.ts +8 -0
- package/out/types/src/evaluator/context.d.ts +2 -0
- package/out/types/src/evaluator/index.d.ts +1 -1
- package/out/types/src/evaluator/memory-safety.d.ts +14 -0
- package/out/types/src/evaluator/types/flowability.d.ts +6 -0
- package/out/types/src/expr-traversal.d.ts +1 -0
- package/out/types/src/expr.d.ts +4 -1
- package/out/types/src/public-safe-report.d.ts +19 -0
- package/out/types/src/tests/comptime-ref-gate.test.d.ts +1 -0
- package/out/types/src/tests/pragma-validation.test.d.ts +1 -0
- package/out/types/src/tests/public-safe-report.test.d.ts +1 -0
- package/out/types/src/tests/type-representation-pointer.test.d.ts +1 -0
- package/out/types/src/tests/unsafe-gate.test.d.ts +1 -0
- package/out/types/src/tests/unsafe-report-classify.test.d.ts +1 -0
- package/out/types/src/types/definitions.d.ts +2 -0
- package/out/types/src/types/utils.d.ts +4 -0
- package/out/types/src/unsafe-report.d.ts +29 -0
- package/out/types/src/value.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/add-pragma-for-pointer-decls.ts +134 -0
- package/scripts/add-pragma.ts +58 -0
- package/scripts/migrate-amp-method-calls.ts +186 -0
- package/scripts/migrate-clone-calls.ts +93 -0
- package/scripts/migrate-get-unwrap.ts +166 -0
- package/scripts/migrate-index-patterns.ts +210 -0
- package/scripts/migrate-index-trait.ts +142 -0
- package/scripts/migrate-iterator.ts +150 -0
- package/scripts/migrate-self-ptr.ts +220 -0
- package/scripts/migrate-skip-pragmas.ts +109 -0
- package/scripts/migrate-tostring.ts +134 -0
- package/scripts/trim-pragma.ts +130 -0
- package/scripts/wrap-extern-calls.ts +161 -0
- package/std/alg/hash.yo +3 -2
- package/std/allocator.yo +6 -5
- package/std/async.yo +2 -2
- package/std/collections/array_list.yo +59 -40
- package/std/collections/btree_map.yo +19 -18
- package/std/collections/deque.yo +9 -8
- package/std/collections/hash_map.yo +101 -13
- package/std/collections/hash_set.yo +5 -4
- package/std/collections/linked_list.yo +39 -4
- package/std/collections/ordered_map.yo +3 -3
- package/std/collections/priority_queue.yo +14 -13
- package/std/crypto/md5.yo +2 -1
- package/std/crypto/random.yo +16 -15
- package/std/crypto/sha256.yo +2 -1
- package/std/encoding/base64.yo +14 -14
- package/std/encoding/hex.yo +3 -3
- package/std/encoding/json.yo +59 -10
- package/std/encoding/punycode.yo +24 -23
- package/std/encoding/toml.yo +4 -3
- package/std/encoding/utf16.yo +2 -2
- package/std/env.yo +43 -28
- package/std/error.yo +6 -6
- package/std/fmt/display.yo +2 -2
- package/std/fmt/index.yo +6 -5
- package/std/fmt/to_string.yo +39 -38
- package/std/fmt/writer.yo +9 -8
- package/std/fs/dir.yo +34 -33
- package/std/fs/file.yo +52 -51
- package/std/fs/metadata.yo +10 -9
- package/std/fs/temp.yo +24 -13
- package/std/fs/walker.yo +10 -9
- package/std/gc.yo +1 -0
- package/std/glob.yo +7 -7
- package/std/http/client.yo +15 -14
- package/std/http/http.yo +6 -6
- package/std/http/index.yo +1 -1
- package/std/imm/list.yo +33 -0
- package/std/imm/map.yo +2 -1
- package/std/imm/set.yo +1 -0
- package/std/imm/sorted_map.yo +1 -0
- package/std/imm/sorted_set.yo +1 -0
- package/std/imm/string.yo +27 -23
- package/std/imm/vec.yo +18 -2
- package/std/io/reader.yo +2 -1
- package/std/io/writer.yo +3 -2
- package/std/libc/assert.yo +1 -0
- package/std/libc/ctype.yo +1 -0
- package/std/libc/dirent.yo +1 -0
- package/std/libc/errno.yo +1 -0
- package/std/libc/fcntl.yo +1 -0
- package/std/libc/float.yo +1 -0
- package/std/libc/limits.yo +1 -0
- package/std/libc/math.yo +1 -0
- package/std/libc/signal.yo +1 -0
- package/std/libc/stdatomic.yo +1 -0
- package/std/libc/stdint.yo +1 -0
- package/std/libc/stdio.yo +1 -0
- package/std/libc/stdlib.yo +1 -0
- package/std/libc/string.yo +1 -0
- package/std/libc/sys/stat.yo +1 -0
- package/std/libc/time.yo +1 -0
- package/std/libc/unistd.yo +1 -0
- package/std/libc/wctype.yo +1 -0
- package/std/libc/windows.yo +2 -0
- package/std/log.yo +7 -6
- package/std/net/addr.yo +5 -4
- package/std/net/dns.yo +7 -6
- package/std/net/errors.yo +8 -8
- package/std/net/tcp.yo +19 -18
- package/std/net/udp.yo +13 -12
- package/std/os/signal.yo +3 -3
- package/std/path.yo +1 -0
- package/std/prelude.yo +353 -182
- package/std/process/command.yo +40 -23
- package/std/process/index.yo +2 -1
- package/std/regex/compiler.yo +10 -9
- package/std/regex/index.yo +41 -41
- package/std/regex/match.yo +2 -2
- package/std/regex/parser.yo +21 -21
- package/std/regex/vm.yo +42 -41
- package/std/string/string.yo +95 -40
- package/std/string/string_builder.yo +9 -9
- package/std/string/unicode.yo +50 -49
- package/std/sync/channel.yo +2 -1
- package/std/sync/cond.yo +5 -4
- package/std/sync/mutex.yo +4 -3
- package/std/sys/advise.yo +1 -0
- package/std/sys/bufio/buf_reader.yo +17 -16
- package/std/sys/bufio/buf_writer.yo +10 -9
- package/std/sys/clock.yo +1 -0
- package/std/sys/copy.yo +1 -0
- package/std/sys/dir.yo +10 -9
- package/std/sys/dns.yo +6 -5
- package/std/sys/errors.yo +11 -11
- package/std/sys/events.yo +1 -0
- package/std/sys/externs.yo +38 -37
- package/std/sys/file.yo +17 -16
- package/std/sys/future.yo +4 -3
- package/std/sys/iov.yo +1 -0
- package/std/sys/mmap.yo +1 -0
- package/std/sys/path.yo +1 -0
- package/std/sys/perm.yo +2 -1
- package/std/sys/pipe.yo +1 -0
- package/std/sys/process.yo +5 -4
- package/std/sys/signal.yo +1 -0
- package/std/sys/socketpair.yo +1 -0
- package/std/sys/sockinfo.yo +1 -0
- package/std/sys/statfs.yo +2 -1
- package/std/sys/statx.yo +1 -0
- package/std/sys/sysinfo.yo +1 -0
- package/std/sys/tcp.yo +15 -14
- package/std/sys/temp.yo +1 -0
- package/std/sys/time.yo +2 -1
- package/std/sys/timer.yo +6 -6
- package/std/sys/tty.yo +2 -1
- package/std/sys/udp.yo +13 -12
- package/std/sys/unix.yo +12 -11
- package/std/testing/bench.yo +4 -3
- package/std/thread.yo +7 -6
- package/std/time/datetime.yo +18 -15
- package/std/time/duration.yo +11 -10
- package/std/time/instant.yo +4 -4
- package/std/time/sleep.yo +1 -0
- package/std/url/index.yo +3 -3
- package/std/worker.yo +4 -3
package/std/fs/file.yo
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
//! ```rust
|
|
9
9
|
//! { File, read_string, write_file, OpenMode } :: import "std/fs/file";
|
|
10
10
|
//!
|
|
11
|
-
//! main :: (fn(io :
|
|
11
|
+
//! main :: (fn(io : Io, exn : Exception) -> unit)({
|
|
12
12
|
//! // Write a file
|
|
13
13
|
//! io.await(write_file(Path.new(`test.txt`), `hello world`, io), { io, exn });
|
|
14
14
|
//!
|
|
@@ -20,14 +20,15 @@
|
|
|
20
20
|
//! f := io.await(File.open(Path.new(`test.txt`), .Read, io), { io, exn });
|
|
21
21
|
//! });
|
|
22
22
|
//! ```
|
|
23
|
+
pragma(Pragma.AllowUnsafe);
|
|
23
24
|
{ GlobalAllocator } :: import("../allocator");
|
|
24
25
|
{ malloc, free } :: GlobalAllocator;
|
|
25
26
|
{ ArrayList } :: import("../collections/array_list");
|
|
26
27
|
open(import("../string"));
|
|
27
28
|
open(import("../fmt"));
|
|
28
29
|
{ Path } :: import("../path");
|
|
29
|
-
{
|
|
30
|
-
{ Error, AnyError, Exception,
|
|
30
|
+
{ IoError } :: import("../sys/errors");
|
|
31
|
+
{ Error, AnyError, Exception, IoExn } :: import("../error");
|
|
31
32
|
{ Metadata } :: import("./metadata");
|
|
32
33
|
_metadata_mod :: import("./metadata");
|
|
33
34
|
{ Statx } :: import("../sys/statx");
|
|
@@ -51,7 +52,7 @@ File :: object(
|
|
|
51
52
|
impl(
|
|
52
53
|
File,
|
|
53
54
|
/// Open a file at `path` with the given mode and custom permissions.
|
|
54
|
-
open_with : (fn(path : Path, mode : OpenMode, perm : FilePermission, io :
|
|
55
|
+
open_with : (fn(path : Path, mode : OpenMode, perm : FilePermission, io : Io) -> Impl(Future(File, IoExn)))({
|
|
55
56
|
flags := _open_mode_to_flags(mode);
|
|
56
57
|
file_mode := cond(
|
|
57
58
|
_open_mode_needs_perm(mode) => i32(perm.mode),
|
|
@@ -62,7 +63,7 @@ impl(
|
|
|
62
63
|
cstr_bytes := path_str.to_cstr();
|
|
63
64
|
cstr := cstr_bytes.ptr().unwrap();
|
|
64
65
|
result := e.io.await(IO_file.openat(AT_FDCWD, cstr, flags, file_mode), e.io);
|
|
65
|
-
fd :=
|
|
66
|
+
fd := IoError.check(result, e.exn);
|
|
66
67
|
File(
|
|
67
68
|
_fd : fd,
|
|
68
69
|
_path : path,
|
|
@@ -71,37 +72,37 @@ impl(
|
|
|
71
72
|
})
|
|
72
73
|
}),
|
|
73
74
|
/// Open a file from a `str` path with the given mode and custom permissions.
|
|
74
|
-
open_with_str : (fn(path : str, mode : OpenMode, perm : FilePermission, io :
|
|
75
|
+
open_with_str : (fn(path : str, mode : OpenMode, perm : FilePermission, io : Io) -> Impl(Future(File, IoExn)))(
|
|
75
76
|
File.open_with(Path.new(String.from(path)), mode, perm, io)
|
|
76
77
|
),
|
|
77
78
|
/// Open a file from a C string path with the given mode and custom permissions.
|
|
78
|
-
open_with_cstr : (fn(path : *(u8), mode : OpenMode, perm : FilePermission, io :
|
|
79
|
+
open_with_cstr : (fn(path : *(u8), mode : OpenMode, perm : FilePermission, io : Io) -> Impl(Future(File, IoExn)))(
|
|
79
80
|
File.open_with(Path.from_cstr(path), mode, perm, io)
|
|
80
81
|
),
|
|
81
82
|
/// Open a file at `path` with the given mode and default permissions (0o644).
|
|
82
|
-
open : (fn(path : Path, mode : OpenMode, io :
|
|
83
|
+
open : (fn(path : Path, mode : OpenMode, io : Io) -> Impl(Future(File, IoExn)))(
|
|
83
84
|
File.open_with(path, mode, FilePermission.default(), io)
|
|
84
85
|
),
|
|
85
86
|
/// Open a file from a `str` path with the given mode and default permissions.
|
|
86
|
-
open_str : (fn(path : str, mode : OpenMode, io :
|
|
87
|
+
open_str : (fn(path : str, mode : OpenMode, io : Io) -> Impl(Future(File, IoExn)))(
|
|
87
88
|
File.open(Path.new(String.from(path)), mode, io)
|
|
88
89
|
),
|
|
89
90
|
/// Open a file from a C string path with the given mode and default permissions.
|
|
90
|
-
open_cstr : (fn(path : *(u8), mode : OpenMode, io :
|
|
91
|
+
open_cstr : (fn(path : *(u8), mode : OpenMode, io : Io) -> Impl(Future(File, IoExn)))(
|
|
91
92
|
File.open(Path.from_cstr(path), mode, io)
|
|
92
93
|
),
|
|
93
94
|
/// Read up to `size` bytes into the buffer `buf`.
|
|
94
95
|
/// Returns the number of bytes actually read.
|
|
95
|
-
read : (fn(self : Self, buf : *(u8), size : u32, io :
|
|
96
|
+
read : (fn(self : Self, buf : *(u8), size : u32, io : Io) -> Impl(Future(i32, IoExn)))({
|
|
96
97
|
fd := self._fd;
|
|
97
98
|
io.async((e) => {
|
|
98
99
|
result := e.io.await(IO_file.read(fd, buf, size, u64(0)), e.io);
|
|
99
|
-
|
|
100
|
+
IoError.check(result, e.exn)
|
|
100
101
|
})
|
|
101
102
|
}),
|
|
102
103
|
/// Write a `String` to the file.
|
|
103
104
|
/// Returns the number of bytes written.
|
|
104
|
-
write_string : (fn(self : Self, data : String, io :
|
|
105
|
+
write_string : (fn(self : Self, data : String, io : Io) -> Impl(Future(i32, IoExn)))({
|
|
105
106
|
fd := self._fd;
|
|
106
107
|
io.async((e) => {
|
|
107
108
|
data_bytes := data.as_bytes();
|
|
@@ -109,14 +110,14 @@ impl(
|
|
|
109
110
|
(data_bytes.len() == usize(0)) => i32(0),
|
|
110
111
|
true => {
|
|
111
112
|
result := e.io.await(IO_file.write(fd, data_bytes.ptr().unwrap(), u32(data_bytes.len()), u64(0)), e.io);
|
|
112
|
-
|
|
113
|
+
IoError.check(result, e.exn)
|
|
113
114
|
}
|
|
114
115
|
)
|
|
115
116
|
})
|
|
116
117
|
}),
|
|
117
118
|
/// Write bytes from an `ArrayList(u8)` to the file.
|
|
118
119
|
/// Returns the number of bytes written.
|
|
119
|
-
write_bytes : (fn(self : Self, data : ArrayList(u8), io :
|
|
120
|
+
write_bytes : (fn(self : Self, data : ArrayList(u8), io : Io) -> Impl(Future(i32, IoExn)))({
|
|
120
121
|
fd := self._fd;
|
|
121
122
|
io.async(
|
|
122
123
|
(e) =>
|
|
@@ -124,13 +125,13 @@ impl(
|
|
|
124
125
|
(data.len() == usize(0)) => i32(0),
|
|
125
126
|
true => {
|
|
126
127
|
result := e.io.await(IO_file.write(fd, data.ptr().unwrap(), u32(data.len()), u64(0)), e.io);
|
|
127
|
-
|
|
128
|
+
IoError.check(result, e.exn)
|
|
128
129
|
}
|
|
129
130
|
)
|
|
130
131
|
)
|
|
131
132
|
}),
|
|
132
133
|
/// Read the entire file contents into an `ArrayList(u8)`.
|
|
133
|
-
read_bytes : (fn(self : Self, io :
|
|
134
|
+
read_bytes : (fn(self : Self, io : Io) -> Impl(Future(ArrayList(u8), IoExn)))({
|
|
134
135
|
fd := self._fd;
|
|
135
136
|
io.async((e) => {
|
|
136
137
|
buf_size := usize(4096);
|
|
@@ -142,7 +143,7 @@ impl(
|
|
|
142
143
|
cond(
|
|
143
144
|
(n < i32(0)) => {
|
|
144
145
|
free(.Some(*(void)(buf)));
|
|
145
|
-
e.exn.throw(dyn(
|
|
146
|
+
e.exn.throw(dyn(IoError.from_errno(i32(0) - n)));
|
|
146
147
|
},
|
|
147
148
|
(n == i32(0)) => break,
|
|
148
149
|
true => {
|
|
@@ -160,19 +161,19 @@ impl(
|
|
|
160
161
|
})
|
|
161
162
|
}),
|
|
162
163
|
/// Read the entire file contents into a `String`.
|
|
163
|
-
read_string : (fn(self : Self, io :
|
|
164
|
+
read_string : (fn(self : Self, io : Io) -> Impl(Future(String, IoExn)))(
|
|
164
165
|
io.async((e) => {
|
|
165
166
|
bytes := e.io.await(self.read_bytes(io), e);
|
|
166
167
|
String.from_bytes(bytes)
|
|
167
168
|
})
|
|
168
169
|
),
|
|
169
170
|
/// Flush (fsync) file data to disk.
|
|
170
|
-
flush : (fn(self : Self, io :
|
|
171
|
+
flush : (fn(self : Self, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
171
172
|
fd := self._fd;
|
|
172
173
|
io.async((e) => {
|
|
173
174
|
result := e.io.await(IO_file.fsync(fd), e.io);
|
|
174
175
|
cond(
|
|
175
|
-
(result < i32(0)) => e.exn.throw(dyn(
|
|
176
|
+
(result < i32(0)) => e.exn.throw(dyn(IoError.from_errno(i32(0) - result))),
|
|
176
177
|
true => ()
|
|
177
178
|
)
|
|
178
179
|
})
|
|
@@ -181,7 +182,7 @@ impl(
|
|
|
181
182
|
seek : (fn(self : Self, offset : i64, from : SeekFrom, exn : Exception) -> i64)({
|
|
182
183
|
result := IO_seek.lseek(self._fd, offset, _seek_from_to_whence(from));
|
|
183
184
|
cond(
|
|
184
|
-
(result < i64(0)) => exn.throw(dyn(
|
|
185
|
+
(result < i64(0)) => exn.throw(dyn(IoError.from_errno(i32(i64(0) - result)))),
|
|
185
186
|
true => result
|
|
186
187
|
)
|
|
187
188
|
}),
|
|
@@ -194,7 +195,7 @@ impl(
|
|
|
194
195
|
IO_file.file_size(self._fd)
|
|
195
196
|
),
|
|
196
197
|
/// Close the file descriptor. Safe to call multiple times.
|
|
197
|
-
close : (fn(self : Self, io :
|
|
198
|
+
close : (fn(self : Self, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
198
199
|
fd := self._fd;
|
|
199
200
|
io.async(
|
|
200
201
|
(e) =>
|
|
@@ -204,7 +205,7 @@ impl(
|
|
|
204
205
|
result := e.io.await(IO_file.close(fd), e.io);
|
|
205
206
|
self._is_closed = true;
|
|
206
207
|
cond(
|
|
207
|
-
(result < i32(0)) => e.exn.throw(dyn(
|
|
208
|
+
(result < i32(0)) => e.exn.throw(dyn(IoError.from_errno(i32(0) - result))),
|
|
208
209
|
true => ()
|
|
209
210
|
)
|
|
210
211
|
}
|
|
@@ -220,7 +221,7 @@ impl(
|
|
|
220
221
|
self._path
|
|
221
222
|
),
|
|
222
223
|
/// Get file metadata (size, permissions, timestamps).
|
|
223
|
-
metadata : (fn(self : Self, io :
|
|
224
|
+
metadata : (fn(self : Self, io : Io) -> Impl(Future(Metadata, IoExn)))(
|
|
224
225
|
_metadata_mod.metadata(self._path, io)
|
|
225
226
|
)
|
|
226
227
|
);
|
|
@@ -243,7 +244,7 @@ export(File, OpenMode, FilePermission, SeekFrom);
|
|
|
243
244
|
// Convenience functions
|
|
244
245
|
// ============================================================================
|
|
245
246
|
/// Read an entire file into a `String`.
|
|
246
|
-
read_string :: (fn(path : Path, io :
|
|
247
|
+
read_string :: (fn(path : Path, io : Io) -> Impl(Future(String, IoExn)))(
|
|
247
248
|
io.async((e) => {
|
|
248
249
|
file := e.io.await(File.open(path,.Read, io), e);
|
|
249
250
|
content := e.io.await(file.read_string(io), e);
|
|
@@ -252,15 +253,15 @@ read_string :: (fn(path : Path, io : IO) -> Impl(Future(String, IOErr)))(
|
|
|
252
253
|
})
|
|
253
254
|
);
|
|
254
255
|
/// Read an entire file into a `String` (`str` path variant).
|
|
255
|
-
read_string_str :: (fn(path : str, io :
|
|
256
|
+
read_string_str :: (fn(path : str, io : Io) -> Impl(Future(String, IoExn)))(
|
|
256
257
|
read_string(Path.new(String.from(path)), io)
|
|
257
258
|
);
|
|
258
259
|
/// Read an entire file into a `String` (C string path variant).
|
|
259
|
-
read_string_cstr :: (fn(path : *(u8), io :
|
|
260
|
+
read_string_cstr :: (fn(path : *(u8), io : Io) -> Impl(Future(String, IoExn)))(
|
|
260
261
|
read_string(Path.from_cstr(path), io)
|
|
261
262
|
);
|
|
262
263
|
/// Read an entire file into a byte list (`ArrayList(u8)`).
|
|
263
|
-
read_file :: (fn(path : Path, io :
|
|
264
|
+
read_file :: (fn(path : Path, io : Io) -> Impl(Future(ArrayList(u8), IoExn)))(
|
|
264
265
|
io.async((e) => {
|
|
265
266
|
file := e.io.await(File.open(path,.Read, io), e);
|
|
266
267
|
content := e.io.await(file.read_bytes(io), e);
|
|
@@ -269,15 +270,15 @@ read_file :: (fn(path : Path, io : IO) -> Impl(Future(ArrayList(u8), IOErr)))(
|
|
|
269
270
|
})
|
|
270
271
|
);
|
|
271
272
|
/// Read an entire file into bytes (`str` path variant).
|
|
272
|
-
read_file_str :: (fn(path : str, io :
|
|
273
|
+
read_file_str :: (fn(path : str, io : Io) -> Impl(Future(ArrayList(u8), IoExn)))(
|
|
273
274
|
read_file(Path.new(String.from(path)), io)
|
|
274
275
|
);
|
|
275
276
|
/// Read an entire file into bytes (C string path variant).
|
|
276
|
-
read_file_cstr :: (fn(path : *(u8), io :
|
|
277
|
+
read_file_cstr :: (fn(path : *(u8), io : Io) -> Impl(Future(ArrayList(u8), IoExn)))(
|
|
277
278
|
read_file(Path.from_cstr(path), io)
|
|
278
279
|
);
|
|
279
280
|
/// Write a `String` to a file, creating or truncating it.
|
|
280
|
-
write_file :: (fn(path : Path, data : String, io :
|
|
281
|
+
write_file :: (fn(path : Path, data : String, io : Io) -> Impl(Future(unit, IoExn)))(
|
|
281
282
|
io.async((e) => {
|
|
282
283
|
file := e.io.await(File.open(path,.Write, io), e);
|
|
283
284
|
e.io.await(file.write_string(data, io), e);
|
|
@@ -285,15 +286,15 @@ write_file :: (fn(path : Path, data : String, io : IO) -> Impl(Future(unit, IOEr
|
|
|
285
286
|
})
|
|
286
287
|
);
|
|
287
288
|
/// Write a `str` to a file, creating or truncating it (`str` path variant).
|
|
288
|
-
write_file_str :: (fn(path : str, data : str, io :
|
|
289
|
+
write_file_str :: (fn(path : str, data : str, io : Io) -> Impl(Future(unit, IoExn)))(
|
|
289
290
|
write_file(Path.new(String.from(path)), String.from(data), io)
|
|
290
291
|
);
|
|
291
292
|
/// Write a `str` to a file, creating or truncating it (C string path variant).
|
|
292
|
-
write_file_cstr :: (fn(path : *(u8), data : str, io :
|
|
293
|
+
write_file_cstr :: (fn(path : *(u8), data : str, io : Io) -> Impl(Future(unit, IoExn)))(
|
|
293
294
|
write_file(Path.from_cstr(path), String.from(data), io)
|
|
294
295
|
);
|
|
295
296
|
/// Write bytes to a file, creating or truncating it.
|
|
296
|
-
write_bytes :: (fn(path : Path, data : ArrayList(u8), io :
|
|
297
|
+
write_bytes :: (fn(path : Path, data : ArrayList(u8), io : Io) -> Impl(Future(unit, IoExn)))(
|
|
297
298
|
io.async((e) => {
|
|
298
299
|
file := e.io.await(File.open(path,.Write, io), e);
|
|
299
300
|
e.io.await(file.write_bytes(data, io), e);
|
|
@@ -301,7 +302,7 @@ write_bytes :: (fn(path : Path, data : ArrayList(u8), io : IO) -> Impl(Future(un
|
|
|
301
302
|
})
|
|
302
303
|
);
|
|
303
304
|
/// Append a `String` to a file, creating it if it does not exist.
|
|
304
|
-
append_file :: (fn(path : Path, data : String, io :
|
|
305
|
+
append_file :: (fn(path : Path, data : String, io : Io) -> Impl(Future(unit, IoExn)))(
|
|
305
306
|
io.async((e) => {
|
|
306
307
|
file := e.io.await(File.open(path,.Append, io), e);
|
|
307
308
|
e.io.await(file.write_string(data, io), e);
|
|
@@ -309,7 +310,7 @@ append_file :: (fn(path : Path, data : String, io : IO) -> Impl(Future(unit, IOE
|
|
|
309
310
|
})
|
|
310
311
|
);
|
|
311
312
|
/// Append a `str` to a file (`str` path variant).
|
|
312
|
-
append_file_str :: (fn(path : str, data : str, io :
|
|
313
|
+
append_file_str :: (fn(path : str, data : str, io : Io) -> Impl(Future(unit, IoExn)))(
|
|
313
314
|
append_file(Path.new(String.from(path)), String.from(data), io)
|
|
314
315
|
);
|
|
315
316
|
extern(
|
|
@@ -318,7 +319,7 @@ extern(
|
|
|
318
319
|
);
|
|
319
320
|
/// Check if a path exists. Returns `false` for any error including file not found.
|
|
320
321
|
/// Does not use the `Exception` effect.
|
|
321
|
-
exists :: (fn(path : Path, io :
|
|
322
|
+
exists :: (fn(path : Path, io : Io) -> Impl(Future(bool, Io)))(
|
|
322
323
|
io.async((io) => {
|
|
323
324
|
cstr_bytes := path.to_string().to_cstr();
|
|
324
325
|
cstr := cstr_bytes.ptr().unwrap();
|
|
@@ -330,15 +331,15 @@ exists :: (fn(path : Path, io : IO) -> Impl(Future(bool, IO)))(
|
|
|
330
331
|
})
|
|
331
332
|
);
|
|
332
333
|
/// Check if a path exists (`str` path variant).
|
|
333
|
-
exists_str :: (fn(path : str, io :
|
|
334
|
+
exists_str :: (fn(path : str, io : Io) -> Impl(Future(bool, Io)))(
|
|
334
335
|
exists(Path.new(String.from(path)), io)
|
|
335
336
|
);
|
|
336
337
|
/// Check if a path exists (C string path variant).
|
|
337
|
-
exists_cstr :: (fn(path : *(u8), io :
|
|
338
|
+
exists_cstr :: (fn(path : *(u8), io : Io) -> Impl(Future(bool, Io)))(
|
|
338
339
|
exists(Path.from_cstr(path), io)
|
|
339
340
|
);
|
|
340
341
|
/// Check if a path is a regular file. Returns `false` for any error.
|
|
341
|
-
is_file :: (fn(path : Path, io :
|
|
342
|
+
is_file :: (fn(path : Path, io : Io) -> Impl(Future(bool, Io)))(
|
|
342
343
|
io.async((io) => {
|
|
343
344
|
path_str := path.to_string();
|
|
344
345
|
cstr_bytes := path_str.to_cstr();
|
|
@@ -358,15 +359,15 @@ is_file :: (fn(path : Path, io : IO) -> Impl(Future(bool, IO)))(
|
|
|
358
359
|
})
|
|
359
360
|
);
|
|
360
361
|
/// Check if a path is a regular file (`str` path variant).
|
|
361
|
-
is_file_str :: (fn(path : str, io :
|
|
362
|
+
is_file_str :: (fn(path : str, io : Io) -> Impl(Future(bool, Io)))(
|
|
362
363
|
is_file(Path.new(String.from(path)), io)
|
|
363
364
|
);
|
|
364
365
|
/// Check if a path is a regular file (C string path variant).
|
|
365
|
-
is_file_cstr :: (fn(path : *(u8), io :
|
|
366
|
+
is_file_cstr :: (fn(path : *(u8), io : Io) -> Impl(Future(bool, Io)))(
|
|
366
367
|
is_file(Path.from_cstr(path), io)
|
|
367
368
|
);
|
|
368
369
|
/// Check if a path is a directory. Returns `false` for any error.
|
|
369
|
-
is_dir :: (fn(path : Path, io :
|
|
370
|
+
is_dir :: (fn(path : Path, io : Io) -> Impl(Future(bool, Io)))(
|
|
370
371
|
io.async((io) => {
|
|
371
372
|
path_str := path.to_string();
|
|
372
373
|
cstr_bytes := path_str.to_cstr();
|
|
@@ -386,16 +387,16 @@ is_dir :: (fn(path : Path, io : IO) -> Impl(Future(bool, IO)))(
|
|
|
386
387
|
})
|
|
387
388
|
);
|
|
388
389
|
/// Check if a path is a directory (`str` path variant).
|
|
389
|
-
is_dir_str :: (fn(path : str, io :
|
|
390
|
+
is_dir_str :: (fn(path : str, io : Io) -> Impl(Future(bool, Io)))(
|
|
390
391
|
is_dir(Path.new(String.from(path)), io)
|
|
391
392
|
);
|
|
392
393
|
/// Check if a path is a directory (C string path variant).
|
|
393
|
-
is_dir_cstr :: (fn(path : *(u8), io :
|
|
394
|
+
is_dir_cstr :: (fn(path : *(u8), io : Io) -> Impl(Future(bool, Io)))(
|
|
394
395
|
is_dir(Path.from_cstr(path), io)
|
|
395
396
|
);
|
|
396
397
|
/// Resolve a path to its canonical absolute form (resolves symlinks, `.` and `..`).
|
|
397
398
|
/// Throws if the path does not exist.
|
|
398
|
-
canonical :: (fn(path : Path, io :
|
|
399
|
+
canonical :: (fn(path : Path, io : Io) -> Impl(Future(Path, IoExn)))(
|
|
399
400
|
io.async((e) => {
|
|
400
401
|
path_str := path.to_string();
|
|
401
402
|
cstr_bytes := path_str.to_cstr();
|
|
@@ -405,14 +406,14 @@ canonical :: (fn(path : Path, io : IO) -> Impl(Future(Path, IOErr)))(
|
|
|
405
406
|
stat_buf := *(u8)(malloc(buf_size).unwrap());
|
|
406
407
|
stat_result := e.io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, stat_buf), e.io);
|
|
407
408
|
free(.Some(*(void)(stat_buf)));
|
|
408
|
-
|
|
409
|
+
IoError.check(stat_result, e.exn);
|
|
409
410
|
// Resolve the canonical path
|
|
410
411
|
resolved_buf := *(u8)(malloc(usize(4096)).unwrap());
|
|
411
412
|
rp_result := IO_path.realpath(cstr, resolved_buf);
|
|
412
413
|
cond(
|
|
413
414
|
(rp_result < i32(0)) => {
|
|
414
415
|
free(.Some(*(void)(resolved_buf)));
|
|
415
|
-
|
|
416
|
+
IoError.check(rp_result, e.exn);
|
|
416
417
|
},
|
|
417
418
|
true => ()
|
|
418
419
|
);
|
|
@@ -422,11 +423,11 @@ canonical :: (fn(path : Path, io : IO) -> Impl(Future(Path, IOErr)))(
|
|
|
422
423
|
})
|
|
423
424
|
);
|
|
424
425
|
/// Resolve a path to its canonical absolute form (`str` path variant).
|
|
425
|
-
canonical_str :: (fn(path : str, io :
|
|
426
|
+
canonical_str :: (fn(path : str, io : Io) -> Impl(Future(Path, IoExn)))(
|
|
426
427
|
canonical(Path.new(String.from(path)), io)
|
|
427
428
|
);
|
|
428
429
|
/// Resolve a path to its canonical absolute form (C string path variant).
|
|
429
|
-
canonical_cstr :: (fn(path : *(u8), io :
|
|
430
|
+
canonical_cstr :: (fn(path : *(u8), io : Io) -> Impl(Future(Path, IoExn)))(
|
|
430
431
|
canonical(Path.from_cstr(path), io)
|
|
431
432
|
);
|
|
432
433
|
export(
|
package/std/fs/metadata.yo
CHANGED
|
@@ -6,18 +6,19 @@
|
|
|
6
6
|
//! ```rust
|
|
7
7
|
//! { metadata } :: import "std/fs/metadata";
|
|
8
8
|
//!
|
|
9
|
-
//! main :: (fn(io :
|
|
9
|
+
//! main :: (fn(io : Io, exn : Exception) -> unit)({
|
|
10
10
|
//! m := io.await(metadata(Path.new(`/tmp/test.txt`), io), { io, exn });
|
|
11
11
|
//! printf("size: %lld\n", m.size());
|
|
12
12
|
//! printf("is file: %d\n", i32(m.is_file()));
|
|
13
13
|
//! });
|
|
14
14
|
//! ```
|
|
15
|
+
pragma(Pragma.AllowUnsafe);
|
|
15
16
|
{ GlobalAllocator } :: import("../allocator");
|
|
16
17
|
{ malloc, free } :: GlobalAllocator;
|
|
17
18
|
open(import("../string"));
|
|
18
19
|
{ Path } :: import("../path");
|
|
19
|
-
{
|
|
20
|
-
{ Error, AnyError, Exception,
|
|
20
|
+
{ IoError } :: import("../sys/errors");
|
|
21
|
+
{ Error, AnyError, Exception, IoExn } :: import("../error");
|
|
21
22
|
{ Statx } :: import("../sys/statx");
|
|
22
23
|
IO_file :: import("../sys/file");
|
|
23
24
|
{ AT_FDCWD, AT_SYMLINK_NOFOLLOW, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, S_IFMT, S_IFREG, S_IFDIR, S_IFLNK, S_IWUSR, S_IWGRP, S_IWOTH } :: import("../sys/constants");
|
|
@@ -101,7 +102,7 @@ extern(
|
|
|
101
102
|
// ============================================================================
|
|
102
103
|
// Internal helper to stat a path
|
|
103
104
|
// ============================================================================
|
|
104
|
-
_stat_path :: (fn(path : Path, flags : i32, io :
|
|
105
|
+
_stat_path :: (fn(path : Path, flags : i32, io : Io) -> Impl(Future(Metadata, IoExn)))(
|
|
105
106
|
io.async((e) => {
|
|
106
107
|
cstr_bytes := path.to_string().to_cstr();
|
|
107
108
|
cstr := cstr_bytes.ptr().unwrap();
|
|
@@ -111,7 +112,7 @@ _stat_path :: (fn(path : Path, flags : i32, io : IO) -> Impl(Future(Metadata, IO
|
|
|
111
112
|
cond(
|
|
112
113
|
(result < i32(0)) => {
|
|
113
114
|
free(.Some(*(void)(buf)));
|
|
114
|
-
e.exn.throw(dyn(
|
|
115
|
+
e.exn.throw(dyn(IoError.from_errno(i32(0) - result)))
|
|
115
116
|
},
|
|
116
117
|
true => {
|
|
117
118
|
sx := Statx(_buf_ptr : buf, _buf_size : buf_size);
|
|
@@ -121,11 +122,11 @@ _stat_path :: (fn(path : Path, flags : i32, io : IO) -> Impl(Future(Metadata, IO
|
|
|
121
122
|
})
|
|
122
123
|
);
|
|
123
124
|
/// Get metadata for a path (follows symlinks).
|
|
124
|
-
metadata :: (fn(path : Path, io :
|
|
125
|
+
metadata :: (fn(path : Path, io : Io) -> Impl(Future(Metadata, IoExn)))(_stat_path(path, AT_STATX_SYNC_AS_STAT, io));
|
|
125
126
|
/// Get metadata for a path given as a raw string (follows symlinks).
|
|
126
|
-
metadata_str :: (fn(path : str, io :
|
|
127
|
+
metadata_str :: (fn(path : str, io : Io) -> Impl(Future(Metadata, IoExn)))(metadata(Path.new(String.from(path)), io));
|
|
127
128
|
/// Get metadata for a path (does NOT follow symlinks).
|
|
128
|
-
symlink_metadata :: (fn(path : Path, io :
|
|
129
|
+
symlink_metadata :: (fn(path : Path, io : Io) -> Impl(Future(Metadata, IoExn)))(_stat_path(path, AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT, io));
|
|
129
130
|
/// Get metadata for a path given as a raw string (does NOT follow symlinks).
|
|
130
|
-
symlink_metadata_str :: (fn(path : str, io :
|
|
131
|
+
symlink_metadata_str :: (fn(path : str, io : Io) -> Impl(Future(Metadata, IoExn)))(symlink_metadata(Path.new(String.from(path)), io));
|
|
131
132
|
export(metadata, metadata_str, symlink_metadata, symlink_metadata_str);
|
package/std/fs/temp.yo
CHANGED
|
@@ -5,19 +5,20 @@
|
|
|
5
5
|
//! ```rust
|
|
6
6
|
//! { TempDir } :: import "std/fs/temp";
|
|
7
7
|
//!
|
|
8
|
-
//! main :: (fn(io :
|
|
8
|
+
//! main :: (fn(io : Io, exn : Exception) -> unit)({
|
|
9
9
|
//! dir := io.await(TempDir.new(io), { io, exn });
|
|
10
10
|
//! println(dir.path());
|
|
11
11
|
//! io.await(dir.remove(io), { io, exn });
|
|
12
12
|
//! });
|
|
13
13
|
//! ```
|
|
14
|
+
pragma(Pragma.AllowUnsafe);
|
|
14
15
|
{ GlobalAllocator } :: import("../allocator");
|
|
15
16
|
{ malloc, free } :: GlobalAllocator;
|
|
16
17
|
open(import("../string"));
|
|
17
18
|
open(import("../fmt"));
|
|
18
19
|
{ Path } :: import("../path");
|
|
19
|
-
{
|
|
20
|
-
{ Error, AnyError, Exception,
|
|
20
|
+
{ IoError } :: import("../sys/errors");
|
|
21
|
+
{ Error, AnyError, Exception, IoExn } :: import("../error");
|
|
21
22
|
_file_mod :: import("./file");
|
|
22
23
|
_dir_mod :: import("./dir");
|
|
23
24
|
IO_temp :: import("../sys/temp");
|
|
@@ -53,7 +54,7 @@ TempDir :: object(
|
|
|
53
54
|
impl(
|
|
54
55
|
TempDir,
|
|
55
56
|
// Create a temporary directory in the given parent directory.
|
|
56
|
-
new_in : (fn(parent : Path, io :
|
|
57
|
+
new_in : (fn(parent : Path, io : Io) -> Impl(Future(TempDir, IoExn)))(
|
|
57
58
|
io.async((e) => {
|
|
58
59
|
// Build template: parent/yo_tmp_XXXXXX
|
|
59
60
|
template_path := parent.join(Path.new(`yo_tmp_XXXXXX`));
|
|
@@ -62,13 +63,19 @@ impl(
|
|
|
62
63
|
template_bytes := template_str.as_bytes();
|
|
63
64
|
buf_len := (template_bytes.len() + usize(1));
|
|
64
65
|
buf := *(u8)(malloc(buf_len).unwrap());
|
|
65
|
-
|
|
66
|
+
// SAFETY: `buf` is a fresh malloc'd `buf_len = template_bytes.len() + 1`
|
|
67
|
+
// byte buffer; we copy exactly `template_bytes.len()` bytes from
|
|
68
|
+
// `template_bytes`'s underlying storage (alive for the duration of this
|
|
69
|
+
// statement — it's the bytes of `template_str` which we own) and write
|
|
70
|
+
// the trailing NUL at `buf[template_bytes.len()]`. `buf` is freed in
|
|
71
|
+
// both the error branch and after `IO_temp.mkdtemp` returns.
|
|
72
|
+
unsafe(memcpy(*(void)(buf), *(void)(template_bytes.ptr().unwrap()), template_bytes.len()));
|
|
66
73
|
(buf &+ template_bytes.len()).* = u8(0);
|
|
67
74
|
result := IO_temp.mkdtemp(buf);
|
|
68
75
|
cond(
|
|
69
76
|
(result < i32(0)) => {
|
|
70
77
|
free(.Some(*(void)(buf)));
|
|
71
|
-
e.exn.throw(dyn(
|
|
78
|
+
e.exn.throw(dyn(IoError.from_errno(i32(0) - result)));
|
|
72
79
|
},
|
|
73
80
|
true => ()
|
|
74
81
|
);
|
|
@@ -78,7 +85,7 @@ impl(
|
|
|
78
85
|
})
|
|
79
86
|
),
|
|
80
87
|
// Create a temporary directory in the system temp dir.
|
|
81
|
-
new : (fn(io :
|
|
88
|
+
new : (fn(io : Io) -> Impl(Future(TempDir, IoExn)))(
|
|
82
89
|
TempDir.new_in(Path.new(_default_tmp_dir()), io)
|
|
83
90
|
),
|
|
84
91
|
// Get the path of the temporary directory.
|
|
@@ -86,7 +93,7 @@ impl(
|
|
|
86
93
|
self._path
|
|
87
94
|
),
|
|
88
95
|
// Remove the temporary directory.
|
|
89
|
-
remove : (fn(self : Self, io :
|
|
96
|
+
remove : (fn(self : Self, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
90
97
|
self_path := self._path;
|
|
91
98
|
io.async(
|
|
92
99
|
(e) =>
|
|
@@ -110,7 +117,7 @@ TempFile :: object(
|
|
|
110
117
|
impl(
|
|
111
118
|
TempFile,
|
|
112
119
|
// Create a temporary file in the given parent directory.
|
|
113
|
-
new_in : (fn(parent : Path, io :
|
|
120
|
+
new_in : (fn(parent : Path, io : Io) -> Impl(Future(TempFile, IoExn)))(
|
|
114
121
|
io.async((e) => {
|
|
115
122
|
// Build template: parent/yo_tmp_XXXXXX
|
|
116
123
|
template_path := parent.join(Path.new(`yo_tmp_XXXXXX`));
|
|
@@ -118,13 +125,17 @@ impl(
|
|
|
118
125
|
template_bytes := template_str.as_bytes();
|
|
119
126
|
buf_len := (template_bytes.len() + usize(1));
|
|
120
127
|
buf := *(u8)(malloc(buf_len).unwrap());
|
|
121
|
-
|
|
128
|
+
// SAFETY: as in `TempDir.new_in` above — `buf` is a fresh malloc'd
|
|
129
|
+
// `template_bytes.len() + 1` byte buffer, we copy exactly the template
|
|
130
|
+
// bytes plus a trailing NUL. `buf` is freed in the error branch and
|
|
131
|
+
// released to mkstemp's owned-fd lifecycle on success.
|
|
132
|
+
unsafe(memcpy(*(void)(buf), *(void)(template_bytes.ptr().unwrap()), template_bytes.len()));
|
|
122
133
|
(buf &+ template_bytes.len()).* = u8(0);
|
|
123
134
|
fd := IO_temp.mkstemp(buf);
|
|
124
135
|
cond(
|
|
125
136
|
(fd < i32(0)) => {
|
|
126
137
|
free(.Some(*(void)(buf)));
|
|
127
|
-
e.exn.throw(dyn(
|
|
138
|
+
e.exn.throw(dyn(IoError.from_errno(i32(0) - fd)));
|
|
128
139
|
},
|
|
129
140
|
true => ()
|
|
130
141
|
);
|
|
@@ -136,7 +147,7 @@ impl(
|
|
|
136
147
|
})
|
|
137
148
|
),
|
|
138
149
|
// Create a temporary file in the system temp dir.
|
|
139
|
-
new : (fn(io :
|
|
150
|
+
new : (fn(io : Io) -> Impl(Future(TempFile, IoExn)))(
|
|
140
151
|
TempFile.new_in(Path.new(_default_tmp_dir()), io)
|
|
141
152
|
),
|
|
142
153
|
// Get the underlying File object.
|
|
@@ -148,7 +159,7 @@ impl(
|
|
|
148
159
|
self._path
|
|
149
160
|
),
|
|
150
161
|
// Remove the temporary file.
|
|
151
|
-
remove : (fn(self : Self, io :
|
|
162
|
+
remove : (fn(self : Self, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
152
163
|
self_file := self._file;
|
|
153
164
|
self_path := self._path;
|
|
154
165
|
io.async(
|
package/std/fs/walker.yo
CHANGED
|
@@ -5,21 +5,22 @@
|
|
|
5
5
|
//! ```rust
|
|
6
6
|
//! { walk, WalkEntry } :: import "std/fs/walker";
|
|
7
7
|
//!
|
|
8
|
-
//! main :: (fn(io :
|
|
8
|
+
//! main :: (fn(io : Io, exn : Exception) -> unit)({
|
|
9
9
|
//! entries := io.await(walk(Path.new(`/tmp`), io), { io, exn });
|
|
10
10
|
//! i := usize(0);
|
|
11
11
|
//! while runtime((i < entries.len())), {
|
|
12
|
-
//! e := entries
|
|
12
|
+
//! e := entries(i);
|
|
13
13
|
//! println(e.path);
|
|
14
14
|
//! i = (i + usize(1));
|
|
15
15
|
//! };
|
|
16
16
|
//! });
|
|
17
17
|
//! ```
|
|
18
|
+
pragma(Pragma.AllowUnsafe);
|
|
18
19
|
{ ArrayList } :: import("../collections/array_list");
|
|
19
20
|
open(import("../string"));
|
|
20
21
|
{ Path } :: import("../path");
|
|
21
|
-
{
|
|
22
|
-
{ Error, AnyError, Exception,
|
|
22
|
+
{ IoError } :: import("../sys/errors");
|
|
23
|
+
{ Error, AnyError, Exception, IoExn } :: import("../error");
|
|
23
24
|
{ FileType } :: import("./dir");
|
|
24
25
|
{ DirEntry } :: import("./dir");
|
|
25
26
|
_dir :: import("./dir");
|
|
@@ -61,7 +62,7 @@ _join_path :: (fn(base : String, name : String) -> String)(
|
|
|
61
62
|
// Walk functions
|
|
62
63
|
// ============================================================================
|
|
63
64
|
// Walk a directory tree with custom options.
|
|
64
|
-
walk_with :: (fn(root : Path, options : WalkOptions, io :
|
|
65
|
+
walk_with :: (fn(root : Path, options : WalkOptions, io : Io) -> Impl(Future(ArrayList(WalkEntry), IoExn)))({
|
|
65
66
|
root_s := root.to_string();
|
|
66
67
|
io.async((e) => {
|
|
67
68
|
results := ArrayList(WalkEntry).new();
|
|
@@ -83,7 +84,7 @@ walk_with :: (fn(root : Path, options : WalkOptions, io : IO) -> Impl(Future(Arr
|
|
|
83
84
|
entries := e.io.await(_dir.read_dir(Path.new(cur_path), e.io), e);
|
|
84
85
|
i := usize(0);
|
|
85
86
|
while(runtime(i < entries.len()), {
|
|
86
|
-
entry := entries
|
|
87
|
+
entry := entries(i);
|
|
87
88
|
entry_path := _join_path(cur_path, entry.name);
|
|
88
89
|
match(
|
|
89
90
|
entry.file_type,
|
|
@@ -124,10 +125,10 @@ walk_with :: (fn(root : Path, options : WalkOptions, io : IO) -> Impl(Future(Arr
|
|
|
124
125
|
results
|
|
125
126
|
})
|
|
126
127
|
});
|
|
127
|
-
walk_with_cstr :: (fn(root : *(u8), options : WalkOptions, io :
|
|
128
|
+
walk_with_cstr :: (fn(root : *(u8), options : WalkOptions, io : Io) -> Impl(Future(ArrayList(WalkEntry), IoExn)))(
|
|
128
129
|
walk_with(Path.from_cstr(root), options, io)
|
|
129
130
|
);
|
|
130
131
|
/// Walk a directory tree with default options.
|
|
131
|
-
walk :: (fn(root : Path, io :
|
|
132
|
-
walk_cstr :: (fn(root : *(u8), io :
|
|
132
|
+
walk :: (fn(root : Path, io : Io) -> Impl(Future(ArrayList(WalkEntry), IoExn)))(walk_with(root, WalkOptions.defaults(), io));
|
|
133
|
+
walk_cstr :: (fn(root : *(u8), io : Io) -> Impl(Future(ArrayList(WalkEntry), IoExn)))(walk(Path.from_cstr(root), io));
|
|
133
134
|
export(walk, walk_cstr, walk_with, walk_with_cstr);
|