@shd101wyy/yo 0.1.25 → 0.1.27
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 +4 -4
- package/.github/skills/yo-async-effects/async-effects-recipes.md +40 -40
- package/.github/skills/yo-core-patterns/SKILL.md +1 -1
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +30 -26
- package/.github/skills/yo-project-workflow/SKILL.md +6 -3
- package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +34 -11
- package/.github/skills/yo-syntax/SKILL.md +7 -6
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +78 -60
- package/.github/skills/yo-wasm-integration/wasm-integration-cheatsheet.md +3 -3
- package/README.md +10 -8
- package/out/cjs/index.cjs +583 -567
- package/out/cjs/yo-cli.cjs +664 -632
- package/out/cjs/yo-lsp.cjs +510 -485
- package/out/esm/index.mjs +538 -522
- package/out/types/src/codegen/codegen-c.d.ts +2 -2
- package/out/types/src/codegen/functions/collection.d.ts +2 -2
- package/out/types/src/codegen/functions/context.d.ts +3 -2
- package/out/types/src/codegen/types/collection.d.ts +2 -2
- package/out/types/src/codegen/utils/index.d.ts +3 -1
- package/out/types/src/doc/builder.d.ts +2 -2
- package/out/types/src/evaluator/calls/closure-type.d.ts +2 -2
- package/out/types/src/evaluator/calls/record-type.d.ts +11 -0
- package/out/types/src/evaluator/context.d.ts +8 -9
- package/out/types/src/evaluator/index.d.ts +3 -3
- package/out/types/src/evaluator/types/record.d.ts +14 -0
- package/out/types/src/evaluator/types/validation.d.ts +2 -2
- package/out/types/src/evaluator/values/anonymous-module.d.ts +5 -5
- package/out/types/src/evaluator/values/impl.d.ts +1 -1
- package/out/types/src/expr.d.ts +1 -4
- package/out/types/src/formatter.d.ts +11 -0
- package/out/types/src/function-value.d.ts +1 -1
- package/out/types/src/lsp/document-manager.d.ts +1 -1
- package/out/types/src/lsp/formatting.d.ts +2 -0
- package/out/types/src/module-manager.d.ts +3 -3
- package/out/types/src/tests/formatter.test.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +3 -4
- package/out/types/src/types/definitions.d.ts +8 -19
- package/out/types/src/types/guards.d.ts +3 -3
- package/out/types/src/types/tags.d.ts +0 -1
- package/out/types/src/types/utils.d.ts +1 -1
- package/out/types/src/value-tag.d.ts +0 -1
- package/out/types/src/value.d.ts +6 -13
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/alg/hash.yo +13 -21
- package/std/allocator.yo +25 -40
- package/std/async.yo +3 -7
- package/std/build.yo +105 -151
- package/std/cli/arg_parser.yo +184 -169
- package/std/collections/array_list.yo +350 -314
- package/std/collections/btree_map.yo +142 -131
- package/std/collections/deque.yo +132 -128
- package/std/collections/hash_map.yo +542 -566
- package/std/collections/hash_set.yo +623 -687
- package/std/collections/linked_list.yo +275 -293
- package/std/collections/ordered_map.yo +113 -85
- package/std/collections/priority_queue.yo +73 -73
- package/std/crypto/md5.yo +191 -95
- package/std/crypto/random.yo +56 -64
- package/std/crypto/sha256.yo +151 -107
- package/std/encoding/base64.yo +87 -81
- package/std/encoding/hex.yo +43 -50
- package/std/encoding/html.yo +56 -81
- package/std/encoding/html_char_utils.yo +7 -13
- package/std/encoding/html_entities.yo +2248 -2253
- package/std/encoding/json.yo +316 -224
- package/std/encoding/punycode.yo +86 -116
- package/std/encoding/toml.yo +67 -66
- package/std/encoding/utf16.yo +37 -44
- package/std/env.yo +62 -91
- package/std/error.yo +12 -20
- package/std/fmt/display.yo +5 -9
- package/std/fmt/index.yo +8 -14
- package/std/fmt/to_string.yo +330 -315
- package/std/fmt/writer.yo +58 -87
- package/std/fs/dir.yo +83 -102
- package/std/fs/file.yo +147 -180
- package/std/fs/metadata.yo +45 -78
- package/std/fs/temp.yo +55 -65
- package/std/fs/types.yo +27 -40
- package/std/fs/walker.yo +53 -68
- package/std/gc.yo +5 -8
- package/std/glob.yo +30 -43
- package/std/http/client.yo +107 -120
- package/std/http/http.yo +106 -96
- package/std/http/index.yo +4 -6
- package/std/imm/list.yo +88 -93
- package/std/imm/map.yo +528 -464
- package/std/imm/set.yo +52 -57
- package/std/imm/sorted_map.yo +340 -286
- package/std/imm/sorted_set.yo +57 -63
- package/std/imm/string.yo +404 -345
- package/std/imm/vec.yo +173 -181
- package/std/io/reader.yo +3 -6
- package/std/io/writer.yo +4 -8
- package/std/libc/assert.yo +5 -9
- package/std/libc/ctype.yo +32 -22
- package/std/libc/dirent.yo +26 -25
- package/std/libc/errno.yo +164 -90
- package/std/libc/fcntl.yo +52 -45
- package/std/libc/float.yo +66 -44
- package/std/libc/limits.yo +42 -33
- package/std/libc/math.yo +53 -82
- package/std/libc/signal.yo +72 -47
- package/std/libc/stdatomic.yo +217 -188
- package/std/libc/stdint.yo +5 -29
- package/std/libc/stdio.yo +5 -29
- package/std/libc/stdlib.yo +32 -39
- package/std/libc/string.yo +5 -23
- package/std/libc/sys/stat.yo +58 -56
- package/std/libc/time.yo +5 -19
- package/std/libc/unistd.yo +5 -20
- package/std/libc/wctype.yo +6 -9
- package/std/libc/windows.yo +26 -30
- package/std/log.yo +41 -55
- package/std/net/addr.yo +102 -97
- package/std/net/dns.yo +27 -28
- package/std/net/errors.yo +50 -49
- package/std/net/tcp.yo +113 -124
- package/std/net/udp.yo +55 -66
- package/std/os/env.yo +35 -33
- package/std/os/signal.yo +15 -25
- package/std/path.yo +276 -311
- package/std/prelude.yo +6316 -4333
- package/std/process/command.yo +87 -103
- package/std/process/index.yo +12 -31
- package/std/regex/compiler.yo +196 -95
- package/std/regex/flags.yo +58 -39
- package/std/regex/index.yo +157 -173
- package/std/regex/match.yo +20 -31
- package/std/regex/node.yo +134 -152
- package/std/regex/parser.yo +283 -259
- package/std/regex/unicode.yo +172 -202
- package/std/regex/vm.yo +155 -171
- package/std/string/index.yo +5 -7
- package/std/string/rune.yo +45 -55
- package/std/string/string.yo +937 -964
- package/std/string/string_builder.yo +94 -104
- package/std/string/unicode.yo +46 -64
- package/std/sync/channel.yo +72 -73
- package/std/sync/cond.yo +31 -36
- package/std/sync/mutex.yo +30 -32
- package/std/sync/once.yo +13 -16
- package/std/sync/rwlock.yo +26 -31
- package/std/sync/waitgroup.yo +20 -25
- package/std/sys/advise.yo +16 -24
- package/std/sys/bufio/buf_reader.yo +77 -93
- package/std/sys/bufio/buf_writer.yo +52 -65
- package/std/sys/clock.yo +4 -9
- package/std/sys/constants.yo +77 -61
- package/std/sys/copy.yo +4 -10
- package/std/sys/dir.yo +26 -43
- package/std/sys/dns.yo +41 -61
- package/std/sys/errors.yo +95 -103
- package/std/sys/events.yo +45 -57
- package/std/sys/externs.yo +319 -267
- package/std/sys/fallocate.yo +7 -11
- package/std/sys/fcntl.yo +14 -22
- package/std/sys/file.yo +26 -40
- package/std/sys/future.yo +5 -8
- package/std/sys/iov.yo +12 -25
- package/std/sys/lock.yo +12 -13
- package/std/sys/mmap.yo +38 -43
- package/std/sys/path.yo +3 -8
- package/std/sys/perm.yo +7 -21
- package/std/sys/pipe.yo +5 -12
- package/std/sys/process.yo +23 -29
- package/std/sys/seek.yo +10 -12
- package/std/sys/signal.yo +7 -13
- package/std/sys/signals.yo +52 -35
- package/std/sys/socket.yo +63 -58
- package/std/sys/socketpair.yo +3 -6
- package/std/sys/sockinfo.yo +11 -20
- package/std/sys/statfs.yo +11 -34
- package/std/sys/statx.yo +25 -52
- package/std/sys/sysinfo.yo +15 -20
- package/std/sys/tcp.yo +62 -92
- package/std/sys/temp.yo +5 -9
- package/std/sys/time.yo +5 -15
- package/std/sys/timer.yo +6 -11
- package/std/sys/tty.yo +10 -18
- package/std/sys/udp.yo +22 -39
- package/std/sys/umask.yo +3 -6
- package/std/sys/unix.yo +33 -52
- package/std/testing/bench.yo +49 -52
- package/std/thread.yo +10 -15
- package/std/time/datetime.yo +105 -89
- package/std/time/duration.yo +43 -56
- package/std/time/instant.yo +13 -18
- package/std/time/sleep.yo +5 -9
- package/std/url/index.yo +184 -209
- package/std/worker.yo +6 -10
- package/out/types/src/evaluator/calls/module-type.d.ts +0 -11
- package/out/types/src/evaluator/types/module.d.ts +0 -19
package/std/fs/file.yo
CHANGED
|
@@ -26,45 +26,38 @@
|
|
|
26
26
|
//! f := io.await(File.open(Path.new(`test.txt`), .Read));
|
|
27
27
|
//! });
|
|
28
28
|
//! ```
|
|
29
|
-
|
|
30
|
-
{ GlobalAllocator } :: import "../allocator";
|
|
29
|
+
{ GlobalAllocator } :: import("../allocator");
|
|
31
30
|
{ malloc, free } :: GlobalAllocator;
|
|
32
|
-
{ ArrayList } :: import
|
|
33
|
-
open
|
|
34
|
-
open
|
|
35
|
-
{ Path } :: import
|
|
36
|
-
{ IOError } :: import
|
|
37
|
-
{ Error, AnyError, Exception } :: import
|
|
38
|
-
{ Metadata } :: import
|
|
39
|
-
_metadata_mod :: import
|
|
40
|
-
{ Statx } :: import
|
|
41
|
-
IO_path :: import
|
|
42
|
-
{ OpenMode, FilePermission, SeekFrom, _open_mode_to_flags, _open_mode_needs_perm, _seek_from_to_whence } :: import
|
|
43
|
-
IO_file :: import
|
|
44
|
-
IO_seek :: import
|
|
45
|
-
{
|
|
46
|
-
AT_FDCWD, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS,
|
|
47
|
-
O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND,
|
|
48
|
-
O_CLOEXEC, DEFAULT_FILE_MODE
|
|
49
|
-
} :: import "../sys/constants";
|
|
50
|
-
|
|
31
|
+
{ ArrayList } :: import("../collections/array_list");
|
|
32
|
+
open(import("../string"));
|
|
33
|
+
open(import("../fmt"));
|
|
34
|
+
{ Path } :: import("../path");
|
|
35
|
+
{ IOError } :: import("../sys/errors");
|
|
36
|
+
{ Error, AnyError, Exception } :: import("../error");
|
|
37
|
+
{ Metadata } :: import("./metadata");
|
|
38
|
+
_metadata_mod :: import("./metadata");
|
|
39
|
+
{ Statx } :: import("../sys/statx");
|
|
40
|
+
IO_path :: import("../sys/path");
|
|
41
|
+
{ OpenMode, FilePermission, SeekFrom, _open_mode_to_flags, _open_mode_needs_perm, _seek_from_to_whence } :: import("./types");
|
|
42
|
+
IO_file :: import("../sys/file");
|
|
43
|
+
IO_seek :: import("../sys/seek");
|
|
44
|
+
{ AT_FDCWD, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND, O_CLOEXEC, DEFAULT_FILE_MODE } :: import("../sys/constants");
|
|
51
45
|
// ============================================================================
|
|
52
46
|
// File
|
|
53
47
|
// ============================================================================
|
|
54
|
-
|
|
55
48
|
/// An open file handle with async read/write operations.
|
|
56
49
|
///
|
|
57
50
|
/// Provides methods for reading, writing, seeking, and querying file metadata.
|
|
58
51
|
/// Files are automatically closed when disposed.
|
|
59
52
|
File :: object(
|
|
60
|
-
_fd
|
|
61
|
-
_path
|
|
53
|
+
_fd : i32,
|
|
54
|
+
_path : Path,
|
|
62
55
|
_is_closed : bool
|
|
63
56
|
);
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
impl(
|
|
58
|
+
File,
|
|
66
59
|
/// Open a file at `path` with the given mode and custom permissions.
|
|
67
|
-
open_with : (fn(path: Path, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))({
|
|
60
|
+
open_with : (fn(path : Path, mode : OpenMode, perm : FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))({
|
|
68
61
|
flags := _open_mode_to_flags(mode);
|
|
69
62
|
file_mode := cond(
|
|
70
63
|
_open_mode_needs_perm(mode) => i32(perm.mode),
|
|
@@ -77,51 +70,44 @@ impl(File,
|
|
|
77
70
|
result := io.await(IO_file.openat(AT_FDCWD, cstr, flags, file_mode));
|
|
78
71
|
fd := IOError.check(result);
|
|
79
72
|
File(
|
|
80
|
-
_fd: fd,
|
|
81
|
-
_path: path,
|
|
82
|
-
_is_closed: false
|
|
73
|
+
_fd : fd,
|
|
74
|
+
_path : path,
|
|
75
|
+
_is_closed : false
|
|
83
76
|
)
|
|
84
77
|
})
|
|
85
78
|
}),
|
|
86
|
-
|
|
87
79
|
/// Open a file from a `str` path with the given mode and custom permissions.
|
|
88
|
-
open_with_str : (fn(path: str, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
80
|
+
open_with_str : (fn(path : str, mode : OpenMode, perm : FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
89
81
|
File.open_with(Path.new(String.from(path)), mode, perm)
|
|
90
82
|
),
|
|
91
|
-
|
|
92
83
|
/// Open a file from a C string path with the given mode and custom permissions.
|
|
93
|
-
open_with_cstr : (fn(path: *(u8), mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
84
|
+
open_with_cstr : (fn(path : *(u8), mode : OpenMode, perm : FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
94
85
|
File.open_with(Path.from_cstr(path), mode, perm)
|
|
95
86
|
),
|
|
96
|
-
|
|
97
87
|
/// Open a file at `path` with the given mode and default permissions (0o644).
|
|
98
|
-
open : (fn(path: Path, mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
88
|
+
open : (fn(path : Path, mode : OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
99
89
|
File.open_with(path, mode, FilePermission.default())
|
|
100
90
|
),
|
|
101
|
-
|
|
102
91
|
/// Open a file from a `str` path with the given mode and default permissions.
|
|
103
|
-
open_str : (fn(path: str, mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
92
|
+
open_str : (fn(path : str, mode : OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
104
93
|
File.open(Path.new(String.from(path)), mode)
|
|
105
94
|
),
|
|
106
|
-
|
|
107
95
|
/// Open a file from a C string path with the given mode and default permissions.
|
|
108
|
-
open_cstr : (fn(path: *(u8), mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
96
|
+
open_cstr : (fn(path : *(u8), mode : OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
109
97
|
File.open(Path.from_cstr(path), mode)
|
|
110
98
|
),
|
|
111
|
-
|
|
112
99
|
/// Read up to `size` bytes into the buffer `buf`.
|
|
113
100
|
/// Returns the number of bytes actually read.
|
|
114
|
-
read : (fn(self: Self, buf: *(u8), size: u32, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
101
|
+
read : (fn(self : Self, buf : *(u8), size : u32, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
115
102
|
fd := self._fd;
|
|
116
103
|
io.async((using(io, exn)) => {
|
|
117
104
|
result := io.await(IO_file.read(fd, buf, size, u64(0)));
|
|
118
105
|
IOError.check(result)
|
|
119
106
|
})
|
|
120
107
|
}),
|
|
121
|
-
|
|
122
108
|
/// Write a `String` to the file.
|
|
123
109
|
/// Returns the number of bytes written.
|
|
124
|
-
write_string : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
110
|
+
write_string : (fn(self : Self, data : String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
125
111
|
fd := self._fd;
|
|
126
112
|
io.async((using(io, exn)) => {
|
|
127
113
|
data_bytes := data.as_bytes();
|
|
@@ -134,233 +120,211 @@ impl(File,
|
|
|
134
120
|
)
|
|
135
121
|
})
|
|
136
122
|
}),
|
|
137
|
-
|
|
138
123
|
/// Write bytes from an `ArrayList(u8)` to the file.
|
|
139
124
|
/// Returns the number of bytes written.
|
|
140
|
-
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
125
|
+
write_bytes : (fn(self : Self, data : ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
141
126
|
fd := self._fd;
|
|
142
|
-
io.async(
|
|
143
|
-
|
|
144
|
-
(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
127
|
+
io.async(
|
|
128
|
+
(using(io, exn)) =>
|
|
129
|
+
cond(
|
|
130
|
+
(data.len() == usize(0)) => i32(0),
|
|
131
|
+
true => {
|
|
132
|
+
result := io.await(IO_file.write(fd, data.ptr().unwrap(), u32(data.len()), u64(0)));
|
|
133
|
+
IOError.check(result)
|
|
134
|
+
}
|
|
135
|
+
)
|
|
150
136
|
)
|
|
151
137
|
}),
|
|
152
|
-
|
|
153
138
|
/// Read the entire file contents into an `ArrayList(u8)`.
|
|
154
|
-
read_bytes : (fn(self: Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
|
|
139
|
+
read_bytes : (fn(self : Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
|
|
155
140
|
fd := self._fd;
|
|
156
141
|
io.async((using(io, exn)) => {
|
|
157
142
|
buf_size := usize(4096);
|
|
158
143
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
159
144
|
result := ArrayList(u8).new();
|
|
160
145
|
offset := u64(0);
|
|
161
|
-
while
|
|
146
|
+
while(runtime(true), {
|
|
162
147
|
n := io.await(IO_file.read(fd, buf, u32(buf_size), offset));
|
|
163
148
|
cond(
|
|
164
149
|
(n < i32(0)) => {
|
|
165
150
|
free(.Some(*(void)(buf)));
|
|
166
|
-
exn.throw(dyn
|
|
151
|
+
exn.throw(dyn(IOError.from_errno(i32(0) - n)));
|
|
167
152
|
},
|
|
168
153
|
(n == i32(0)) => break,
|
|
169
154
|
true => {
|
|
170
155
|
offset = (offset + u64(n));
|
|
171
156
|
i := usize(0);
|
|
172
|
-
while
|
|
157
|
+
while(runtime(i < usize(n)), {
|
|
173
158
|
result.push((buf &+ i).*);
|
|
174
159
|
i = (i + usize(1));
|
|
175
|
-
};
|
|
160
|
+
});
|
|
176
161
|
}
|
|
177
162
|
);
|
|
178
|
-
};
|
|
163
|
+
});
|
|
179
164
|
free(.Some(*(void)(buf)));
|
|
180
165
|
result
|
|
181
166
|
})
|
|
182
167
|
}),
|
|
183
|
-
|
|
184
168
|
/// Read the entire file contents into a `String`.
|
|
185
|
-
read_string : (fn(self: Self, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
169
|
+
read_string : (fn(self : Self, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
186
170
|
io.async((using(io, exn)) => {
|
|
187
171
|
bytes := io.await(self.read_bytes());
|
|
188
172
|
String.from_bytes(bytes)
|
|
189
173
|
})
|
|
190
174
|
),
|
|
191
|
-
|
|
192
175
|
/// Flush (fsync) file data to disk.
|
|
193
|
-
flush : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
176
|
+
flush : (fn(self : Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
194
177
|
fd := self._fd;
|
|
195
178
|
io.async((using(io, exn)) => {
|
|
196
179
|
result := io.await(IO_file.fsync(fd));
|
|
197
180
|
cond(
|
|
198
|
-
(result < i32(0)) => exn.throw(dyn
|
|
181
|
+
(result < i32(0)) => exn.throw(dyn(IOError.from_errno(i32(0) - result))),
|
|
199
182
|
true => ()
|
|
200
183
|
)
|
|
201
184
|
})
|
|
202
185
|
}),
|
|
203
|
-
|
|
204
186
|
/// Seek to a position relative to `from`. Returns the new absolute byte offset.
|
|
205
|
-
seek : (fn(self: Self, offset: i64, from: SeekFrom, using(exn : Exception)) -> i64)({
|
|
187
|
+
seek : (fn(self : Self, offset : i64, from : SeekFrom, using(exn : Exception)) -> i64)({
|
|
206
188
|
result := IO_seek.lseek(self._fd, offset, _seek_from_to_whence(from));
|
|
207
189
|
cond(
|
|
208
|
-
(result < i64(0)) => exn.throw(dyn
|
|
190
|
+
(result < i64(0)) => exn.throw(dyn(IOError.from_errno(i32(i64(0) - result)))),
|
|
209
191
|
true => result
|
|
210
192
|
)
|
|
211
193
|
}),
|
|
212
|
-
|
|
213
194
|
/// Get the current file position (byte offset from the beginning).
|
|
214
|
-
position : (fn(self: Self) -> i64)(
|
|
195
|
+
position : (fn(self : Self) -> i64)(
|
|
215
196
|
IO_seek.lseek(self._fd, i64(0), IO_seek.SEEK_CUR)
|
|
216
197
|
),
|
|
217
|
-
|
|
218
198
|
/// Get the file size in bytes.
|
|
219
|
-
size : (fn(self: Self) -> i64)(
|
|
199
|
+
size : (fn(self : Self) -> i64)(
|
|
220
200
|
IO_file.file_size(self._fd)
|
|
221
201
|
),
|
|
222
|
-
|
|
223
202
|
/// Close the file descriptor. Safe to call multiple times.
|
|
224
|
-
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
203
|
+
close : (fn(self : Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
225
204
|
fd := self._fd;
|
|
226
|
-
io.async(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
205
|
+
io.async(
|
|
206
|
+
(using(io, exn)) =>
|
|
207
|
+
cond(
|
|
208
|
+
self._is_closed => (),
|
|
209
|
+
true => {
|
|
210
|
+
result := io.await(IO_file.close(fd));
|
|
211
|
+
self._is_closed = true;
|
|
212
|
+
cond(
|
|
213
|
+
(result < i32(0)) => exn.throw(dyn(IOError.from_errno(i32(0) - result))),
|
|
214
|
+
true => ()
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
)
|
|
238
218
|
)
|
|
239
219
|
}),
|
|
240
|
-
|
|
241
220
|
/// Get the underlying file descriptor.
|
|
242
|
-
fd : (fn(self: Self) -> i32)(
|
|
221
|
+
fd : (fn(self : Self) -> i32)(
|
|
243
222
|
self._fd
|
|
244
223
|
),
|
|
245
|
-
|
|
246
224
|
/// Get the path this file was opened with.
|
|
247
|
-
path : (fn(self: Self) -> Path)(
|
|
225
|
+
path : (fn(self : Self) -> Path)(
|
|
248
226
|
self._path
|
|
249
227
|
),
|
|
250
|
-
|
|
251
228
|
/// Get file metadata (size, permissions, timestamps).
|
|
252
|
-
metadata : (fn(self: Self, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(
|
|
229
|
+
metadata : (fn(self : Self, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(
|
|
253
230
|
_metadata_mod.metadata(self._path)
|
|
254
231
|
)
|
|
255
232
|
);
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
233
|
+
impl(
|
|
234
|
+
File,
|
|
235
|
+
Dispose(
|
|
236
|
+
dispose : (fn(self : Self) -> unit)({
|
|
237
|
+
cond(
|
|
238
|
+
(!(self._is_closed)) => {
|
|
239
|
+
IO_file.close_sync(self._fd);
|
|
240
|
+
self._is_closed = true;
|
|
241
|
+
},
|
|
242
|
+
true => ()
|
|
243
|
+
);
|
|
244
|
+
})
|
|
245
|
+
)
|
|
246
|
+
);
|
|
247
|
+
export(File, OpenMode, FilePermission, SeekFrom);
|
|
271
248
|
// ============================================================================
|
|
272
249
|
// Convenience functions
|
|
273
250
|
// ============================================================================
|
|
274
|
-
|
|
275
251
|
/// Read an entire file into a `String`.
|
|
276
|
-
read_string :: (fn(path: Path, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
252
|
+
read_string :: (fn(path : Path, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
277
253
|
io.async((using(io, exn)) => {
|
|
278
|
-
file := io.await(File.open(path
|
|
254
|
+
file := io.await(File.open(path,.Read));
|
|
279
255
|
content := io.await(file.read_string());
|
|
280
256
|
io.await(file.close());
|
|
281
|
-
return
|
|
257
|
+
return(content);
|
|
282
258
|
})
|
|
283
259
|
);
|
|
284
|
-
|
|
285
260
|
/// Read an entire file into a `String` (`str` path variant).
|
|
286
|
-
read_string_str :: (fn(path: str, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
261
|
+
read_string_str :: (fn(path : str, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
287
262
|
read_string(Path.new(String.from(path)))
|
|
288
263
|
);
|
|
289
|
-
|
|
290
264
|
/// Read an entire file into a `String` (C string path variant).
|
|
291
|
-
read_string_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
265
|
+
read_string_cstr :: (fn(path : *(u8), using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
292
266
|
read_string(Path.from_cstr(path))
|
|
293
267
|
);
|
|
294
|
-
|
|
295
268
|
/// Read an entire file into a byte list (`ArrayList(u8)`).
|
|
296
|
-
read_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
269
|
+
read_file :: (fn(path : Path, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
297
270
|
io.async((using(io, exn)) => {
|
|
298
|
-
file := io.await(File.open(path
|
|
271
|
+
file := io.await(File.open(path,.Read));
|
|
299
272
|
content := io.await(file.read_bytes());
|
|
300
273
|
io.await(file.close());
|
|
301
|
-
return
|
|
274
|
+
return(content);
|
|
302
275
|
})
|
|
303
276
|
);
|
|
304
|
-
|
|
305
277
|
/// Read an entire file into bytes (`str` path variant).
|
|
306
|
-
read_file_str :: (fn(path: str, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
278
|
+
read_file_str :: (fn(path : str, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
307
279
|
read_file(Path.new(String.from(path)))
|
|
308
280
|
);
|
|
309
|
-
|
|
310
281
|
/// Read an entire file into bytes (C string path variant).
|
|
311
|
-
read_file_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
282
|
+
read_file_cstr :: (fn(path : *(u8), using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
312
283
|
read_file(Path.from_cstr(path))
|
|
313
284
|
);
|
|
314
|
-
|
|
315
285
|
/// Write a `String` to a file, creating or truncating it.
|
|
316
|
-
write_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
286
|
+
write_file :: (fn(path : Path, data : String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
317
287
|
io.async((using(io, exn)) => {
|
|
318
|
-
file := io.await(File.open(path
|
|
288
|
+
file := io.await(File.open(path,.Write));
|
|
319
289
|
io.await(file.write_string(data));
|
|
320
290
|
io.await(file.close());
|
|
321
291
|
})
|
|
322
292
|
);
|
|
323
|
-
|
|
324
293
|
/// Write a `str` to a file, creating or truncating it (`str` path variant).
|
|
325
|
-
write_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
294
|
+
write_file_str :: (fn(path : str, data : str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
326
295
|
write_file(Path.new(String.from(path)), String.from(data))
|
|
327
296
|
);
|
|
328
|
-
|
|
329
297
|
/// Write a `str` to a file, creating or truncating it (C string path variant).
|
|
330
|
-
write_file_cstr :: (fn(path: *(u8), data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
298
|
+
write_file_cstr :: (fn(path : *(u8), data : str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
331
299
|
write_file(Path.from_cstr(path), String.from(data))
|
|
332
300
|
);
|
|
333
|
-
|
|
334
301
|
/// Write bytes to a file, creating or truncating it.
|
|
335
|
-
write_bytes :: (fn(path: Path, data: ArrayList(u8), using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
302
|
+
write_bytes :: (fn(path : Path, data : ArrayList(u8), using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
336
303
|
io.async((using(io, exn)) => {
|
|
337
|
-
file := io.await(File.open(path
|
|
304
|
+
file := io.await(File.open(path,.Write));
|
|
338
305
|
io.await(file.write_bytes(data));
|
|
339
306
|
io.await(file.close());
|
|
340
307
|
})
|
|
341
308
|
);
|
|
342
|
-
|
|
343
309
|
/// Append a `String` to a file, creating it if it does not exist.
|
|
344
|
-
append_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
310
|
+
append_file :: (fn(path : Path, data : String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
345
311
|
io.async((using(io, exn)) => {
|
|
346
|
-
file := io.await(File.open(path
|
|
312
|
+
file := io.await(File.open(path,.Append));
|
|
347
313
|
io.await(file.write_string(data));
|
|
348
314
|
io.await(file.close());
|
|
349
315
|
})
|
|
350
316
|
);
|
|
351
|
-
|
|
352
317
|
/// Append a `str` to a file (`str` path variant).
|
|
353
|
-
append_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
318
|
+
append_file_str :: (fn(path : str, data : str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
354
319
|
append_file(Path.new(String.from(path)), String.from(data))
|
|
355
320
|
);
|
|
356
|
-
|
|
357
|
-
|
|
321
|
+
extern(
|
|
322
|
+
"Yo",
|
|
358
323
|
__yo_statx_buf_size : (fn() -> usize)
|
|
359
|
-
;
|
|
360
|
-
|
|
324
|
+
);
|
|
361
325
|
/// Check if a path exists. Returns `false` for any error including file not found.
|
|
362
326
|
/// Does not use the `Exception` effect.
|
|
363
|
-
exists :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
327
|
+
exists :: (fn(path : Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
364
328
|
io.async((using(io : IO)) => {
|
|
365
329
|
cstr_bytes := path.to_string().to_cstr();
|
|
366
330
|
cstr := cstr_bytes.ptr().unwrap();
|
|
@@ -368,22 +332,19 @@ exists :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
368
332
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
369
333
|
result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, buf));
|
|
370
334
|
free(.Some(*(void)(buf)));
|
|
371
|
-
|
|
335
|
+
result >= i32(0)
|
|
372
336
|
})
|
|
373
337
|
);
|
|
374
|
-
|
|
375
338
|
/// Check if a path exists (`str` path variant).
|
|
376
|
-
exists_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
339
|
+
exists_str :: (fn(path : str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
377
340
|
exists(Path.new(String.from(path)), using(io))
|
|
378
341
|
);
|
|
379
|
-
|
|
380
342
|
/// Check if a path exists (C string path variant).
|
|
381
|
-
exists_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
343
|
+
exists_cstr :: (fn(path : *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
382
344
|
exists(Path.from_cstr(path), using(io))
|
|
383
345
|
);
|
|
384
|
-
|
|
385
346
|
/// Check if a path is a regular file. Returns `false` for any error.
|
|
386
|
-
is_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
347
|
+
is_file :: (fn(path : Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
387
348
|
io.async((using(io : IO)) => {
|
|
388
349
|
path_str := path.to_string();
|
|
389
350
|
cstr_bytes := path_str.to_cstr();
|
|
@@ -394,7 +355,7 @@ is_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
394
355
|
r := cond(
|
|
395
356
|
(result < i32(0)) => false,
|
|
396
357
|
true => {
|
|
397
|
-
sx := Statx(_buf_ptr: buf, _buf_size: buf_size);
|
|
358
|
+
sx := Statx(_buf_ptr : buf, _buf_size : buf_size);
|
|
398
359
|
sx.is_file()
|
|
399
360
|
}
|
|
400
361
|
);
|
|
@@ -402,19 +363,16 @@ is_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
402
363
|
r
|
|
403
364
|
})
|
|
404
365
|
);
|
|
405
|
-
|
|
406
366
|
/// Check if a path is a regular file (`str` path variant).
|
|
407
|
-
is_file_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
367
|
+
is_file_str :: (fn(path : str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
408
368
|
is_file(Path.new(String.from(path)), using(io))
|
|
409
369
|
);
|
|
410
|
-
|
|
411
370
|
/// Check if a path is a regular file (C string path variant).
|
|
412
|
-
is_file_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
371
|
+
is_file_cstr :: (fn(path : *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
413
372
|
is_file(Path.from_cstr(path), using(io))
|
|
414
373
|
);
|
|
415
|
-
|
|
416
374
|
/// Check if a path is a directory. Returns `false` for any error.
|
|
417
|
-
is_dir :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
375
|
+
is_dir :: (fn(path : Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
418
376
|
io.async((using(io : IO)) => {
|
|
419
377
|
path_str := path.to_string();
|
|
420
378
|
cstr_bytes := path_str.to_cstr();
|
|
@@ -425,7 +383,7 @@ is_dir :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
425
383
|
r := cond(
|
|
426
384
|
(result < i32(0)) => false,
|
|
427
385
|
true => {
|
|
428
|
-
sx := Statx(_buf_ptr: buf, _buf_size: buf_size);
|
|
386
|
+
sx := Statx(_buf_ptr : buf, _buf_size : buf_size);
|
|
429
387
|
sx.is_directory()
|
|
430
388
|
}
|
|
431
389
|
);
|
|
@@ -433,20 +391,17 @@ is_dir :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
433
391
|
r
|
|
434
392
|
})
|
|
435
393
|
);
|
|
436
|
-
|
|
437
394
|
/// Check if a path is a directory (`str` path variant).
|
|
438
|
-
is_dir_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
395
|
+
is_dir_str :: (fn(path : str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
439
396
|
is_dir(Path.new(String.from(path)), using(io))
|
|
440
397
|
);
|
|
441
|
-
|
|
442
398
|
/// Check if a path is a directory (C string path variant).
|
|
443
|
-
is_dir_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
399
|
+
is_dir_cstr :: (fn(path : *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
444
400
|
is_dir(Path.from_cstr(path), using(io))
|
|
445
401
|
);
|
|
446
|
-
|
|
447
402
|
/// Resolve a path to its canonical absolute form (resolves symlinks, `.` and `..`).
|
|
448
403
|
/// Throws if the path does not exist.
|
|
449
|
-
canonical :: (fn(path: Path, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
404
|
+
canonical :: (fn(path : Path, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
450
405
|
io.async((using(io, exn)) => {
|
|
451
406
|
path_str := path.to_string();
|
|
452
407
|
cstr_bytes := path_str.to_cstr();
|
|
@@ -472,25 +427,37 @@ canonical :: (fn(path: Path, using(io : IO)) -> Impl(Future(Path, IO, Exception)
|
|
|
472
427
|
Path.new(resolved)
|
|
473
428
|
})
|
|
474
429
|
);
|
|
475
|
-
|
|
476
430
|
/// Resolve a path to its canonical absolute form (`str` path variant).
|
|
477
|
-
canonical_str :: (fn(path: str, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
431
|
+
canonical_str :: (fn(path : str, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
478
432
|
canonical(Path.new(String.from(path)))
|
|
479
433
|
);
|
|
480
|
-
|
|
481
434
|
/// Resolve a path to its canonical absolute form (C string path variant).
|
|
482
|
-
canonical_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
435
|
+
canonical_cstr :: (fn(path : *(u8), using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
|
|
483
436
|
canonical(Path.from_cstr(path))
|
|
484
437
|
);
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
438
|
+
export(
|
|
439
|
+
read_string,
|
|
440
|
+
read_string_str,
|
|
441
|
+
read_string_cstr,
|
|
442
|
+
read_file,
|
|
443
|
+
read_file_str,
|
|
444
|
+
read_file_cstr,
|
|
445
|
+
write_file,
|
|
446
|
+
write_file_str,
|
|
447
|
+
write_file_cstr,
|
|
490
448
|
write_bytes,
|
|
491
|
-
append_file,
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
449
|
+
append_file,
|
|
450
|
+
append_file_str,
|
|
451
|
+
exists,
|
|
452
|
+
exists_str,
|
|
453
|
+
exists_cstr,
|
|
454
|
+
is_file,
|
|
455
|
+
is_file_str,
|
|
456
|
+
is_file_cstr,
|
|
457
|
+
is_dir,
|
|
458
|
+
is_dir_str,
|
|
459
|
+
is_dir_cstr,
|
|
460
|
+
canonical,
|
|
461
|
+
canonical_str,
|
|
462
|
+
canonical_cstr
|
|
463
|
+
);
|