@shd101wyy/yo 0.1.12 → 0.1.14
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 +578 -572
- package/out/cjs/yo-cli.cjs +1447 -529
- package/out/esm/index.mjs +434 -428
- 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 +27 -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/expr.d.ts +2 -1
- 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 +498 -0
- package/std/alg/hash.yo +12 -24
- package/std/allocator.yo +21 -29
- package/std/async.yo +4 -2
- package/std/build.yo +192 -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 +16 -15
- package/std/encoding/hex.yo +17 -10
- package/std/encoding/html.yo +17 -11
- package/std/encoding/html_char_utils.yo +14 -11
- package/std/encoding/html_entities.yo +7 -8
- package/std/encoding/json.yo +39 -19
- package/std/encoding/punycode.yo +24 -18
- package/std/encoding/toml.yo +26 -9
- package/std/encoding/utf16.yo +19 -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 +40 -30
- package/std/fs/file.yo +80 -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 +31 -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,31 @@
|
|
|
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
|
+
//!
|
|
8
|
+
//! ```rust
|
|
9
|
+
//! { File, read_string, write_file, OpenMode } :: import "std/fs/file";
|
|
10
|
+
//!
|
|
11
|
+
//! main :: (fn(using(io : IO)) -> unit)({
|
|
12
|
+
//! given(exn) := Exception(
|
|
13
|
+
//! throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
14
|
+
//! { println(error); panic("Exception found."); }
|
|
15
|
+
//! )
|
|
16
|
+
//! );
|
|
17
|
+
//!
|
|
18
|
+
//! // Write a file
|
|
19
|
+
//! io.await(write_file(Path.new(`test.txt`), `hello world`));
|
|
20
|
+
//!
|
|
21
|
+
//! // Read it back
|
|
22
|
+
//! content := io.await(read_string(Path.new(`test.txt`)));
|
|
23
|
+
//! println(content);
|
|
24
|
+
//!
|
|
25
|
+
//! // Open with OpenMode
|
|
26
|
+
//! f := io.await(File.open(Path.new(`test.txt`), .Read));
|
|
27
|
+
//! });
|
|
28
|
+
//! ```
|
|
26
29
|
|
|
27
30
|
{ GlobalAllocator } :: import "../allocator";
|
|
28
31
|
{ malloc, free } :: GlobalAllocator;
|
|
@@ -49,6 +52,10 @@ IO_seek :: import "../sys/seek";
|
|
|
49
52
|
// File
|
|
50
53
|
// ============================================================================
|
|
51
54
|
|
|
55
|
+
/// An open file handle with async read/write operations.
|
|
56
|
+
///
|
|
57
|
+
/// Provides methods for reading, writing, seeking, and querying file metadata.
|
|
58
|
+
/// Files are automatically closed when disposed.
|
|
52
59
|
File :: object(
|
|
53
60
|
_fd : i32,
|
|
54
61
|
_path : Path,
|
|
@@ -56,7 +63,7 @@ File :: object(
|
|
|
56
63
|
);
|
|
57
64
|
|
|
58
65
|
impl(File,
|
|
59
|
-
|
|
66
|
+
/// Open a file at `path` with the given mode and custom permissions.
|
|
60
67
|
open_with : (fn(path: Path, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))({
|
|
61
68
|
flags := _open_mode_to_flags(mode);
|
|
62
69
|
file_mode := cond(
|
|
@@ -77,33 +84,33 @@ impl(File,
|
|
|
77
84
|
})
|
|
78
85
|
}),
|
|
79
86
|
|
|
80
|
-
|
|
87
|
+
/// Open a file from a `str` path with the given mode and custom permissions.
|
|
81
88
|
open_with_str : (fn(path: str, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
82
89
|
File.open_with(Path.new(String.from(path)), mode, perm)
|
|
83
90
|
),
|
|
84
91
|
|
|
85
|
-
|
|
92
|
+
/// Open a file from a C string path with the given mode and custom permissions.
|
|
86
93
|
open_with_cstr : (fn(path: *(u8), mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
87
94
|
File.open_with(Path.from_cstr(path), mode, perm)
|
|
88
95
|
),
|
|
89
96
|
|
|
90
|
-
|
|
97
|
+
/// Open a file at `path` with the given mode and default permissions (0o644).
|
|
91
98
|
open : (fn(path: Path, mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
92
99
|
File.open_with(path, mode, FilePermission.default())
|
|
93
100
|
),
|
|
94
101
|
|
|
95
|
-
|
|
102
|
+
/// Open a file from a `str` path with the given mode and default permissions.
|
|
96
103
|
open_str : (fn(path: str, mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
97
104
|
File.open(Path.new(String.from(path)), mode)
|
|
98
105
|
),
|
|
99
106
|
|
|
100
|
-
|
|
107
|
+
/// Open a file from a C string path with the given mode and default permissions.
|
|
101
108
|
open_cstr : (fn(path: *(u8), mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
102
109
|
File.open(Path.from_cstr(path), mode)
|
|
103
110
|
),
|
|
104
111
|
|
|
105
|
-
|
|
106
|
-
|
|
112
|
+
/// Read up to `size` bytes into the buffer `buf`.
|
|
113
|
+
/// Returns the number of bytes actually read.
|
|
107
114
|
read : (fn(self: Self, buf: *(u8), size: u32, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
108
115
|
fd := self._fd;
|
|
109
116
|
io.async((using(io, exn)) => {
|
|
@@ -112,8 +119,8 @@ impl(File,
|
|
|
112
119
|
})
|
|
113
120
|
}),
|
|
114
121
|
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
/// Write a `String` to the file.
|
|
123
|
+
/// Returns the number of bytes written.
|
|
117
124
|
write_string : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
118
125
|
fd := self._fd;
|
|
119
126
|
io.async((using(io, exn)) => {
|
|
@@ -128,8 +135,8 @@ impl(File,
|
|
|
128
135
|
})
|
|
129
136
|
}),
|
|
130
137
|
|
|
131
|
-
|
|
132
|
-
|
|
138
|
+
/// Write bytes from an `ArrayList(u8)` to the file.
|
|
139
|
+
/// Returns the number of bytes written.
|
|
133
140
|
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
134
141
|
fd := self._fd;
|
|
135
142
|
io.async((using(io, exn)) =>
|
|
@@ -143,7 +150,7 @@ impl(File,
|
|
|
143
150
|
)
|
|
144
151
|
}),
|
|
145
152
|
|
|
146
|
-
|
|
153
|
+
/// Read the entire file contents into an `ArrayList(u8)`.
|
|
147
154
|
read_bytes : (fn(self: Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
|
|
148
155
|
fd := self._fd;
|
|
149
156
|
io.async((using(io, exn)) => {
|
|
@@ -174,7 +181,7 @@ impl(File,
|
|
|
174
181
|
})
|
|
175
182
|
}),
|
|
176
183
|
|
|
177
|
-
|
|
184
|
+
/// Read the entire file contents into a `String`.
|
|
178
185
|
read_string : (fn(self: Self, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
179
186
|
io.async((using(io, exn)) => {
|
|
180
187
|
bytes := io.await(self.read_bytes());
|
|
@@ -182,7 +189,7 @@ impl(File,
|
|
|
182
189
|
})
|
|
183
190
|
),
|
|
184
191
|
|
|
185
|
-
|
|
192
|
+
/// Flush (fsync) file data to disk.
|
|
186
193
|
flush : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
187
194
|
fd := self._fd;
|
|
188
195
|
io.async((using(io, exn)) => {
|
|
@@ -194,7 +201,7 @@ impl(File,
|
|
|
194
201
|
})
|
|
195
202
|
}),
|
|
196
203
|
|
|
197
|
-
|
|
204
|
+
/// Seek to a position relative to `from`. Returns the new absolute byte offset.
|
|
198
205
|
seek : (fn(self: Self, offset: i64, from: SeekFrom, using(exn : Exception)) -> i64)({
|
|
199
206
|
result := IO_seek.lseek(self._fd, offset, _seek_from_to_whence(from));
|
|
200
207
|
cond(
|
|
@@ -203,17 +210,17 @@ impl(File,
|
|
|
203
210
|
)
|
|
204
211
|
}),
|
|
205
212
|
|
|
206
|
-
|
|
213
|
+
/// Get the current file position (byte offset from the beginning).
|
|
207
214
|
position : (fn(self: Self) -> i64)(
|
|
208
215
|
IO_seek.lseek(self._fd, i64(0), IO_seek.SEEK_CUR)
|
|
209
216
|
),
|
|
210
217
|
|
|
211
|
-
|
|
218
|
+
/// Get the file size in bytes.
|
|
212
219
|
size : (fn(self: Self) -> i64)(
|
|
213
220
|
IO_file.file_size(self._fd)
|
|
214
221
|
),
|
|
215
222
|
|
|
216
|
-
|
|
223
|
+
/// Close the file descriptor. Safe to call multiple times.
|
|
217
224
|
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
218
225
|
fd := self._fd;
|
|
219
226
|
io.async((using(io, exn)) =>
|
|
@@ -231,17 +238,17 @@ impl(File,
|
|
|
231
238
|
)
|
|
232
239
|
}),
|
|
233
240
|
|
|
234
|
-
|
|
241
|
+
/// Get the underlying file descriptor.
|
|
235
242
|
fd : (fn(self: Self) -> i32)(
|
|
236
243
|
self._fd
|
|
237
244
|
),
|
|
238
245
|
|
|
239
|
-
|
|
246
|
+
/// Get the path this file was opened with.
|
|
240
247
|
path : (fn(self: Self) -> Path)(
|
|
241
248
|
self._path
|
|
242
249
|
),
|
|
243
250
|
|
|
244
|
-
|
|
251
|
+
/// Get file metadata (size, permissions, timestamps).
|
|
245
252
|
metadata : (fn(self: Self, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(
|
|
246
253
|
_metadata_mod.metadata(self._path)
|
|
247
254
|
)
|
|
@@ -265,7 +272,7 @@ export File, OpenMode, FilePermission, SeekFrom;
|
|
|
265
272
|
// Convenience functions
|
|
266
273
|
// ============================================================================
|
|
267
274
|
|
|
268
|
-
|
|
275
|
+
/// Read an entire file into a `String`.
|
|
269
276
|
read_string :: (fn(path: Path, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
270
277
|
io.async((using(io, exn)) => {
|
|
271
278
|
file := io.await(File.open(path, .Read));
|
|
@@ -275,17 +282,17 @@ read_string :: (fn(path: Path, using(io : IO)) -> Impl(Future(String, IO, Except
|
|
|
275
282
|
})
|
|
276
283
|
);
|
|
277
284
|
|
|
278
|
-
|
|
285
|
+
/// Read an entire file into a `String` (`str` path variant).
|
|
279
286
|
read_string_str :: (fn(path: str, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
280
287
|
read_string(Path.new(String.from(path)))
|
|
281
288
|
);
|
|
282
289
|
|
|
283
|
-
|
|
290
|
+
/// Read an entire file into a `String` (C string path variant).
|
|
284
291
|
read_string_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
285
292
|
read_string(Path.from_cstr(path))
|
|
286
293
|
);
|
|
287
294
|
|
|
288
|
-
|
|
295
|
+
/// Read an entire file into a byte list (`ArrayList(u8)`).
|
|
289
296
|
read_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
290
297
|
io.async((using(io, exn)) => {
|
|
291
298
|
file := io.await(File.open(path, .Read));
|
|
@@ -295,17 +302,17 @@ read_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, E
|
|
|
295
302
|
})
|
|
296
303
|
);
|
|
297
304
|
|
|
298
|
-
|
|
305
|
+
/// Read an entire file into bytes (`str` path variant).
|
|
299
306
|
read_file_str :: (fn(path: str, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
300
307
|
read_file(Path.new(String.from(path)))
|
|
301
308
|
);
|
|
302
309
|
|
|
303
|
-
|
|
310
|
+
/// Read an entire file into bytes (C string path variant).
|
|
304
311
|
read_file_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
305
312
|
read_file(Path.from_cstr(path))
|
|
306
313
|
);
|
|
307
314
|
|
|
308
|
-
|
|
315
|
+
/// Write a `String` to a file, creating or truncating it.
|
|
309
316
|
write_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
310
317
|
io.async((using(io, exn)) => {
|
|
311
318
|
file := io.await(File.open(path, .Write));
|
|
@@ -314,17 +321,17 @@ write_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit,
|
|
|
314
321
|
})
|
|
315
322
|
);
|
|
316
323
|
|
|
317
|
-
|
|
324
|
+
/// Write a `str` to a file, creating or truncating it (`str` path variant).
|
|
318
325
|
write_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
319
326
|
write_file(Path.new(String.from(path)), String.from(data))
|
|
320
327
|
);
|
|
321
328
|
|
|
322
|
-
|
|
329
|
+
/// Write a `str` to a file, creating or truncating it (C string path variant).
|
|
323
330
|
write_file_cstr :: (fn(path: *(u8), data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
324
331
|
write_file(Path.from_cstr(path), String.from(data))
|
|
325
332
|
);
|
|
326
333
|
|
|
327
|
-
|
|
334
|
+
/// Write bytes to a file, creating or truncating it.
|
|
328
335
|
write_bytes :: (fn(path: Path, data: ArrayList(u8), using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
329
336
|
io.async((using(io, exn)) => {
|
|
330
337
|
file := io.await(File.open(path, .Write));
|
|
@@ -333,7 +340,7 @@ write_bytes :: (fn(path: Path, data: ArrayList(u8), using(io : IO)) -> Impl(Futu
|
|
|
333
340
|
})
|
|
334
341
|
);
|
|
335
342
|
|
|
336
|
-
|
|
343
|
+
/// Append a `String` to a file, creating it if it does not exist.
|
|
337
344
|
append_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
338
345
|
io.async((using(io, exn)) => {
|
|
339
346
|
file := io.await(File.open(path, .Append));
|
|
@@ -342,7 +349,7 @@ append_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit
|
|
|
342
349
|
})
|
|
343
350
|
);
|
|
344
351
|
|
|
345
|
-
|
|
352
|
+
/// Append a `str` to a file (`str` path variant).
|
|
346
353
|
append_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
347
354
|
append_file(Path.new(String.from(path)), String.from(data))
|
|
348
355
|
);
|
|
@@ -351,8 +358,8 @@ extern "Yo",
|
|
|
351
358
|
__yo_statx_buf_size : (fn() -> usize)
|
|
352
359
|
;
|
|
353
360
|
|
|
354
|
-
|
|
355
|
-
|
|
361
|
+
/// Check if a path exists. Returns `false` for any error including file not found.
|
|
362
|
+
/// Does not use the `Exception` effect.
|
|
356
363
|
exists :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
357
364
|
io.async((using(io : IO)) => {
|
|
358
365
|
cstr_bytes := path.to_string().to_cstr();
|
|
@@ -365,18 +372,17 @@ exists :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
365
372
|
})
|
|
366
373
|
);
|
|
367
374
|
|
|
368
|
-
|
|
375
|
+
/// Check if a path exists (`str` path variant).
|
|
369
376
|
exists_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
370
377
|
exists(Path.new(String.from(path)), using(io))
|
|
371
378
|
);
|
|
372
379
|
|
|
373
|
-
|
|
380
|
+
/// Check if a path exists (C string path variant).
|
|
374
381
|
exists_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
375
382
|
exists(Path.from_cstr(path), using(io))
|
|
376
383
|
);
|
|
377
384
|
|
|
378
|
-
|
|
379
|
-
// Returns false for any error (including file not found).
|
|
385
|
+
/// Check if a path is a regular file. Returns `false` for any error.
|
|
380
386
|
is_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
381
387
|
io.async((using(io : IO)) => {
|
|
382
388
|
path_str := path.to_string();
|
|
@@ -397,18 +403,17 @@ is_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
397
403
|
})
|
|
398
404
|
);
|
|
399
405
|
|
|
400
|
-
|
|
406
|
+
/// Check if a path is a regular file (`str` path variant).
|
|
401
407
|
is_file_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
402
408
|
is_file(Path.new(String.from(path)), using(io))
|
|
403
409
|
);
|
|
404
410
|
|
|
405
|
-
|
|
411
|
+
/// Check if a path is a regular file (C string path variant).
|
|
406
412
|
is_file_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
407
413
|
is_file(Path.from_cstr(path), using(io))
|
|
408
414
|
);
|
|
409
415
|
|
|
410
|
-
|
|
411
|
-
// Returns false for any error (including file not found).
|
|
416
|
+
/// Check if a path is a directory. Returns `false` for any error.
|
|
412
417
|
is_dir :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
413
418
|
io.async((using(io : IO)) => {
|
|
414
419
|
path_str := path.to_string();
|
|
@@ -429,18 +434,18 @@ is_dir :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
429
434
|
})
|
|
430
435
|
);
|
|
431
436
|
|
|
432
|
-
|
|
437
|
+
/// Check if a path is a directory (`str` path variant).
|
|
433
438
|
is_dir_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
434
439
|
is_dir(Path.new(String.from(path)), using(io))
|
|
435
440
|
);
|
|
436
441
|
|
|
437
|
-
|
|
442
|
+
/// Check if a path is a directory (C string path variant).
|
|
438
443
|
is_dir_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
439
444
|
is_dir(Path.from_cstr(path), using(io))
|
|
440
445
|
);
|
|
441
446
|
|
|
442
|
-
|
|
443
|
-
|
|
447
|
+
/// Resolve a path to its canonical absolute form (resolves symlinks, `.` and `..`).
|
|
448
|
+
/// Throws if the path does not exist.
|
|
444
449
|
canonical :: (fn(path: Path, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
445
450
|
io.async((using(io, exn)) => {
|
|
446
451
|
path_str := path.to_string();
|
|
@@ -468,12 +473,12 @@ canonical :: (fn(path: Path, using(io : IO)) -> Impl(Future(Path, IO, Exception)
|
|
|
468
473
|
})
|
|
469
474
|
);
|
|
470
475
|
|
|
471
|
-
|
|
476
|
+
/// Resolve a path to its canonical absolute form (`str` path variant).
|
|
472
477
|
canonical_str :: (fn(path: str, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
473
478
|
canonical(Path.new(String.from(path)))
|
|
474
479
|
);
|
|
475
480
|
|
|
476
|
-
|
|
481
|
+
/// Resolve a path to its canonical absolute form (C string path variant).
|
|
477
482
|
canonical_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
478
483
|
canonical(Path.from_cstr(path))
|
|
479
484
|
);
|
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).
|