@shd101wyy/yo 0.1.28 → 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.
Files changed (55) hide show
  1. package/.github/skills/yo-async-effects/SKILL.md +15 -15
  2. package/.github/skills/yo-async-effects/async-effects-recipes.md +110 -121
  3. package/.github/skills/yo-syntax/SKILL.md +2 -2
  4. package/.github/skills/yo-syntax/syntax-cheatsheet.md +49 -75
  5. package/README.md +2 -0
  6. package/out/cjs/index.cjs +622 -611
  7. package/out/cjs/yo-cli.cjs +727 -716
  8. package/out/cjs/yo-lsp.cjs +637 -626
  9. package/out/esm/index.mjs +515 -504
  10. package/out/types/src/codegen/functions/declarations.d.ts +1 -1
  11. package/out/types/src/doc/model.d.ts +0 -1
  12. package/out/types/src/env.d.ts +0 -2
  13. package/out/types/src/evaluator/context.d.ts +1 -1
  14. package/out/types/src/evaluator/exprs/{escape.d.ts → unwind.d.ts} +1 -1
  15. package/out/types/src/evaluator/types/function.d.ts +1 -2
  16. package/out/types/src/evaluator/utils.d.ts +0 -1
  17. package/out/types/src/expr.d.ts +5 -6
  18. package/out/types/src/types/creators.d.ts +4 -6
  19. package/out/types/src/types/definitions.d.ts +7 -16
  20. package/out/types/src/types/guards.d.ts +1 -2
  21. package/out/types/src/types/tags.d.ts +0 -1
  22. package/out/types/src/types/utils.d.ts +1 -0
  23. package/out/types/tsconfig.tsbuildinfo +1 -1
  24. package/package.json +1 -1
  25. package/std/async.yo +1 -1
  26. package/std/crypto/random.yo +6 -6
  27. package/std/encoding/base64.yo +4 -4
  28. package/std/encoding/hex.yo +2 -2
  29. package/std/encoding/json.yo +3 -3
  30. package/std/encoding/utf16.yo +1 -1
  31. package/std/error.yo +14 -2
  32. package/std/fs/dir.yo +56 -62
  33. package/std/fs/file.yo +118 -124
  34. package/std/fs/metadata.yo +11 -17
  35. package/std/fs/temp.yo +21 -27
  36. package/std/fs/walker.yo +10 -16
  37. package/std/http/client.yo +25 -29
  38. package/std/http/index.yo +4 -4
  39. package/std/io/reader.yo +1 -1
  40. package/std/io/writer.yo +2 -2
  41. package/std/net/addr.yo +1 -1
  42. package/std/net/dns.yo +10 -14
  43. package/std/net/errors.yo +1 -1
  44. package/std/net/tcp.yo +67 -71
  45. package/std/net/udp.yo +36 -40
  46. package/std/os/signal.yo +2 -2
  47. package/std/prelude.yo +27 -21
  48. package/std/process/command.yo +32 -38
  49. package/std/regex/parser.yo +10 -10
  50. package/std/sys/bufio/buf_reader.yo +14 -14
  51. package/std/sys/bufio/buf_writer.yo +17 -17
  52. package/std/sys/errors.yo +1 -1
  53. package/std/thread.yo +2 -2
  54. package/std/url/index.yo +2 -2
  55. 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(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
- //!
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, using(io : IO)) -> Impl(Future(File, IO, Exception)))({
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((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
95
+ read : (fn(self : Self, buf : *(u8), size : u32, io : IO) -> Impl(Future(i32, IOErr)))({
102
96
  fd := self._fd;
103
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
104
+ write_string : (fn(self : Self, data : String, io : IO) -> Impl(Future(i32, IOErr)))({
111
105
  fd := self._fd;
112
- io.async((using(io, exn)) => {
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), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
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
- (using(io, exn)) =>
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, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
133
+ read_bytes : (fn(self : Self, io : IO) -> Impl(Future(ArrayList(u8), IOErr)))({
140
134
  fd := self._fd;
141
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
170
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
170
+ flush : (fn(self : Self, io : IO) -> Impl(Future(unit, IOErr)))({
177
171
  fd := self._fd;
178
- io.async((using(io, exn)) => {
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, using(exn : Exception)) -> i64)({
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, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
197
+ close : (fn(self : Self, io : IO) -> Impl(Future(unit, IOErr)))({
204
198
  fd := self._fd;
205
199
  io.async(
206
- (using(io, exn)) =>
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, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
253
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
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), using(io : IO)) -> Impl(Future(String, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
270
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
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), using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
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, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
287
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
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), using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
303
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
311
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
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, using(io : IO)) -> Impl(Future(bool, IO)))(
328
- io.async((using(io : IO)) => {
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, using(io : IO)) -> Impl(Future(bool, IO)))(
340
- exists(Path.new(String.from(path)), using(io))
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), using(io : IO)) -> Impl(Future(bool, IO)))(
344
- exists(Path.from_cstr(path), using(io))
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, using(io : IO)) -> Impl(Future(bool, IO)))(
348
- io.async((using(io : IO)) => {
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, using(io : IO)) -> Impl(Future(bool, IO)))(
368
- is_file(Path.new(String.from(path)), using(io))
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), using(io : IO)) -> Impl(Future(bool, IO)))(
372
- is_file(Path.from_cstr(path), using(io))
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, using(io : IO)) -> Impl(Future(bool, IO)))(
376
- io.async((using(io : IO)) => {
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, using(io : IO)) -> Impl(Future(bool, IO)))(
396
- is_dir(Path.new(String.from(path)), using(io))
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), using(io : IO)) -> Impl(Future(bool, IO)))(
400
- is_dir(Path.from_cstr(path), using(io))
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, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
405
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
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), using(io : IO)) -> Impl(Future(Path, IO, Exception)))(
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,
@@ -6,14 +6,8 @@
6
6
  //! ```rust
7
7
  //! { metadata } :: import "std/fs/metadata";
8
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`)));
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, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(
111
- io.async((using(io, exn)) => {
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, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(_stat_path(path, AT_STATX_SYNC_AS_STAT));
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, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(metadata(Path.new(String.from(path))));
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, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(_stat_path(path, AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT));
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, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(symlink_metadata(Path.new(String.from(path))));
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);