@shd101wyy/yo 0.1.27 → 0.1.29
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 +15 -15
- package/.github/skills/yo-async-effects/async-effects-recipes.md +110 -121
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +3 -0
- package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +2 -0
- package/.github/skills/yo-syntax/SKILL.md +2 -2
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +195 -73
- package/README.md +2 -0
- package/out/cjs/index.cjs +624 -613
- package/out/cjs/yo-cli.cjs +739 -727
- package/out/cjs/yo-lsp.cjs +636 -625
- package/out/esm/index.mjs +526 -515
- package/out/types/src/codegen/functions/declarations.d.ts +1 -1
- package/out/types/src/doc/model.d.ts +0 -1
- package/out/types/src/env.d.ts +1 -2
- package/out/types/src/evaluator/calls/helper.d.ts +4 -2
- package/out/types/src/evaluator/context.d.ts +1 -1
- package/out/types/src/evaluator/exprs/{escape.d.ts → unwind.d.ts} +1 -1
- package/out/types/src/evaluator/types/function.d.ts +1 -2
- package/out/types/src/evaluator/types/synthesizer.d.ts +1 -0
- package/out/types/src/evaluator/utils.d.ts +0 -1
- package/out/types/src/expr.d.ts +5 -6
- package/out/types/src/test-runner.d.ts +2 -0
- package/out/types/src/types/creators.d.ts +4 -6
- package/out/types/src/types/definitions.d.ts +7 -16
- package/out/types/src/types/guards.d.ts +1 -2
- package/out/types/src/types/tags.d.ts +0 -1
- package/out/types/src/types/utils.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/probe-parser-parity.ts +61 -0
- package/scripts/probe-yo-self-parser.sh +33 -0
- package/scripts/validate-yo-self-fmt.ts +184 -0
- package/std/async.yo +1 -1
- package/std/crypto/random.yo +6 -6
- package/std/encoding/base64.yo +4 -4
- package/std/encoding/hex.yo +2 -2
- package/std/encoding/json.yo +3 -3
- package/std/encoding/utf16.yo +1 -1
- package/std/error.yo +14 -2
- package/std/fs/dir.yo +56 -62
- package/std/fs/file.yo +118 -124
- package/std/fs/metadata.yo +11 -17
- package/std/fs/temp.yo +21 -27
- package/std/fs/walker.yo +10 -16
- package/std/http/client.yo +25 -29
- package/std/http/index.yo +4 -4
- package/std/io/reader.yo +1 -1
- package/std/io/writer.yo +2 -2
- package/std/net/addr.yo +1 -1
- package/std/net/dns.yo +10 -14
- package/std/net/errors.yo +1 -1
- package/std/net/tcp.yo +67 -71
- package/std/net/udp.yo +36 -40
- package/std/os/signal.yo +2 -2
- package/std/prelude.yo +27 -21
- package/std/process/command.yo +32 -38
- package/std/regex/parser.yo +10 -10
- package/std/sys/bufio/buf_reader.yo +14 -14
- package/std/sys/bufio/buf_writer.yo +17 -17
- package/std/sys/errors.yo +1 -1
- package/std/thread.yo +2 -2
- package/std/url/index.yo +2 -2
- package/std/worker.yo +2 -2
package/std/fs/file.yo
CHANGED
|
@@ -8,22 +8,16 @@
|
|
|
8
8
|
//! ```rust
|
|
9
9
|
//! { File, read_string, write_file, OpenMode } :: import "std/fs/file";
|
|
10
10
|
//!
|
|
11
|
-
//! main :: (fn(
|
|
12
|
-
//! given(exn) := Exception(
|
|
13
|
-
//! throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
14
|
-
//! { println(error); panic("Exception found."); }
|
|
15
|
-
//! )
|
|
16
|
-
//! );
|
|
17
|
-
//!
|
|
11
|
+
//! main :: (fn(io : IO, exn : Exception) -> unit)({
|
|
18
12
|
//! // Write a file
|
|
19
|
-
//! io.await(write_file(Path.new(`test.txt`), `hello world
|
|
13
|
+
//! io.await(write_file(Path.new(`test.txt`), `hello world`, io), { io, exn });
|
|
20
14
|
//!
|
|
21
15
|
//! // Read it back
|
|
22
|
-
//! content := io.await(read_string(Path.new(`test.txt`)));
|
|
16
|
+
//! content := io.await(read_string(Path.new(`test.txt`), io), { io, exn });
|
|
23
17
|
//! println(content);
|
|
24
18
|
//!
|
|
25
19
|
//! // Open with OpenMode
|
|
26
|
-
//! f := io.await(File.open(Path.new(`test.txt`), .Read));
|
|
20
|
+
//! f := io.await(File.open(Path.new(`test.txt`), .Read, io), { io, exn });
|
|
27
21
|
//! });
|
|
28
22
|
//! ```
|
|
29
23
|
{ GlobalAllocator } :: import("../allocator");
|
|
@@ -33,7 +27,7 @@ open(import("../string"));
|
|
|
33
27
|
open(import("../fmt"));
|
|
34
28
|
{ Path } :: import("../path");
|
|
35
29
|
{ IOError } :: import("../sys/errors");
|
|
36
|
-
{ Error, AnyError, Exception } :: import("../error");
|
|
30
|
+
{ Error, AnyError, Exception, IOErr } :: import("../error");
|
|
37
31
|
{ Metadata } :: import("./metadata");
|
|
38
32
|
_metadata_mod :: import("./metadata");
|
|
39
33
|
{ Statx } :: import("../sys/statx");
|
|
@@ -57,18 +51,18 @@ File :: object(
|
|
|
57
51
|
impl(
|
|
58
52
|
File,
|
|
59
53
|
/// Open a file at `path` with the given mode and custom permissions.
|
|
60
|
-
open_with : (fn(path : Path, mode : OpenMode, perm : FilePermission,
|
|
54
|
+
open_with : (fn(path : Path, mode : OpenMode, perm : FilePermission, io : IO) -> Impl(Future(File, IOErr)))({
|
|
61
55
|
flags := _open_mode_to_flags(mode);
|
|
62
56
|
file_mode := cond(
|
|
63
57
|
_open_mode_needs_perm(mode) => i32(perm.mode),
|
|
64
58
|
true => i32(0)
|
|
65
59
|
);
|
|
66
|
-
io.async((
|
|
60
|
+
io.async((e) => {
|
|
67
61
|
path_str := path.to_string();
|
|
68
62
|
cstr_bytes := path_str.to_cstr();
|
|
69
63
|
cstr := cstr_bytes.ptr().unwrap();
|
|
70
|
-
result := io.await(IO_file.openat(AT_FDCWD, cstr, flags, file_mode));
|
|
71
|
-
fd := IOError.check(result);
|
|
64
|
+
result := e.io.await(IO_file.openat(AT_FDCWD, cstr, flags, file_mode), e.io);
|
|
65
|
+
fd := IOError.check(result, e.exn);
|
|
72
66
|
File(
|
|
73
67
|
_fd : fd,
|
|
74
68
|
_path : path,
|
|
@@ -77,78 +71,78 @@ impl(
|
|
|
77
71
|
})
|
|
78
72
|
}),
|
|
79
73
|
/// Open a file from a `str` path with the given mode and custom permissions.
|
|
80
|
-
open_with_str : (fn(path : str, mode : OpenMode, perm : FilePermission,
|
|
81
|
-
File.open_with(Path.new(String.from(path)), mode, perm)
|
|
74
|
+
open_with_str : (fn(path : str, mode : OpenMode, perm : FilePermission, io : IO) -> Impl(Future(File, IOErr)))(
|
|
75
|
+
File.open_with(Path.new(String.from(path)), mode, perm, io)
|
|
82
76
|
),
|
|
83
77
|
/// Open a file from a C string path with the given mode and custom permissions.
|
|
84
|
-
open_with_cstr : (fn(path : *(u8), mode : OpenMode, perm : FilePermission,
|
|
85
|
-
File.open_with(Path.from_cstr(path), mode, perm)
|
|
78
|
+
open_with_cstr : (fn(path : *(u8), mode : OpenMode, perm : FilePermission, io : IO) -> Impl(Future(File, IOErr)))(
|
|
79
|
+
File.open_with(Path.from_cstr(path), mode, perm, io)
|
|
86
80
|
),
|
|
87
81
|
/// Open a file at `path` with the given mode and default permissions (0o644).
|
|
88
|
-
open : (fn(path : Path, mode : OpenMode,
|
|
89
|
-
File.open_with(path, mode, FilePermission.default())
|
|
82
|
+
open : (fn(path : Path, mode : OpenMode, io : IO) -> Impl(Future(File, IOErr)))(
|
|
83
|
+
File.open_with(path, mode, FilePermission.default(), io)
|
|
90
84
|
),
|
|
91
85
|
/// Open a file from a `str` path with the given mode and default permissions.
|
|
92
|
-
open_str : (fn(path : str, mode : OpenMode,
|
|
93
|
-
File.open(Path.new(String.from(path)), mode)
|
|
86
|
+
open_str : (fn(path : str, mode : OpenMode, io : IO) -> Impl(Future(File, IOErr)))(
|
|
87
|
+
File.open(Path.new(String.from(path)), mode, io)
|
|
94
88
|
),
|
|
95
89
|
/// Open a file from a C string path with the given mode and default permissions.
|
|
96
|
-
open_cstr : (fn(path : *(u8), mode : OpenMode,
|
|
97
|
-
File.open(Path.from_cstr(path), mode)
|
|
90
|
+
open_cstr : (fn(path : *(u8), mode : OpenMode, io : IO) -> Impl(Future(File, IOErr)))(
|
|
91
|
+
File.open(Path.from_cstr(path), mode, io)
|
|
98
92
|
),
|
|
99
93
|
/// Read up to `size` bytes into the buffer `buf`.
|
|
100
94
|
/// Returns the number of bytes actually read.
|
|
101
|
-
read : (fn(self : Self, buf : *(u8), size : u32,
|
|
95
|
+
read : (fn(self : Self, buf : *(u8), size : u32, io : IO) -> Impl(Future(i32, IOErr)))({
|
|
102
96
|
fd := self._fd;
|
|
103
|
-
io.async((
|
|
104
|
-
result := io.await(IO_file.read(fd, buf, size, u64(0)));
|
|
105
|
-
IOError.check(result)
|
|
97
|
+
io.async((e) => {
|
|
98
|
+
result := e.io.await(IO_file.read(fd, buf, size, u64(0)), e.io);
|
|
99
|
+
IOError.check(result, e.exn)
|
|
106
100
|
})
|
|
107
101
|
}),
|
|
108
102
|
/// Write a `String` to the file.
|
|
109
103
|
/// Returns the number of bytes written.
|
|
110
|
-
write_string : (fn(self : Self, data : String,
|
|
104
|
+
write_string : (fn(self : Self, data : String, io : IO) -> Impl(Future(i32, IOErr)))({
|
|
111
105
|
fd := self._fd;
|
|
112
|
-
io.async((
|
|
106
|
+
io.async((e) => {
|
|
113
107
|
data_bytes := data.as_bytes();
|
|
114
108
|
cond(
|
|
115
109
|
(data_bytes.len() == usize(0)) => i32(0),
|
|
116
110
|
true => {
|
|
117
|
-
result := io.await(IO_file.write(fd, data_bytes.ptr().unwrap(), u32(data_bytes.len()), u64(0)));
|
|
118
|
-
IOError.check(result)
|
|
111
|
+
result := e.io.await(IO_file.write(fd, data_bytes.ptr().unwrap(), u32(data_bytes.len()), u64(0)), e.io);
|
|
112
|
+
IOError.check(result, e.exn)
|
|
119
113
|
}
|
|
120
114
|
)
|
|
121
115
|
})
|
|
122
116
|
}),
|
|
123
117
|
/// Write bytes from an `ArrayList(u8)` to the file.
|
|
124
118
|
/// Returns the number of bytes written.
|
|
125
|
-
write_bytes : (fn(self : Self, data : ArrayList(u8),
|
|
119
|
+
write_bytes : (fn(self : Self, data : ArrayList(u8), io : IO) -> Impl(Future(i32, IOErr)))({
|
|
126
120
|
fd := self._fd;
|
|
127
121
|
io.async(
|
|
128
|
-
(
|
|
122
|
+
(e) =>
|
|
129
123
|
cond(
|
|
130
124
|
(data.len() == usize(0)) => i32(0),
|
|
131
125
|
true => {
|
|
132
|
-
result := io.await(IO_file.write(fd, data.ptr().unwrap(), u32(data.len()), u64(0)));
|
|
133
|
-
IOError.check(result)
|
|
126
|
+
result := e.io.await(IO_file.write(fd, data.ptr().unwrap(), u32(data.len()), u64(0)), e.io);
|
|
127
|
+
IOError.check(result, e.exn)
|
|
134
128
|
}
|
|
135
129
|
)
|
|
136
130
|
)
|
|
137
131
|
}),
|
|
138
132
|
/// Read the entire file contents into an `ArrayList(u8)`.
|
|
139
|
-
read_bytes : (fn(self : Self,
|
|
133
|
+
read_bytes : (fn(self : Self, io : IO) -> Impl(Future(ArrayList(u8), IOErr)))({
|
|
140
134
|
fd := self._fd;
|
|
141
|
-
io.async((
|
|
135
|
+
io.async((e) => {
|
|
142
136
|
buf_size := usize(4096);
|
|
143
137
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
144
138
|
result := ArrayList(u8).new();
|
|
145
139
|
offset := u64(0);
|
|
146
140
|
while(runtime(true), {
|
|
147
|
-
n := io.await(IO_file.read(fd, buf, u32(buf_size), offset));
|
|
141
|
+
n := e.io.await(IO_file.read(fd, buf, u32(buf_size), offset), e.io);
|
|
148
142
|
cond(
|
|
149
143
|
(n < i32(0)) => {
|
|
150
144
|
free(.Some(*(void)(buf)));
|
|
151
|
-
exn.throw(dyn(IOError.from_errno(i32(0) - n)));
|
|
145
|
+
e.exn.throw(dyn(IOError.from_errno(i32(0) - n)));
|
|
152
146
|
},
|
|
153
147
|
(n == i32(0)) => break,
|
|
154
148
|
true => {
|
|
@@ -166,25 +160,25 @@ impl(
|
|
|
166
160
|
})
|
|
167
161
|
}),
|
|
168
162
|
/// Read the entire file contents into a `String`.
|
|
169
|
-
read_string : (fn(self : Self,
|
|
170
|
-
io.async((
|
|
171
|
-
bytes := io.await(self.read_bytes());
|
|
163
|
+
read_string : (fn(self : Self, io : IO) -> Impl(Future(String, IOErr)))(
|
|
164
|
+
io.async((e) => {
|
|
165
|
+
bytes := e.io.await(self.read_bytes(io), e);
|
|
172
166
|
String.from_bytes(bytes)
|
|
173
167
|
})
|
|
174
168
|
),
|
|
175
169
|
/// Flush (fsync) file data to disk.
|
|
176
|
-
flush : (fn(self : Self,
|
|
170
|
+
flush : (fn(self : Self, io : IO) -> Impl(Future(unit, IOErr)))({
|
|
177
171
|
fd := self._fd;
|
|
178
|
-
io.async((
|
|
179
|
-
result := io.await(IO_file.fsync(fd));
|
|
172
|
+
io.async((e) => {
|
|
173
|
+
result := e.io.await(IO_file.fsync(fd), e.io);
|
|
180
174
|
cond(
|
|
181
|
-
(result < i32(0)) => exn.throw(dyn(IOError.from_errno(i32(0) - result))),
|
|
175
|
+
(result < i32(0)) => e.exn.throw(dyn(IOError.from_errno(i32(0) - result))),
|
|
182
176
|
true => ()
|
|
183
177
|
)
|
|
184
178
|
})
|
|
185
179
|
}),
|
|
186
180
|
/// Seek to a position relative to `from`. Returns the new absolute byte offset.
|
|
187
|
-
seek : (fn(self : Self, offset : i64, from : SeekFrom,
|
|
181
|
+
seek : (fn(self : Self, offset : i64, from : SeekFrom, exn : Exception) -> i64)({
|
|
188
182
|
result := IO_seek.lseek(self._fd, offset, _seek_from_to_whence(from));
|
|
189
183
|
cond(
|
|
190
184
|
(result < i64(0)) => exn.throw(dyn(IOError.from_errno(i32(i64(0) - result)))),
|
|
@@ -200,17 +194,17 @@ impl(
|
|
|
200
194
|
IO_file.file_size(self._fd)
|
|
201
195
|
),
|
|
202
196
|
/// Close the file descriptor. Safe to call multiple times.
|
|
203
|
-
close : (fn(self : Self,
|
|
197
|
+
close : (fn(self : Self, io : IO) -> Impl(Future(unit, IOErr)))({
|
|
204
198
|
fd := self._fd;
|
|
205
199
|
io.async(
|
|
206
|
-
(
|
|
200
|
+
(e) =>
|
|
207
201
|
cond(
|
|
208
202
|
self._is_closed => (),
|
|
209
203
|
true => {
|
|
210
|
-
result := io.await(IO_file.close(fd));
|
|
204
|
+
result := e.io.await(IO_file.close(fd), e.io);
|
|
211
205
|
self._is_closed = true;
|
|
212
206
|
cond(
|
|
213
|
-
(result < i32(0)) => exn.throw(dyn(IOError.from_errno(i32(0) - result))),
|
|
207
|
+
(result < i32(0)) => e.exn.throw(dyn(IOError.from_errno(i32(0) - result))),
|
|
214
208
|
true => ()
|
|
215
209
|
)
|
|
216
210
|
}
|
|
@@ -226,8 +220,8 @@ impl(
|
|
|
226
220
|
self._path
|
|
227
221
|
),
|
|
228
222
|
/// Get file metadata (size, permissions, timestamps).
|
|
229
|
-
metadata : (fn(self : Self,
|
|
230
|
-
_metadata_mod.metadata(self._path)
|
|
223
|
+
metadata : (fn(self : Self, io : IO) -> Impl(Future(Metadata, IOErr)))(
|
|
224
|
+
_metadata_mod.metadata(self._path, io)
|
|
231
225
|
)
|
|
232
226
|
);
|
|
233
227
|
impl(
|
|
@@ -249,74 +243,74 @@ export(File, OpenMode, FilePermission, SeekFrom);
|
|
|
249
243
|
// Convenience functions
|
|
250
244
|
// ============================================================================
|
|
251
245
|
/// Read an entire file into a `String`.
|
|
252
|
-
read_string :: (fn(path : Path,
|
|
253
|
-
io.async((
|
|
254
|
-
file := io.await(File.open(path,.Read));
|
|
255
|
-
content := io.await(file.read_string());
|
|
256
|
-
io.await(file.close());
|
|
246
|
+
read_string :: (fn(path : Path, io : IO) -> Impl(Future(String, IOErr)))(
|
|
247
|
+
io.async((e) => {
|
|
248
|
+
file := e.io.await(File.open(path,.Read, io), e);
|
|
249
|
+
content := e.io.await(file.read_string(io), e);
|
|
250
|
+
e.io.await(file.close(io), e);
|
|
257
251
|
return(content);
|
|
258
252
|
})
|
|
259
253
|
);
|
|
260
254
|
/// Read an entire file into a `String` (`str` path variant).
|
|
261
|
-
read_string_str :: (fn(path : str,
|
|
262
|
-
read_string(Path.new(String.from(path)))
|
|
255
|
+
read_string_str :: (fn(path : str, io : IO) -> Impl(Future(String, IOErr)))(
|
|
256
|
+
read_string(Path.new(String.from(path)), io)
|
|
263
257
|
);
|
|
264
258
|
/// Read an entire file into a `String` (C string path variant).
|
|
265
|
-
read_string_cstr :: (fn(path : *(u8),
|
|
266
|
-
read_string(Path.from_cstr(path))
|
|
259
|
+
read_string_cstr :: (fn(path : *(u8), io : IO) -> Impl(Future(String, IOErr)))(
|
|
260
|
+
read_string(Path.from_cstr(path), io)
|
|
267
261
|
);
|
|
268
262
|
/// Read an entire file into a byte list (`ArrayList(u8)`).
|
|
269
|
-
read_file :: (fn(path : Path,
|
|
270
|
-
io.async((
|
|
271
|
-
file := io.await(File.open(path,.Read));
|
|
272
|
-
content := io.await(file.read_bytes());
|
|
273
|
-
io.await(file.close());
|
|
263
|
+
read_file :: (fn(path : Path, io : IO) -> Impl(Future(ArrayList(u8), IOErr)))(
|
|
264
|
+
io.async((e) => {
|
|
265
|
+
file := e.io.await(File.open(path,.Read, io), e);
|
|
266
|
+
content := e.io.await(file.read_bytes(io), e);
|
|
267
|
+
e.io.await(file.close(io), e);
|
|
274
268
|
return(content);
|
|
275
269
|
})
|
|
276
270
|
);
|
|
277
271
|
/// Read an entire file into bytes (`str` path variant).
|
|
278
|
-
read_file_str :: (fn(path : str,
|
|
279
|
-
read_file(Path.new(String.from(path)))
|
|
272
|
+
read_file_str :: (fn(path : str, io : IO) -> Impl(Future(ArrayList(u8), IOErr)))(
|
|
273
|
+
read_file(Path.new(String.from(path)), io)
|
|
280
274
|
);
|
|
281
275
|
/// Read an entire file into bytes (C string path variant).
|
|
282
|
-
read_file_cstr :: (fn(path : *(u8),
|
|
283
|
-
read_file(Path.from_cstr(path))
|
|
276
|
+
read_file_cstr :: (fn(path : *(u8), io : IO) -> Impl(Future(ArrayList(u8), IOErr)))(
|
|
277
|
+
read_file(Path.from_cstr(path), io)
|
|
284
278
|
);
|
|
285
279
|
/// Write a `String` to a file, creating or truncating it.
|
|
286
|
-
write_file :: (fn(path : Path, data : String,
|
|
287
|
-
io.async((
|
|
288
|
-
file := io.await(File.open(path,.Write));
|
|
289
|
-
io.await(file.write_string(data));
|
|
290
|
-
io.await(file.close());
|
|
280
|
+
write_file :: (fn(path : Path, data : String, io : IO) -> Impl(Future(unit, IOErr)))(
|
|
281
|
+
io.async((e) => {
|
|
282
|
+
file := e.io.await(File.open(path,.Write, io), e);
|
|
283
|
+
e.io.await(file.write_string(data, io), e);
|
|
284
|
+
e.io.await(file.close(io), e);
|
|
291
285
|
})
|
|
292
286
|
);
|
|
293
287
|
/// Write a `str` to a file, creating or truncating it (`str` path variant).
|
|
294
|
-
write_file_str :: (fn(path : str, data : str,
|
|
295
|
-
write_file(Path.new(String.from(path)), String.from(data))
|
|
288
|
+
write_file_str :: (fn(path : str, data : str, io : IO) -> Impl(Future(unit, IOErr)))(
|
|
289
|
+
write_file(Path.new(String.from(path)), String.from(data), io)
|
|
296
290
|
);
|
|
297
291
|
/// Write a `str` to a file, creating or truncating it (C string path variant).
|
|
298
|
-
write_file_cstr :: (fn(path : *(u8), data : str,
|
|
299
|
-
write_file(Path.from_cstr(path), String.from(data))
|
|
292
|
+
write_file_cstr :: (fn(path : *(u8), data : str, io : IO) -> Impl(Future(unit, IOErr)))(
|
|
293
|
+
write_file(Path.from_cstr(path), String.from(data), io)
|
|
300
294
|
);
|
|
301
295
|
/// Write bytes to a file, creating or truncating it.
|
|
302
|
-
write_bytes :: (fn(path : Path, data : ArrayList(u8),
|
|
303
|
-
io.async((
|
|
304
|
-
file := io.await(File.open(path,.Write));
|
|
305
|
-
io.await(file.write_bytes(data));
|
|
306
|
-
io.await(file.close());
|
|
296
|
+
write_bytes :: (fn(path : Path, data : ArrayList(u8), io : IO) -> Impl(Future(unit, IOErr)))(
|
|
297
|
+
io.async((e) => {
|
|
298
|
+
file := e.io.await(File.open(path,.Write, io), e);
|
|
299
|
+
e.io.await(file.write_bytes(data, io), e);
|
|
300
|
+
e.io.await(file.close(io), e);
|
|
307
301
|
})
|
|
308
302
|
);
|
|
309
303
|
/// Append a `String` to a file, creating it if it does not exist.
|
|
310
|
-
append_file :: (fn(path : Path, data : String,
|
|
311
|
-
io.async((
|
|
312
|
-
file := io.await(File.open(path,.Append));
|
|
313
|
-
io.await(file.write_string(data));
|
|
314
|
-
io.await(file.close());
|
|
304
|
+
append_file :: (fn(path : Path, data : String, io : IO) -> Impl(Future(unit, IOErr)))(
|
|
305
|
+
io.async((e) => {
|
|
306
|
+
file := e.io.await(File.open(path,.Append, io), e);
|
|
307
|
+
e.io.await(file.write_string(data, io), e);
|
|
308
|
+
e.io.await(file.close(io), e);
|
|
315
309
|
})
|
|
316
310
|
);
|
|
317
311
|
/// Append a `str` to a file (`str` path variant).
|
|
318
|
-
append_file_str :: (fn(path : str, data : str,
|
|
319
|
-
append_file(Path.new(String.from(path)), String.from(data))
|
|
312
|
+
append_file_str :: (fn(path : str, data : str, io : IO) -> Impl(Future(unit, IOErr)))(
|
|
313
|
+
append_file(Path.new(String.from(path)), String.from(data), io)
|
|
320
314
|
);
|
|
321
315
|
extern(
|
|
322
316
|
"Yo",
|
|
@@ -324,34 +318,34 @@ extern(
|
|
|
324
318
|
);
|
|
325
319
|
/// Check if a path exists. Returns `false` for any error including file not found.
|
|
326
320
|
/// Does not use the `Exception` effect.
|
|
327
|
-
exists :: (fn(path : Path,
|
|
328
|
-
io.async((
|
|
321
|
+
exists :: (fn(path : Path, io : IO) -> Impl(Future(bool, IO)))(
|
|
322
|
+
io.async((io) => {
|
|
329
323
|
cstr_bytes := path.to_string().to_cstr();
|
|
330
324
|
cstr := cstr_bytes.ptr().unwrap();
|
|
331
325
|
buf_size := __yo_statx_buf_size();
|
|
332
326
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
333
|
-
result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, buf));
|
|
327
|
+
result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, buf), io);
|
|
334
328
|
free(.Some(*(void)(buf)));
|
|
335
329
|
result >= i32(0)
|
|
336
330
|
})
|
|
337
331
|
);
|
|
338
332
|
/// Check if a path exists (`str` path variant).
|
|
339
|
-
exists_str :: (fn(path : str,
|
|
340
|
-
exists(Path.new(String.from(path)),
|
|
333
|
+
exists_str :: (fn(path : str, io : IO) -> Impl(Future(bool, IO)))(
|
|
334
|
+
exists(Path.new(String.from(path)), io)
|
|
341
335
|
);
|
|
342
336
|
/// Check if a path exists (C string path variant).
|
|
343
|
-
exists_cstr :: (fn(path : *(u8),
|
|
344
|
-
exists(Path.from_cstr(path),
|
|
337
|
+
exists_cstr :: (fn(path : *(u8), io : IO) -> Impl(Future(bool, IO)))(
|
|
338
|
+
exists(Path.from_cstr(path), io)
|
|
345
339
|
);
|
|
346
340
|
/// Check if a path is a regular file. Returns `false` for any error.
|
|
347
|
-
is_file :: (fn(path : Path,
|
|
348
|
-
io.async((
|
|
341
|
+
is_file :: (fn(path : Path, io : IO) -> Impl(Future(bool, IO)))(
|
|
342
|
+
io.async((io) => {
|
|
349
343
|
path_str := path.to_string();
|
|
350
344
|
cstr_bytes := path_str.to_cstr();
|
|
351
345
|
cstr := cstr_bytes.ptr().unwrap();
|
|
352
346
|
buf_size := __yo_statx_buf_size();
|
|
353
347
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
354
|
-
result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, buf));
|
|
348
|
+
result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, buf), io);
|
|
355
349
|
r := cond(
|
|
356
350
|
(result < i32(0)) => false,
|
|
357
351
|
true => {
|
|
@@ -364,22 +358,22 @@ is_file :: (fn(path : Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
364
358
|
})
|
|
365
359
|
);
|
|
366
360
|
/// Check if a path is a regular file (`str` path variant).
|
|
367
|
-
is_file_str :: (fn(path : str,
|
|
368
|
-
is_file(Path.new(String.from(path)),
|
|
361
|
+
is_file_str :: (fn(path : str, io : IO) -> Impl(Future(bool, IO)))(
|
|
362
|
+
is_file(Path.new(String.from(path)), io)
|
|
369
363
|
);
|
|
370
364
|
/// Check if a path is a regular file (C string path variant).
|
|
371
|
-
is_file_cstr :: (fn(path : *(u8),
|
|
372
|
-
is_file(Path.from_cstr(path),
|
|
365
|
+
is_file_cstr :: (fn(path : *(u8), io : IO) -> Impl(Future(bool, IO)))(
|
|
366
|
+
is_file(Path.from_cstr(path), io)
|
|
373
367
|
);
|
|
374
368
|
/// Check if a path is a directory. Returns `false` for any error.
|
|
375
|
-
is_dir :: (fn(path : Path,
|
|
376
|
-
io.async((
|
|
369
|
+
is_dir :: (fn(path : Path, io : IO) -> Impl(Future(bool, IO)))(
|
|
370
|
+
io.async((io) => {
|
|
377
371
|
path_str := path.to_string();
|
|
378
372
|
cstr_bytes := path_str.to_cstr();
|
|
379
373
|
cstr := cstr_bytes.ptr().unwrap();
|
|
380
374
|
buf_size := __yo_statx_buf_size();
|
|
381
375
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
382
|
-
result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, buf));
|
|
376
|
+
result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, buf), io);
|
|
383
377
|
r := cond(
|
|
384
378
|
(result < i32(0)) => false,
|
|
385
379
|
true => {
|
|
@@ -392,33 +386,33 @@ is_dir :: (fn(path : Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
|
392
386
|
})
|
|
393
387
|
);
|
|
394
388
|
/// Check if a path is a directory (`str` path variant).
|
|
395
|
-
is_dir_str :: (fn(path : str,
|
|
396
|
-
is_dir(Path.new(String.from(path)),
|
|
389
|
+
is_dir_str :: (fn(path : str, io : IO) -> Impl(Future(bool, IO)))(
|
|
390
|
+
is_dir(Path.new(String.from(path)), io)
|
|
397
391
|
);
|
|
398
392
|
/// Check if a path is a directory (C string path variant).
|
|
399
|
-
is_dir_cstr :: (fn(path : *(u8),
|
|
400
|
-
is_dir(Path.from_cstr(path),
|
|
393
|
+
is_dir_cstr :: (fn(path : *(u8), io : IO) -> Impl(Future(bool, IO)))(
|
|
394
|
+
is_dir(Path.from_cstr(path), io)
|
|
401
395
|
);
|
|
402
396
|
/// Resolve a path to its canonical absolute form (resolves symlinks, `.` and `..`).
|
|
403
397
|
/// Throws if the path does not exist.
|
|
404
|
-
canonical :: (fn(path : Path,
|
|
405
|
-
io.async((
|
|
398
|
+
canonical :: (fn(path : Path, io : IO) -> Impl(Future(Path, IOErr)))(
|
|
399
|
+
io.async((e) => {
|
|
406
400
|
path_str := path.to_string();
|
|
407
401
|
cstr_bytes := path_str.to_cstr();
|
|
408
402
|
cstr := cstr_bytes.ptr().unwrap();
|
|
409
403
|
// Async stat to verify path exists (provides await point for proper RC cleanup)
|
|
410
404
|
buf_size := __yo_statx_buf_size();
|
|
411
405
|
stat_buf := *(u8)(malloc(buf_size).unwrap());
|
|
412
|
-
stat_result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, stat_buf));
|
|
406
|
+
stat_result := e.io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, stat_buf), e.io);
|
|
413
407
|
free(.Some(*(void)(stat_buf)));
|
|
414
|
-
IOError.check(stat_result);
|
|
408
|
+
IOError.check(stat_result, e.exn);
|
|
415
409
|
// Resolve the canonical path
|
|
416
410
|
resolved_buf := *(u8)(malloc(usize(4096)).unwrap());
|
|
417
411
|
rp_result := IO_path.realpath(cstr, resolved_buf);
|
|
418
412
|
cond(
|
|
419
413
|
(rp_result < i32(0)) => {
|
|
420
414
|
free(.Some(*(void)(resolved_buf)));
|
|
421
|
-
IOError.check(rp_result);
|
|
415
|
+
IOError.check(rp_result, e.exn);
|
|
422
416
|
},
|
|
423
417
|
true => ()
|
|
424
418
|
);
|
|
@@ -428,12 +422,12 @@ canonical :: (fn(path : Path, using(io : IO)) -> Impl(Future(Path, IO, Exception
|
|
|
428
422
|
})
|
|
429
423
|
);
|
|
430
424
|
/// Resolve a path to its canonical absolute form (`str` path variant).
|
|
431
|
-
canonical_str :: (fn(path : str,
|
|
432
|
-
canonical(Path.new(String.from(path)))
|
|
425
|
+
canonical_str :: (fn(path : str, io : IO) -> Impl(Future(Path, IOErr)))(
|
|
426
|
+
canonical(Path.new(String.from(path)), io)
|
|
433
427
|
);
|
|
434
428
|
/// Resolve a path to its canonical absolute form (C string path variant).
|
|
435
|
-
canonical_cstr :: (fn(path : *(u8),
|
|
436
|
-
canonical(Path.from_cstr(path))
|
|
429
|
+
canonical_cstr :: (fn(path : *(u8), io : IO) -> Impl(Future(Path, IOErr)))(
|
|
430
|
+
canonical(Path.from_cstr(path), io)
|
|
437
431
|
);
|
|
438
432
|
export(
|
|
439
433
|
read_string,
|
package/std/fs/metadata.yo
CHANGED
|
@@ -6,14 +6,8 @@
|
|
|
6
6
|
//! ```rust
|
|
7
7
|
//! { metadata } :: import "std/fs/metadata";
|
|
8
8
|
//!
|
|
9
|
-
//! main :: (fn(
|
|
10
|
-
//!
|
|
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`)));
|
|
9
|
+
//! main :: (fn(io : IO, exn : Exception) -> unit)({
|
|
10
|
+
//! m := io.await(metadata(Path.new(`/tmp/test.txt`), io), { io, exn });
|
|
17
11
|
//! printf("size: %lld\n", m.size());
|
|
18
12
|
//! printf("is file: %d\n", i32(m.is_file()));
|
|
19
13
|
//! });
|
|
@@ -23,7 +17,7 @@
|
|
|
23
17
|
open(import("../string"));
|
|
24
18
|
{ Path } :: import("../path");
|
|
25
19
|
{ IOError } :: import("../sys/errors");
|
|
26
|
-
{ Error, AnyError, Exception } :: import("../error");
|
|
20
|
+
{ Error, AnyError, Exception, IOErr } :: import("../error");
|
|
27
21
|
{ Statx } :: import("../sys/statx");
|
|
28
22
|
IO_file :: import("../sys/file");
|
|
29
23
|
{ AT_FDCWD, AT_SYMLINK_NOFOLLOW, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, S_IFMT, S_IFREG, S_IFDIR, S_IFLNK, S_IWUSR, S_IWGRP, S_IWOTH } :: import("../sys/constants");
|
|
@@ -107,17 +101,17 @@ extern(
|
|
|
107
101
|
// ============================================================================
|
|
108
102
|
// Internal helper to stat a path
|
|
109
103
|
// ============================================================================
|
|
110
|
-
_stat_path :: (fn(path : Path, flags : i32,
|
|
111
|
-
io.async((
|
|
104
|
+
_stat_path :: (fn(path : Path, flags : i32, io : IO) -> Impl(Future(Metadata, IOErr)))(
|
|
105
|
+
io.async((e) => {
|
|
112
106
|
cstr_bytes := path.to_string().to_cstr();
|
|
113
107
|
cstr := cstr_bytes.ptr().unwrap();
|
|
114
108
|
buf_size := __yo_statx_buf_size();
|
|
115
109
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
116
|
-
result := io.await(IO_file.statx(AT_FDCWD, cstr, flags, STATX_BASIC_STATS, buf));
|
|
110
|
+
result := e.io.await(IO_file.statx(AT_FDCWD, cstr, flags, STATX_BASIC_STATS, buf), e.io);
|
|
117
111
|
cond(
|
|
118
112
|
(result < i32(0)) => {
|
|
119
113
|
free(.Some(*(void)(buf)));
|
|
120
|
-
exn.throw(dyn(IOError.from_errno(i32(0) - result)))
|
|
114
|
+
e.exn.throw(dyn(IOError.from_errno(i32(0) - result)))
|
|
121
115
|
},
|
|
122
116
|
true => {
|
|
123
117
|
sx := Statx(_buf_ptr : buf, _buf_size : buf_size);
|
|
@@ -127,11 +121,11 @@ _stat_path :: (fn(path : Path, flags : i32, using(io : IO)) -> Impl(Future(Metad
|
|
|
127
121
|
})
|
|
128
122
|
);
|
|
129
123
|
/// Get metadata for a path (follows symlinks).
|
|
130
|
-
metadata :: (fn(path : Path,
|
|
124
|
+
metadata :: (fn(path : Path, io : IO) -> Impl(Future(Metadata, IOErr)))(_stat_path(path, AT_STATX_SYNC_AS_STAT, io));
|
|
131
125
|
/// Get metadata for a path given as a raw string (follows symlinks).
|
|
132
|
-
metadata_str :: (fn(path : str,
|
|
126
|
+
metadata_str :: (fn(path : str, io : IO) -> Impl(Future(Metadata, IOErr)))(metadata(Path.new(String.from(path)), io));
|
|
133
127
|
/// Get metadata for a path (does NOT follow symlinks).
|
|
134
|
-
symlink_metadata :: (fn(path : Path,
|
|
128
|
+
symlink_metadata :: (fn(path : Path, io : IO) -> Impl(Future(Metadata, IOErr)))(_stat_path(path, AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT, io));
|
|
135
129
|
/// Get metadata for a path given as a raw string (does NOT follow symlinks).
|
|
136
|
-
symlink_metadata_str :: (fn(path : str,
|
|
130
|
+
symlink_metadata_str :: (fn(path : str, io : IO) -> Impl(Future(Metadata, IOErr)))(symlink_metadata(Path.new(String.from(path)), io));
|
|
137
131
|
export(metadata, metadata_str, symlink_metadata, symlink_metadata_str);
|