@shd101wyy/yo 0.1.11 → 0.1.13
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/README.md +10 -1
- package/out/cjs/index.cjs +579 -573
- package/out/cjs/yo-cli.cjs +1413 -592
- package/out/esm/index.mjs +437 -431
- package/out/types/src/build-runner.d.ts +1 -1
- package/out/types/src/doc/builder.d.ts +21 -0
- package/out/types/src/doc/builder.test.d.ts +1 -0
- package/out/types/src/doc/extractor.d.ts +27 -0
- package/out/types/src/doc/extractor.test.d.ts +1 -0
- package/out/types/src/doc/model.d.ts +87 -0
- package/out/types/src/doc/render-html.d.ts +23 -0
- package/out/types/src/doc/render-html.test.d.ts +1 -0
- package/out/types/src/doc/render-json.d.ts +7 -0
- package/out/types/src/doc/render-json.test.d.ts +1 -0
- package/out/types/src/doc/render-markdown.d.ts +13 -0
- package/out/types/src/doc/render-markdown.test.d.ts +1 -0
- package/out/types/src/doc/sections.d.ts +7 -0
- package/out/types/src/doc/sections.test.d.ts +1 -0
- package/out/types/src/doc-command.d.ts +10 -0
- package/out/types/src/env.d.ts +1 -0
- package/out/types/src/evaluator/builtins/build.d.ts +17 -0
- package/out/types/src/evaluator/context.d.ts +1 -0
- package/out/types/src/evaluator/exprs/import.d.ts +2 -0
- package/out/types/src/expr.d.ts +2 -1
- package/out/types/src/tests/import-path.test.d.ts +1 -0
- package/out/types/src/token.d.ts +4 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/scripts/build-site.ts +461 -0
- package/std/alg/hash.yo +12 -24
- package/std/allocator.yo +21 -29
- package/std/async.yo +4 -2
- package/std/build.yo +188 -42
- package/std/cli/arg_parser.yo +37 -1
- package/std/collections/array_list.yo +8 -20
- package/std/collections/btree_map.yo +15 -20
- package/std/collections/deque.yo +13 -15
- package/std/collections/hash_map.yo +15 -54
- package/std/collections/hash_set.yo +14 -50
- package/std/collections/linked_list.yo +6 -23
- package/std/collections/priority_queue.yo +15 -17
- package/std/crypto/md5.yo +10 -9
- package/std/crypto/random.yo +14 -12
- package/std/crypto/sha256.yo +9 -8
- package/std/encoding/base64.yo +13 -15
- package/std/encoding/hex.yo +14 -10
- package/std/encoding/html.yo +14 -11
- package/std/encoding/html_char_utils.yo +14 -11
- package/std/encoding/html_entities.yo +7 -8
- package/std/encoding/json.yo +36 -19
- package/std/encoding/punycode.yo +21 -18
- package/std/encoding/toml.yo +23 -9
- package/std/encoding/utf16.yo +16 -9
- package/std/error.yo +10 -23
- package/std/fmt/display.yo +15 -17
- package/std/fmt/index.yo +6 -27
- package/std/fmt/to_string.yo +4 -10
- package/std/fmt/writer.yo +33 -34
- package/std/fs/dir.yo +37 -30
- package/std/fs/file.yo +77 -75
- package/std/fs/metadata.yo +25 -25
- package/std/fs/temp.yo +21 -27
- package/std/fs/types.yo +20 -23
- package/std/fs/walker.yo +26 -31
- package/std/gc.yo +5 -0
- package/std/glob/index.yo +3 -0
- package/std/http/client.yo +25 -11
- package/std/http/http.yo +20 -0
- package/std/http/index.yo +1 -0
- package/std/io/reader.yo +4 -8
- package/std/io/writer.yo +4 -7
- package/std/libc/assert.yo +2 -2
- package/std/libc/ctype.yo +1 -2
- package/std/libc/dirent.yo +1 -2
- package/std/libc/errno.yo +1 -2
- package/std/libc/fcntl.yo +2 -2
- package/std/libc/float.yo +1 -2
- package/std/libc/limits.yo +1 -2
- package/std/libc/math.yo +2 -0
- package/std/libc/signal.yo +1 -2
- package/std/libc/stdatomic.yo +1 -2
- package/std/libc/stdint.yo +4 -3
- package/std/libc/stdio.yo +2 -0
- package/std/libc/stdlib.yo +2 -0
- package/std/libc/string.yo +2 -0
- package/std/libc/sys/stat.yo +1 -2
- package/std/libc/time.yo +2 -2
- package/std/libc/unistd.yo +2 -0
- package/std/libc/wctype.yo +1 -2
- package/std/libc/windows.yo +2 -2
- package/std/log/index.yo +11 -26
- package/std/net/addr.yo +18 -11
- package/std/net/dns.yo +3 -2
- package/std/net/errors.yo +16 -2
- package/std/net/tcp.yo +25 -22
- package/std/net/udp.yo +14 -12
- package/std/os/env.yo +23 -18
- package/std/os/signal.yo +31 -19
- package/std/path.yo +23 -74
- package/std/prelude.yo +284 -113
- package/std/process.yo +23 -37
- package/std/regex/compiler.yo +3 -5
- package/std/regex/flags.yo +11 -11
- package/std/regex/index.yo +2 -13
- package/std/regex/match.yo +3 -5
- package/std/regex/node.yo +6 -6
- package/std/regex/parser.yo +2 -4
- package/std/regex/unicode.yo +5 -5
- package/std/regex/vm.yo +5 -5
- package/std/string/index.yo +2 -1
- package/std/string/rune.yo +25 -1
- package/std/string/string.yo +31 -19
- package/std/string/unicode.yo +14 -15
- package/std/sync/channel.yo +18 -28
- package/std/sync/cond.yo +4 -0
- package/std/sync/mutex.yo +4 -1
- package/std/sync/once.yo +17 -19
- package/std/sync/rwlock.yo +19 -22
- package/std/sync/waitgroup.yo +21 -23
- package/std/sys/advise.yo +4 -4
- package/std/sys/bufio/buf_reader.yo +19 -16
- package/std/sys/bufio/buf_writer.yo +14 -11
- package/std/sys/clock.yo +4 -4
- package/std/sys/constants.yo +5 -5
- package/std/sys/copy.yo +9 -8
- package/std/sys/dir.yo +9 -8
- package/std/sys/dns.yo +8 -8
- package/std/sys/errors.yo +35 -6
- package/std/sys/events.yo +3 -3
- package/std/sys/externs.yo +3 -3
- package/std/sys/fallocate.yo +4 -4
- package/std/sys/fcntl.yo +8 -6
- package/std/sys/file.yo +7 -8
- package/std/sys/future.yo +1 -3
- package/std/sys/iov.yo +4 -4
- package/std/sys/lock.yo +7 -7
- package/std/sys/mmap.yo +7 -8
- package/std/sys/path.yo +4 -7
- package/std/sys/perm.yo +8 -8
- package/std/sys/pipe.yo +9 -8
- package/std/sys/process.yo +8 -8
- package/std/sys/seek.yo +4 -4
- package/std/sys/signal.yo +4 -4
- package/std/sys/signals.yo +4 -4
- package/std/sys/socket.yo +4 -4
- package/std/sys/socketpair.yo +4 -4
- package/std/sys/sockinfo.yo +4 -4
- package/std/sys/statfs.yo +8 -8
- package/std/sys/statx.yo +4 -4
- package/std/sys/sysinfo.yo +4 -4
- package/std/sys/tcp.yo +8 -8
- package/std/sys/temp.yo +9 -8
- package/std/sys/time.yo +8 -8
- package/std/sys/timer.yo +7 -8
- package/std/sys/tty.yo +13 -10
- package/std/sys/udp.yo +8 -8
- package/std/sys/umask.yo +4 -4
- package/std/sys/unix.yo +5 -5
- package/std/testing/bench.yo +21 -10
- package/std/thread.yo +18 -9
- package/std/time/datetime.yo +12 -14
- package/std/time/duration.yo +12 -14
- package/std/time/instant.yo +13 -16
- package/std/time/sleep.yo +9 -8
- package/std/url/index.yo +3 -19
- package/std/worker.yo +10 -18
package/std/fs/file.yo
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
//! Async file I/O operations with Exception-based error handling.
|
|
2
|
+
//!
|
|
3
|
+
//! Wraps a file descriptor with typed async I/O operations.
|
|
4
|
+
//! Uses the `Exception` effect for error handling.
|
|
5
|
+
//!
|
|
6
|
+
//! Example:
|
|
7
|
+
//! { File, read_string, write_file, OpenMode } :: import "std/fs/file";
|
|
8
|
+
//!
|
|
9
|
+
//! main :: (fn(using(io : IO)) -> unit)({
|
|
10
|
+
//! given(exn) := Exception(
|
|
11
|
+
//! throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
12
|
+
//! { println(error); panic("Exception found."); }
|
|
13
|
+
//! )
|
|
14
|
+
//! );
|
|
15
|
+
//!
|
|
16
|
+
//! // Write a file
|
|
17
|
+
//! io.await(write_file(Path.new(`test.txt`), `hello world`));
|
|
18
|
+
//!
|
|
19
|
+
//! // Read it back
|
|
20
|
+
//! content := io.await(read_string(Path.new(`test.txt`)));
|
|
21
|
+
//! println(content);
|
|
22
|
+
//!
|
|
23
|
+
//! // Open with OpenMode
|
|
24
|
+
//! f := io.await(File.open(Path.new(`test.txt`), .Read));
|
|
25
|
+
//! });
|
|
26
26
|
|
|
27
27
|
{ GlobalAllocator } :: import "../allocator";
|
|
28
28
|
{ malloc, free } :: GlobalAllocator;
|
|
@@ -49,6 +49,10 @@ IO_seek :: import "../sys/seek";
|
|
|
49
49
|
// File
|
|
50
50
|
// ============================================================================
|
|
51
51
|
|
|
52
|
+
/// An open file handle with async read/write operations.
|
|
53
|
+
///
|
|
54
|
+
/// Provides methods for reading, writing, seeking, and querying file metadata.
|
|
55
|
+
/// Files are automatically closed when disposed.
|
|
52
56
|
File :: object(
|
|
53
57
|
_fd : i32,
|
|
54
58
|
_path : Path,
|
|
@@ -56,7 +60,7 @@ File :: object(
|
|
|
56
60
|
);
|
|
57
61
|
|
|
58
62
|
impl(File,
|
|
59
|
-
|
|
63
|
+
/// Open a file at `path` with the given mode and custom permissions.
|
|
60
64
|
open_with : (fn(path: Path, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))({
|
|
61
65
|
flags := _open_mode_to_flags(mode);
|
|
62
66
|
file_mode := cond(
|
|
@@ -77,33 +81,33 @@ impl(File,
|
|
|
77
81
|
})
|
|
78
82
|
}),
|
|
79
83
|
|
|
80
|
-
|
|
84
|
+
/// Open a file from a `str` path with the given mode and custom permissions.
|
|
81
85
|
open_with_str : (fn(path: str, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
82
86
|
File.open_with(Path.new(String.from(path)), mode, perm)
|
|
83
87
|
),
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
/// Open a file from a C string path with the given mode and custom permissions.
|
|
86
90
|
open_with_cstr : (fn(path: *(u8), mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
87
91
|
File.open_with(Path.from_cstr(path), mode, perm)
|
|
88
92
|
),
|
|
89
93
|
|
|
90
|
-
|
|
94
|
+
/// Open a file at `path` with the given mode and default permissions (0o644).
|
|
91
95
|
open : (fn(path: Path, mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
92
96
|
File.open_with(path, mode, FilePermission.default())
|
|
93
97
|
),
|
|
94
98
|
|
|
95
|
-
|
|
99
|
+
/// Open a file from a `str` path with the given mode and default permissions.
|
|
96
100
|
open_str : (fn(path: str, mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
97
101
|
File.open(Path.new(String.from(path)), mode)
|
|
98
102
|
),
|
|
99
103
|
|
|
100
|
-
|
|
104
|
+
/// Open a file from a C string path with the given mode and default permissions.
|
|
101
105
|
open_cstr : (fn(path: *(u8), mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
102
106
|
File.open(Path.from_cstr(path), mode)
|
|
103
107
|
),
|
|
104
108
|
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
/// Read up to `size` bytes into the buffer `buf`.
|
|
110
|
+
/// Returns the number of bytes actually read.
|
|
107
111
|
read : (fn(self: Self, buf: *(u8), size: u32, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
108
112
|
fd := self._fd;
|
|
109
113
|
io.async((using(io, exn)) => {
|
|
@@ -112,8 +116,8 @@ impl(File,
|
|
|
112
116
|
})
|
|
113
117
|
}),
|
|
114
118
|
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
/// Write a `String` to the file.
|
|
120
|
+
/// Returns the number of bytes written.
|
|
117
121
|
write_string : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
118
122
|
fd := self._fd;
|
|
119
123
|
io.async((using(io, exn)) => {
|
|
@@ -128,8 +132,8 @@ impl(File,
|
|
|
128
132
|
})
|
|
129
133
|
}),
|
|
130
134
|
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
/// Write bytes from an `ArrayList(u8)` to the file.
|
|
136
|
+
/// Returns the number of bytes written.
|
|
133
137
|
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
134
138
|
fd := self._fd;
|
|
135
139
|
io.async((using(io, exn)) =>
|
|
@@ -143,7 +147,7 @@ impl(File,
|
|
|
143
147
|
)
|
|
144
148
|
}),
|
|
145
149
|
|
|
146
|
-
|
|
150
|
+
/// Read the entire file contents into an `ArrayList(u8)`.
|
|
147
151
|
read_bytes : (fn(self: Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
|
|
148
152
|
fd := self._fd;
|
|
149
153
|
io.async((using(io, exn)) => {
|
|
@@ -174,7 +178,7 @@ impl(File,
|
|
|
174
178
|
})
|
|
175
179
|
}),
|
|
176
180
|
|
|
177
|
-
|
|
181
|
+
/// Read the entire file contents into a `String`.
|
|
178
182
|
read_string : (fn(self: Self, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
179
183
|
io.async((using(io, exn)) => {
|
|
180
184
|
bytes := io.await(self.read_bytes());
|
|
@@ -182,7 +186,7 @@ impl(File,
|
|
|
182
186
|
})
|
|
183
187
|
),
|
|
184
188
|
|
|
185
|
-
|
|
189
|
+
/// Flush (fsync) file data to disk.
|
|
186
190
|
flush : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
187
191
|
fd := self._fd;
|
|
188
192
|
io.async((using(io, exn)) => {
|
|
@@ -194,7 +198,7 @@ impl(File,
|
|
|
194
198
|
})
|
|
195
199
|
}),
|
|
196
200
|
|
|
197
|
-
|
|
201
|
+
/// Seek to a position relative to `from`. Returns the new absolute byte offset.
|
|
198
202
|
seek : (fn(self: Self, offset: i64, from: SeekFrom, using(exn : Exception)) -> i64)({
|
|
199
203
|
result := IO_seek.lseek(self._fd, offset, _seek_from_to_whence(from));
|
|
200
204
|
cond(
|
|
@@ -203,17 +207,17 @@ impl(File,
|
|
|
203
207
|
)
|
|
204
208
|
}),
|
|
205
209
|
|
|
206
|
-
|
|
210
|
+
/// Get the current file position (byte offset from the beginning).
|
|
207
211
|
position : (fn(self: Self) -> i64)(
|
|
208
212
|
IO_seek.lseek(self._fd, i64(0), IO_seek.SEEK_CUR)
|
|
209
213
|
),
|
|
210
214
|
|
|
211
|
-
|
|
215
|
+
/// Get the file size in bytes.
|
|
212
216
|
size : (fn(self: Self) -> i64)(
|
|
213
217
|
IO_file.file_size(self._fd)
|
|
214
218
|
),
|
|
215
219
|
|
|
216
|
-
|
|
220
|
+
/// Close the file descriptor. Safe to call multiple times.
|
|
217
221
|
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
218
222
|
fd := self._fd;
|
|
219
223
|
io.async((using(io, exn)) =>
|
|
@@ -231,17 +235,17 @@ impl(File,
|
|
|
231
235
|
)
|
|
232
236
|
}),
|
|
233
237
|
|
|
234
|
-
|
|
238
|
+
/// Get the underlying file descriptor.
|
|
235
239
|
fd : (fn(self: Self) -> i32)(
|
|
236
240
|
self._fd
|
|
237
241
|
),
|
|
238
242
|
|
|
239
|
-
|
|
243
|
+
/// Get the path this file was opened with.
|
|
240
244
|
path : (fn(self: Self) -> Path)(
|
|
241
245
|
self._path
|
|
242
246
|
),
|
|
243
247
|
|
|
244
|
-
|
|
248
|
+
/// Get file metadata (size, permissions, timestamps).
|
|
245
249
|
metadata : (fn(self: Self, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(
|
|
246
250
|
_metadata_mod.metadata(self._path)
|
|
247
251
|
)
|
|
@@ -265,7 +269,7 @@ export File, OpenMode, FilePermission, SeekFrom;
|
|
|
265
269
|
// Convenience functions
|
|
266
270
|
// ============================================================================
|
|
267
271
|
|
|
268
|
-
|
|
272
|
+
/// Read an entire file into a `String`.
|
|
269
273
|
read_string :: (fn(path: Path, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
270
274
|
io.async((using(io, exn)) => {
|
|
271
275
|
file := io.await(File.open(path, .Read));
|
|
@@ -275,17 +279,17 @@ read_string :: (fn(path: Path, using(io : IO)) -> Impl(Future(String, IO, Except
|
|
|
275
279
|
})
|
|
276
280
|
);
|
|
277
281
|
|
|
278
|
-
|
|
282
|
+
/// Read an entire file into a `String` (`str` path variant).
|
|
279
283
|
read_string_str :: (fn(path: str, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
280
284
|
read_string(Path.new(String.from(path)))
|
|
281
285
|
);
|
|
282
286
|
|
|
283
|
-
|
|
287
|
+
/// Read an entire file into a `String` (C string path variant).
|
|
284
288
|
read_string_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
285
289
|
read_string(Path.from_cstr(path))
|
|
286
290
|
);
|
|
287
291
|
|
|
288
|
-
|
|
292
|
+
/// Read an entire file into a byte list (`ArrayList(u8)`).
|
|
289
293
|
read_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
290
294
|
io.async((using(io, exn)) => {
|
|
291
295
|
file := io.await(File.open(path, .Read));
|
|
@@ -295,17 +299,17 @@ read_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, E
|
|
|
295
299
|
})
|
|
296
300
|
);
|
|
297
301
|
|
|
298
|
-
|
|
302
|
+
/// Read an entire file into bytes (`str` path variant).
|
|
299
303
|
read_file_str :: (fn(path: str, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
300
304
|
read_file(Path.new(String.from(path)))
|
|
301
305
|
);
|
|
302
306
|
|
|
303
|
-
|
|
307
|
+
/// Read an entire file into bytes (C string path variant).
|
|
304
308
|
read_file_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
305
309
|
read_file(Path.from_cstr(path))
|
|
306
310
|
);
|
|
307
311
|
|
|
308
|
-
|
|
312
|
+
/// Write a `String` to a file, creating or truncating it.
|
|
309
313
|
write_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
310
314
|
io.async((using(io, exn)) => {
|
|
311
315
|
file := io.await(File.open(path, .Write));
|
|
@@ -314,17 +318,17 @@ write_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit,
|
|
|
314
318
|
})
|
|
315
319
|
);
|
|
316
320
|
|
|
317
|
-
|
|
321
|
+
/// Write a `str` to a file, creating or truncating it (`str` path variant).
|
|
318
322
|
write_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
319
323
|
write_file(Path.new(String.from(path)), String.from(data))
|
|
320
324
|
);
|
|
321
325
|
|
|
322
|
-
|
|
326
|
+
/// Write a `str` to a file, creating or truncating it (C string path variant).
|
|
323
327
|
write_file_cstr :: (fn(path: *(u8), data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
324
328
|
write_file(Path.from_cstr(path), String.from(data))
|
|
325
329
|
);
|
|
326
330
|
|
|
327
|
-
|
|
331
|
+
/// Write bytes to a file, creating or truncating it.
|
|
328
332
|
write_bytes :: (fn(path: Path, data: ArrayList(u8), using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
329
333
|
io.async((using(io, exn)) => {
|
|
330
334
|
file := io.await(File.open(path, .Write));
|
|
@@ -333,7 +337,7 @@ write_bytes :: (fn(path: Path, data: ArrayList(u8), using(io : IO)) -> Impl(Futu
|
|
|
333
337
|
})
|
|
334
338
|
);
|
|
335
339
|
|
|
336
|
-
|
|
340
|
+
/// Append a `String` to a file, creating it if it does not exist.
|
|
337
341
|
append_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
338
342
|
io.async((using(io, exn)) => {
|
|
339
343
|
file := io.await(File.open(path, .Append));
|
|
@@ -342,7 +346,7 @@ append_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit
|
|
|
342
346
|
})
|
|
343
347
|
);
|
|
344
348
|
|
|
345
|
-
|
|
349
|
+
/// Append a `str` to a file (`str` path variant).
|
|
346
350
|
append_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
347
351
|
append_file(Path.new(String.from(path)), String.from(data))
|
|
348
352
|
);
|
|
@@ -351,8 +355,8 @@ extern "Yo",
|
|
|
351
355
|
__yo_statx_buf_size : (fn() -> usize)
|
|
352
356
|
;
|
|
353
357
|
|
|
354
|
-
|
|
355
|
-
|
|
358
|
+
/// Check if a path exists. Returns `false` for any error including file not found.
|
|
359
|
+
/// Does not use the `Exception` effect.
|
|
356
360
|
exists :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
357
361
|
io.async((using(io : IO)) => {
|
|
358
362
|
cstr_bytes := path.to_string().to_cstr();
|
|
@@ -365,18 +369,17 @@ exists :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
365
369
|
})
|
|
366
370
|
);
|
|
367
371
|
|
|
368
|
-
|
|
372
|
+
/// Check if a path exists (`str` path variant).
|
|
369
373
|
exists_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
370
374
|
exists(Path.new(String.from(path)), using(io))
|
|
371
375
|
);
|
|
372
376
|
|
|
373
|
-
|
|
377
|
+
/// Check if a path exists (C string path variant).
|
|
374
378
|
exists_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
375
379
|
exists(Path.from_cstr(path), using(io))
|
|
376
380
|
);
|
|
377
381
|
|
|
378
|
-
|
|
379
|
-
// Returns false for any error (including file not found).
|
|
382
|
+
/// Check if a path is a regular file. Returns `false` for any error.
|
|
380
383
|
is_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
381
384
|
io.async((using(io : IO)) => {
|
|
382
385
|
path_str := path.to_string();
|
|
@@ -397,18 +400,17 @@ is_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
397
400
|
})
|
|
398
401
|
);
|
|
399
402
|
|
|
400
|
-
|
|
403
|
+
/// Check if a path is a regular file (`str` path variant).
|
|
401
404
|
is_file_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
402
405
|
is_file(Path.new(String.from(path)), using(io))
|
|
403
406
|
);
|
|
404
407
|
|
|
405
|
-
|
|
408
|
+
/// Check if a path is a regular file (C string path variant).
|
|
406
409
|
is_file_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
407
410
|
is_file(Path.from_cstr(path), using(io))
|
|
408
411
|
);
|
|
409
412
|
|
|
410
|
-
|
|
411
|
-
// Returns false for any error (including file not found).
|
|
413
|
+
/// Check if a path is a directory. Returns `false` for any error.
|
|
412
414
|
is_dir :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
413
415
|
io.async((using(io : IO)) => {
|
|
414
416
|
path_str := path.to_string();
|
|
@@ -429,18 +431,18 @@ is_dir :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
429
431
|
})
|
|
430
432
|
);
|
|
431
433
|
|
|
432
|
-
|
|
434
|
+
/// Check if a path is a directory (`str` path variant).
|
|
433
435
|
is_dir_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
434
436
|
is_dir(Path.new(String.from(path)), using(io))
|
|
435
437
|
);
|
|
436
438
|
|
|
437
|
-
|
|
439
|
+
/// Check if a path is a directory (C string path variant).
|
|
438
440
|
is_dir_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
439
441
|
is_dir(Path.from_cstr(path), using(io))
|
|
440
442
|
);
|
|
441
443
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
+
/// Resolve a path to its canonical absolute form (resolves symlinks, `.` and `..`).
|
|
445
|
+
/// Throws if the path does not exist.
|
|
444
446
|
canonical :: (fn(path: Path, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
445
447
|
io.async((using(io, exn)) => {
|
|
446
448
|
path_str := path.to_string();
|
|
@@ -468,12 +470,12 @@ canonical :: (fn(path: Path, using(io : IO)) -> Impl(Future(Path, IO, Exception)
|
|
|
468
470
|
})
|
|
469
471
|
);
|
|
470
472
|
|
|
471
|
-
|
|
473
|
+
/// Resolve a path to its canonical absolute form (`str` path variant).
|
|
472
474
|
canonical_str :: (fn(path: str, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
473
475
|
canonical(Path.new(String.from(path)))
|
|
474
476
|
);
|
|
475
477
|
|
|
476
|
-
|
|
478
|
+
/// Resolve a path to its canonical absolute form (C string path variant).
|
|
477
479
|
canonical_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
478
480
|
canonical(Path.from_cstr(path))
|
|
479
481
|
);
|
package/std/fs/metadata.yo
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
//! File metadata via `statx` with ergonomic accessors.
|
|
2
|
+
//! Uses the Exception effect for error handling.
|
|
3
|
+
//!
|
|
4
|
+
//! # Example
|
|
5
|
+
//!
|
|
6
|
+
//! ```rust
|
|
7
|
+
//! { metadata } :: import "std/fs/metadata";
|
|
8
|
+
//!
|
|
9
|
+
//! main :: (fn(using(io : IO)) -> unit)({
|
|
10
|
+
//! given(exn) : Exception = {
|
|
11
|
+
//! throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
12
|
+
//! { println(error.to_string()); exit(i32(1)); }
|
|
13
|
+
//! )
|
|
14
|
+
//! };
|
|
15
|
+
//!
|
|
16
|
+
//! m := io.await(metadata(Path.new(`/tmp/test.txt`)));
|
|
17
|
+
//! printf("size: %lld\n", m.size());
|
|
18
|
+
//! printf("is file: %d\n", i32(m.is_file()));
|
|
19
|
+
//! });
|
|
20
|
+
//! ```
|
|
20
21
|
|
|
21
22
|
{ GlobalAllocator } :: import "../allocator";
|
|
22
23
|
{ malloc, free } :: GlobalAllocator;
|
|
@@ -32,10 +33,7 @@ IO_file :: import "../sys/file";
|
|
|
32
33
|
S_IWUSR, S_IWGRP, S_IWOTH
|
|
33
34
|
} :: import "../sys/constants";
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
// Metadata
|
|
37
|
-
// ============================================================================
|
|
38
|
-
|
|
36
|
+
/// File metadata wrapper around `Statx`.
|
|
39
37
|
Metadata :: object(
|
|
40
38
|
_statx : Statx,
|
|
41
39
|
_buf_ptr : *(u8)
|
|
@@ -149,20 +147,22 @@ _stat_path :: (fn(path: Path, flags: i32, using(io : IO)) -> Impl(Future(Metadat
|
|
|
149
147
|
})
|
|
150
148
|
);
|
|
151
149
|
|
|
152
|
-
|
|
150
|
+
/// Get metadata for a path (follows symlinks).
|
|
153
151
|
metadata :: (fn(path: Path, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))
|
|
154
152
|
_stat_path(path, AT_STATX_SYNC_AS_STAT)
|
|
155
153
|
;
|
|
156
154
|
|
|
155
|
+
/// Get metadata for a path given as a raw string (follows symlinks).
|
|
157
156
|
metadata_str :: (fn(path: str, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))
|
|
158
157
|
metadata(Path.new(String.from(path)))
|
|
159
158
|
;
|
|
160
159
|
|
|
161
|
-
|
|
160
|
+
/// Get metadata for a path (does NOT follow symlinks).
|
|
162
161
|
symlink_metadata :: (fn(path: Path, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))
|
|
163
162
|
_stat_path(path, (AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT))
|
|
164
163
|
;
|
|
165
164
|
|
|
165
|
+
/// Get metadata for a path given as a raw string (does NOT follow symlinks).
|
|
166
166
|
symlink_metadata_str :: (fn(path: str, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))
|
|
167
167
|
symlink_metadata(Path.new(String.from(path)))
|
|
168
168
|
;
|
package/std/fs/temp.yo
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
//! RAII-managed temporary files and directories.
|
|
2
|
+
//!
|
|
3
|
+
//! # Example
|
|
4
|
+
//!
|
|
5
|
+
//! ```rust
|
|
6
|
+
//! { TempDir } :: import "std/fs/temp";
|
|
7
|
+
//!
|
|
8
|
+
//! main :: (fn(using(io : IO)) -> unit)({
|
|
9
|
+
//! given(exn) : Exception = {
|
|
10
|
+
//! throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
11
|
+
//! { println(error.to_string()); exit(i32(1)); }
|
|
12
|
+
//! )
|
|
13
|
+
//! };
|
|
14
|
+
//!
|
|
15
|
+
//! dir := io.await(TempDir.new());
|
|
16
|
+
//! println(dir.path());
|
|
17
|
+
//! io.await(dir.remove());
|
|
18
|
+
//! });
|
|
19
|
+
//! ```
|
|
20
20
|
|
|
21
21
|
{ GlobalAllocator } :: import "../allocator";
|
|
22
22
|
{ malloc, free } :: GlobalAllocator;
|
|
@@ -52,10 +52,7 @@ _default_tmp_dir :: (fn() -> String)(
|
|
|
52
52
|
);
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
// TempDir
|
|
57
|
-
// ============================================================================
|
|
58
|
-
|
|
55
|
+
/// Temporary directory that can be cleaned up with `remove`.
|
|
59
56
|
TempDir :: object(
|
|
60
57
|
_path : Path,
|
|
61
58
|
_removed : bool
|
|
@@ -115,10 +112,7 @@ impl(TempDir,
|
|
|
115
112
|
|
|
116
113
|
export TempDir;
|
|
117
114
|
|
|
118
|
-
|
|
119
|
-
// TempFile
|
|
120
|
-
// ============================================================================
|
|
121
|
-
|
|
115
|
+
/// Temporary file backed by a `File` handle.
|
|
122
116
|
TempFile :: object(
|
|
123
117
|
_file : _file_mod.File,
|
|
124
118
|
_path : Path,
|
package/std/fs/types.yo
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
// OpenMode and FilePermission for typed file operations.
|
|
1
|
+
//! File system types for open modes, permissions, and seek positions.
|
|
4
2
|
|
|
5
3
|
{
|
|
6
4
|
O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND,
|
|
7
5
|
O_EXCL, O_CLOEXEC, DEFAULT_FILE_MODE
|
|
8
6
|
} :: import "../sys/constants";
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
// OpenMode — determines how a file is opened
|
|
12
|
-
// ============================================================================
|
|
13
|
-
|
|
8
|
+
/// Determines how a file is opened.
|
|
14
9
|
OpenMode :: enum(
|
|
15
|
-
Read
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
/// Read an existing file (O_RDONLY).
|
|
11
|
+
Read,
|
|
12
|
+
/// Create or overwrite a file (O_WRONLY | O_CREAT | O_TRUNC).
|
|
13
|
+
Write,
|
|
14
|
+
/// Append to a file (O_WRONLY | O_CREAT | O_APPEND).
|
|
15
|
+
Append,
|
|
16
|
+
/// Read and write an existing file (O_RDWR).
|
|
17
|
+
ReadWrite,
|
|
18
|
+
/// Create a new file, fail if it already exists (O_WRONLY | O_CREAT | O_EXCL).
|
|
19
|
+
CreateNew
|
|
20
20
|
);
|
|
21
21
|
|
|
22
22
|
// Convert OpenMode to POSIX open flags.
|
|
@@ -45,10 +45,7 @@ _open_mode_needs_perm :: (fn(mode: OpenMode) -> bool)(
|
|
|
45
45
|
|
|
46
46
|
export OpenMode, _open_mode_to_flags, _open_mode_needs_perm;
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
// FilePermission — POSIX file permission bits
|
|
50
|
-
// ============================================================================
|
|
51
|
-
|
|
48
|
+
/// POSIX file permission bits.
|
|
52
49
|
FilePermission :: newtype(
|
|
53
50
|
mode : u32
|
|
54
51
|
);
|
|
@@ -77,14 +74,14 @@ impl(FilePermission,
|
|
|
77
74
|
|
|
78
75
|
export FilePermission;
|
|
79
76
|
|
|
80
|
-
|
|
81
|
-
// SeekFrom — file seek position reference
|
|
82
|
-
// ============================================================================
|
|
83
|
-
|
|
77
|
+
/// Reference point for file seek operations.
|
|
84
78
|
SeekFrom :: enum(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
/// Seek from the beginning of the file.
|
|
80
|
+
Start,
|
|
81
|
+
/// Seek relative to the current position.
|
|
82
|
+
Current,
|
|
83
|
+
/// Seek relative to the end of the file.
|
|
84
|
+
End
|
|
88
85
|
);
|
|
89
86
|
|
|
90
87
|
// Convert SeekFrom to POSIX whence constant (i32).
|