@shd101wyy/yo 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/out/cjs/index.cjs +568 -563
- package/out/cjs/yo-cli.cjs +686 -556
- package/out/esm/index.mjs +509 -504
- package/out/types/src/build-runner.d.ts +22 -0
- package/out/types/src/cache.d.ts +3 -0
- package/out/types/src/codegen/async/state-machine.d.ts +1 -1
- package/out/types/src/codegen/codegen-c.d.ts +3 -0
- package/out/types/src/codegen/exprs/await.d.ts +1 -0
- package/out/types/src/codegen/exprs/return.d.ts +1 -0
- package/out/types/src/codegen/exprs/while.d.ts +1 -1
- package/out/types/src/codegen/functions/context.d.ts +6 -18
- package/out/types/src/codegen/functions/declarations.d.ts +10 -2
- package/out/types/src/codegen/index.d.ts +4 -0
- package/out/types/src/codegen/utils/index.d.ts +3 -0
- package/out/types/src/evaluator/async/await-analysis.d.ts +1 -0
- package/out/types/src/evaluator/builtins/build.d.ts +135 -0
- package/out/types/src/evaluator/context.d.ts +1 -0
- package/out/types/src/expr.d.ts +18 -0
- package/out/types/src/fetch-command.d.ts +6 -0
- package/out/types/src/fetch.d.ts +10 -0
- package/out/types/src/function-value.d.ts +1 -0
- package/out/types/src/init.d.ts +5 -0
- package/out/types/src/install-command.d.ts +6 -0
- package/out/types/src/lock-file.d.ts +16 -0
- package/out/types/src/module-manager.d.ts +3 -1
- package/out/types/src/pkg-config.d.ts +11 -0
- package/out/types/src/target.d.ts +28 -0
- package/out/types/src/tests/build-system.test.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +2 -1
- package/out/types/src/types/definitions.d.ts +2 -1
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/build.yo +287 -0
- package/std/crypto/random.yo +27 -15
- package/std/encoding/base64.yo +24 -49
- package/std/encoding/hex.yo +25 -22
- package/std/encoding/json.yo +25 -3
- package/std/encoding/utf16.yo +6 -5
- package/std/fs/dir.yo +107 -104
- package/std/fs/file.yo +122 -158
- package/std/fs/metadata.yo +23 -22
- package/std/fs/temp.yo +42 -48
- package/std/fs/walker.yo +48 -55
- package/std/net/addr.yo +8 -7
- package/std/net/dns.yo +27 -33
- package/std/net/errors.yo +13 -8
- package/std/net/tcp.yo +92 -113
- package/std/net/udp.yo +50 -54
- package/std/os/env.yo +5 -5
- package/std/os/signal.yo +21 -16
- package/std/path.yo +2 -2
- package/std/prelude.yo +23 -2
- package/std/process.yo +23 -43
- package/std/sys/clock.yo +1 -1
- package/std/sys/constants.yo +3 -3
- package/std/sys/errors.yo +45 -33
- package/std/sys/mmap.yo +2 -2
- package/std/sys/signals.yo +4 -4
- package/std/sys/socket.yo +25 -25
- package/std/sys/sysinfo.yo +4 -4
- package/std/url/url.yo +19 -32
- package/out/types/src/codegen/effects/effect-state-machine.d.ts +0 -34
package/std/fs/file.yo
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
// std/fs/file.yo - High-level file object
|
|
2
2
|
//
|
|
3
3
|
// Wraps a file descriptor with typed async I/O operations.
|
|
4
|
+
// Uses Exception effect for error handling.
|
|
4
5
|
//
|
|
5
6
|
// Example:
|
|
6
|
-
// { File,
|
|
7
|
+
// { File, read_string, write_file, OpenMode } :: import "std/fs/file";
|
|
7
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); panic("Exception found."); }
|
|
13
|
+
// )
|
|
14
|
+
// );
|
|
15
|
+
//
|
|
9
16
|
// // Write a file
|
|
10
17
|
// io.await(write_file(Path.new(`test.txt`), `hello world`));
|
|
11
18
|
//
|
|
12
19
|
// // Read it back
|
|
13
|
-
// content := io.await(
|
|
14
|
-
//
|
|
15
|
-
// .Ok(s) => println(s),
|
|
16
|
-
// .Err(e) => println(e.to_string())
|
|
17
|
-
// );
|
|
20
|
+
// content := io.await(read_string(Path.new(`test.txt`)));
|
|
21
|
+
// println(content);
|
|
18
22
|
//
|
|
19
23
|
// // Open with OpenMode
|
|
20
24
|
// f := io.await(File.open(Path.new(`test.txt`), .Read));
|
|
@@ -27,13 +31,15 @@ open import "../string";
|
|
|
27
31
|
open import "../fmt";
|
|
28
32
|
{ Path } :: import "../path";
|
|
29
33
|
{ IOError } :: import "../sys/errors";
|
|
34
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
30
35
|
{ Metadata } :: import "./metadata";
|
|
31
36
|
_metadata_mod :: import "./metadata";
|
|
32
37
|
{ OpenMode, FilePermission, _open_mode_to_flags, _open_mode_needs_perm } :: import "./types";
|
|
33
38
|
IO_file :: import "../sys/file";
|
|
34
39
|
IO_seek :: import "../sys/seek";
|
|
35
40
|
{
|
|
36
|
-
AT_FDCWD,
|
|
41
|
+
AT_FDCWD, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS,
|
|
42
|
+
O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND,
|
|
37
43
|
O_CLOEXEC, DEFAULT_FILE_MODE
|
|
38
44
|
} :: import "../sys/constants";
|
|
39
45
|
|
|
@@ -49,74 +55,72 @@ File :: object(
|
|
|
49
55
|
|
|
50
56
|
impl(File,
|
|
51
57
|
// Open a file with OpenMode and custom permissions.
|
|
52
|
-
open_with : (fn(path: Path, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(
|
|
58
|
+
open_with : (fn(path: Path, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))({
|
|
53
59
|
flags := _open_mode_to_flags(mode);
|
|
54
60
|
file_mode := cond(
|
|
55
61
|
_open_mode_needs_perm(mode) => i32(perm.mode),
|
|
56
62
|
true => i32(0)
|
|
57
63
|
);
|
|
58
|
-
io.async((using(io
|
|
64
|
+
io.async((using(io, exn)) => {
|
|
59
65
|
path_str := path.to_string();
|
|
60
66
|
cstr_bytes := path_str.to_cstr();
|
|
61
67
|
cstr := cstr_bytes.ptr().unwrap();
|
|
62
68
|
result := io.await(IO_file.openat(AT_FDCWD, cstr, flags, file_mode));
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
_is_closed: false
|
|
69
|
-
))
|
|
69
|
+
fd := IOError.check(result);
|
|
70
|
+
File(
|
|
71
|
+
_fd: fd,
|
|
72
|
+
_path: path,
|
|
73
|
+
_is_closed: false
|
|
70
74
|
)
|
|
71
75
|
})
|
|
72
76
|
}),
|
|
73
77
|
|
|
74
78
|
// Open a file from a str path with OpenMode and custom permissions.
|
|
75
|
-
open_with_str : (fn(path: str, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(
|
|
76
|
-
File.open_with(Path.new(String.from(path)), mode, perm
|
|
79
|
+
open_with_str : (fn(path: str, mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
80
|
+
File.open_with(Path.new(String.from(path)), mode, perm)
|
|
77
81
|
),
|
|
78
82
|
|
|
79
83
|
// Open a file from a C string path with OpenMode and custom permissions.
|
|
80
|
-
open_with_cstr : (fn(path: *(u8), mode: OpenMode, perm: FilePermission, using(io : IO)) -> Impl(Future(
|
|
81
|
-
File.open_with(Path.from_cstr(path), mode, perm
|
|
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)
|
|
82
86
|
),
|
|
83
87
|
|
|
84
88
|
// Open a file with OpenMode and default permissions.
|
|
85
|
-
open : (fn(path: Path, mode: OpenMode, using(io : IO)) -> Impl(Future(
|
|
86
|
-
File.open_with(path, mode, FilePermission.default()
|
|
89
|
+
open : (fn(path: Path, mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
90
|
+
File.open_with(path, mode, FilePermission.default())
|
|
87
91
|
),
|
|
88
92
|
|
|
89
93
|
// Open a file from a str path with OpenMode and default permissions.
|
|
90
|
-
open_str : (fn(path: str, mode: OpenMode, using(io : IO)) -> Impl(Future(
|
|
91
|
-
File.open(Path.new(String.from(path)), mode
|
|
94
|
+
open_str : (fn(path: str, mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
95
|
+
File.open(Path.new(String.from(path)), mode)
|
|
92
96
|
),
|
|
93
97
|
|
|
94
98
|
// Open a file from a C string path with OpenMode and default permissions.
|
|
95
|
-
open_cstr : (fn(path: *(u8), mode: OpenMode, using(io : IO)) -> Impl(Future(
|
|
96
|
-
File.open(Path.from_cstr(path), mode
|
|
99
|
+
open_cstr : (fn(path: *(u8), mode: OpenMode, using(io : IO)) -> Impl(Future(File, IO, Exception)))(
|
|
100
|
+
File.open(Path.from_cstr(path), mode)
|
|
97
101
|
),
|
|
98
102
|
|
|
99
103
|
// Read up to `size` bytes into buffer.
|
|
100
104
|
// Returns number of bytes read.
|
|
101
|
-
read : (fn(self: Self, buf: *(u8), size: u32, using(io : IO)) -> Impl(Future(
|
|
105
|
+
read : (fn(self: Self, buf: *(u8), size: u32, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
102
106
|
fd := self._fd;
|
|
103
|
-
io.async((using(io
|
|
107
|
+
io.async((using(io, exn)) => {
|
|
104
108
|
result := io.await(IO_file.read(fd, buf, size, u64(0)));
|
|
105
|
-
IOError.
|
|
109
|
+
IOError.check(result)
|
|
106
110
|
})
|
|
107
111
|
}),
|
|
108
112
|
|
|
109
113
|
// Write a String to the file.
|
|
110
114
|
// Returns number of bytes written.
|
|
111
|
-
|
|
115
|
+
write_string : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
112
116
|
fd := self._fd;
|
|
113
|
-
io.async((using(io
|
|
117
|
+
io.async((using(io, exn)) => {
|
|
114
118
|
data_bytes := data.as_bytes();
|
|
115
119
|
cond(
|
|
116
|
-
(data_bytes.len() == usize(0)) =>
|
|
120
|
+
(data_bytes.len() == usize(0)) => i32(0),
|
|
117
121
|
true => {
|
|
118
122
|
result := io.await(IO_file.write(fd, data_bytes.ptr().unwrap(), u32(data_bytes.len()), u64(0)));
|
|
119
|
-
IOError.
|
|
123
|
+
IOError.check(result)
|
|
120
124
|
}
|
|
121
125
|
)
|
|
122
126
|
})
|
|
@@ -124,34 +128,33 @@ impl(File,
|
|
|
124
128
|
|
|
125
129
|
// Write bytes from an ArrayList to the file.
|
|
126
130
|
// Returns number of bytes written.
|
|
127
|
-
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(
|
|
131
|
+
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
128
132
|
fd := self._fd;
|
|
129
|
-
io.async((using(io
|
|
133
|
+
io.async((using(io, exn)) =>
|
|
130
134
|
cond(
|
|
131
|
-
(data.len() == usize(0)) =>
|
|
135
|
+
(data.len() == usize(0)) => i32(0),
|
|
132
136
|
true => {
|
|
133
137
|
result := io.await(IO_file.write(fd, data.ptr().unwrap(), u32(data.len()), u64(0)));
|
|
134
|
-
IOError.
|
|
138
|
+
IOError.check(result)
|
|
135
139
|
}
|
|
136
140
|
)
|
|
137
141
|
)
|
|
138
142
|
}),
|
|
139
143
|
|
|
140
144
|
// Read the entire file into a byte list.
|
|
141
|
-
|
|
145
|
+
read_bytes : (fn(self: Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
|
|
142
146
|
fd := self._fd;
|
|
143
|
-
io.async((using(io
|
|
147
|
+
io.async((using(io, exn)) => {
|
|
144
148
|
buf_size := usize(4096);
|
|
145
149
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
146
150
|
result := ArrayList(u8).new();
|
|
147
151
|
offset := u64(0);
|
|
148
|
-
(read_err : Option(IOError)) = .None;
|
|
149
152
|
while runtime(true), {
|
|
150
153
|
n := io.await(IO_file.read(fd, buf, u32(buf_size), offset));
|
|
151
154
|
cond(
|
|
152
155
|
(n < i32(0)) => {
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
free(.Some(*(void)(buf)));
|
|
157
|
+
exn.throw(dyn IOError.from_errno((i32(0) - n)));
|
|
155
158
|
},
|
|
156
159
|
(n == i32(0)) => break,
|
|
157
160
|
true => {
|
|
@@ -165,43 +168,37 @@ impl(File,
|
|
|
165
168
|
);
|
|
166
169
|
};
|
|
167
170
|
free(.Some(*(void)(buf)));
|
|
168
|
-
|
|
169
|
-
.Some(e) => .Err(e),
|
|
170
|
-
.None => .Ok(result)
|
|
171
|
-
)
|
|
171
|
+
result
|
|
172
172
|
})
|
|
173
173
|
}),
|
|
174
174
|
|
|
175
175
|
// Read the entire file into a String.
|
|
176
|
-
|
|
177
|
-
io.async((using(io
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
.Ok(bytes) => .Ok(String.from_bytes(bytes)),
|
|
181
|
-
.Err(e) => .Err(e)
|
|
182
|
-
)
|
|
176
|
+
read_string : (fn(self: Self, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
177
|
+
io.async((using(io, exn)) => {
|
|
178
|
+
bytes := io.await(self.read_bytes());
|
|
179
|
+
String.from_bytes(bytes)
|
|
183
180
|
})
|
|
184
181
|
),
|
|
185
182
|
|
|
186
183
|
// Sync file data to disk.
|
|
187
|
-
flush : (fn(self: Self, using(io : IO)) -> Impl(Future(
|
|
184
|
+
flush : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
188
185
|
fd := self._fd;
|
|
189
|
-
io.async((using(io
|
|
186
|
+
io.async((using(io, exn)) => {
|
|
190
187
|
result := io.await(IO_file.fsync(fd));
|
|
191
188
|
cond(
|
|
192
|
-
(result < i32(0)) => .
|
|
193
|
-
true =>
|
|
189
|
+
(result < i32(0)) => exn.throw(dyn IOError.from_errno((i32(0) - result))),
|
|
190
|
+
true => ()
|
|
194
191
|
)
|
|
195
192
|
})
|
|
196
193
|
}),
|
|
197
194
|
|
|
198
195
|
// Seek to a position. Returns the new absolute position.
|
|
199
196
|
// whence: SEEK_SET(0), SEEK_CUR(1), SEEK_END(2)
|
|
200
|
-
seek : (fn(self: Self, offset: i64, whence: i32) ->
|
|
197
|
+
seek : (fn(self: Self, offset: i64, whence: i32, using(exn : Exception)) -> i64)({
|
|
201
198
|
result := IO_seek.lseek(self._fd, offset, whence);
|
|
202
199
|
cond(
|
|
203
|
-
(result < i64(0)) => .
|
|
204
|
-
true =>
|
|
200
|
+
(result < i64(0)) => exn.throw(dyn IOError.from_errno(i32((i64(0) - result)))),
|
|
201
|
+
true => result
|
|
205
202
|
)
|
|
206
203
|
}),
|
|
207
204
|
|
|
@@ -216,17 +213,17 @@ impl(File,
|
|
|
216
213
|
),
|
|
217
214
|
|
|
218
215
|
// Close the file.
|
|
219
|
-
close : (fn(self: Self, using(io : IO)) -> Impl(Future(
|
|
216
|
+
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
220
217
|
fd := self._fd;
|
|
221
|
-
io.async((using(io
|
|
218
|
+
io.async((using(io, exn)) =>
|
|
222
219
|
cond(
|
|
223
|
-
self._is_closed =>
|
|
220
|
+
self._is_closed => (),
|
|
224
221
|
true => {
|
|
225
222
|
result := io.await(IO_file.close(fd));
|
|
226
223
|
self._is_closed = true;
|
|
227
224
|
cond(
|
|
228
|
-
(result < i32(0)) => .
|
|
229
|
-
true =>
|
|
225
|
+
(result < i32(0)) => exn.throw(dyn IOError.from_errno((i32(0) - result))),
|
|
226
|
+
true => ()
|
|
230
227
|
)
|
|
231
228
|
}
|
|
232
229
|
)
|
|
@@ -244,8 +241,8 @@ impl(File,
|
|
|
244
241
|
),
|
|
245
242
|
|
|
246
243
|
// Get file metadata.
|
|
247
|
-
metadata : (fn(self: Self, using(io : IO)) -> Impl(Future(
|
|
248
|
-
_metadata_mod.metadata(self._path
|
|
244
|
+
metadata : (fn(self: Self, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(
|
|
245
|
+
_metadata_mod.metadata(self._path)
|
|
249
246
|
)
|
|
250
247
|
);
|
|
251
248
|
|
|
@@ -268,150 +265,117 @@ export File, OpenMode, FilePermission;
|
|
|
268
265
|
// ============================================================================
|
|
269
266
|
|
|
270
267
|
// Read an entire file into a String (Path version).
|
|
271
|
-
|
|
272
|
-
io.async((using(io
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
io.await(file.close(using(io)));
|
|
278
|
-
return content;
|
|
279
|
-
},
|
|
280
|
-
.Err(e) => .Err(e)
|
|
281
|
-
)
|
|
268
|
+
read_string :: (fn(path: Path, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
269
|
+
io.async((using(io, exn)) => {
|
|
270
|
+
file := io.await(File.open(path, .Read));
|
|
271
|
+
content := io.await(file.read_string());
|
|
272
|
+
io.await(file.close());
|
|
273
|
+
return content;
|
|
282
274
|
})
|
|
283
275
|
);
|
|
284
276
|
|
|
285
277
|
// Read an entire file into a String (str version).
|
|
286
|
-
|
|
287
|
-
|
|
278
|
+
read_string_str :: (fn(path: str, using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
279
|
+
read_string(Path.new(String.from(path)))
|
|
288
280
|
);
|
|
289
281
|
|
|
290
282
|
// Read an entire file into a String (C string version).
|
|
291
|
-
|
|
292
|
-
|
|
283
|
+
read_string_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(String, IO, Exception)))(
|
|
284
|
+
read_string(Path.from_cstr(path))
|
|
293
285
|
);
|
|
294
286
|
|
|
295
287
|
// Read an entire file into bytes (Path version).
|
|
296
|
-
read_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(
|
|
297
|
-
io.async((using(io
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
io.await(file.close(using(io)));
|
|
303
|
-
return content;
|
|
304
|
-
},
|
|
305
|
-
.Err(e) => .Err(e)
|
|
306
|
-
)
|
|
288
|
+
read_file :: (fn(path: Path, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
289
|
+
io.async((using(io, exn)) => {
|
|
290
|
+
file := io.await(File.open(path, .Read));
|
|
291
|
+
content := io.await(file.read_bytes());
|
|
292
|
+
io.await(file.close());
|
|
293
|
+
return content;
|
|
307
294
|
})
|
|
308
295
|
);
|
|
309
296
|
|
|
310
297
|
// Read an entire file into bytes (str version).
|
|
311
|
-
read_file_str :: (fn(path: str, using(io : IO)) -> Impl(Future(
|
|
312
|
-
read_file(Path.new(String.from(path))
|
|
298
|
+
read_file_str :: (fn(path: str, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
299
|
+
read_file(Path.new(String.from(path)))
|
|
313
300
|
);
|
|
314
301
|
|
|
315
302
|
// Read an entire file into bytes (C string version).
|
|
316
|
-
read_file_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(
|
|
317
|
-
read_file(Path.from_cstr(path)
|
|
303
|
+
read_file_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))(
|
|
304
|
+
read_file(Path.from_cstr(path))
|
|
318
305
|
);
|
|
319
306
|
|
|
320
|
-
// Write a
|
|
321
|
-
write_file :: (fn(path: Path, data:
|
|
322
|
-
io.async((using(io
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
write_result := io.await(file.write(String.from(data), using(io)));
|
|
327
|
-
io.await(file.close(using(io)));
|
|
328
|
-
match(write_result,
|
|
329
|
-
.Ok(_) => .Ok(()),
|
|
330
|
-
.Err(e) => .Err(e)
|
|
331
|
-
)
|
|
332
|
-
},
|
|
333
|
-
.Err(e) => .Err(e)
|
|
334
|
-
)
|
|
307
|
+
// Write a String to a file (creates or truncates) (Path version).
|
|
308
|
+
write_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
309
|
+
io.async((using(io, exn)) => {
|
|
310
|
+
file := io.await(File.open(path, .Write));
|
|
311
|
+
io.await(file.write_string(data));
|
|
312
|
+
io.await(file.close());
|
|
335
313
|
})
|
|
336
314
|
);
|
|
337
315
|
|
|
338
316
|
// Write a str to a file (creates or truncates) (str path version).
|
|
339
|
-
write_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(
|
|
340
|
-
write_file(Path.new(String.from(path)), data
|
|
317
|
+
write_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
318
|
+
write_file(Path.new(String.from(path)), String.from(data))
|
|
341
319
|
);
|
|
342
320
|
|
|
343
321
|
// Write a str to a file (creates or truncates) (C string path version).
|
|
344
|
-
write_file_cstr :: (fn(path: *(u8), data: str, using(io : IO)) -> Impl(Future(
|
|
345
|
-
write_file(Path.from_cstr(path), data
|
|
322
|
+
write_file_cstr :: (fn(path: *(u8), data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
323
|
+
write_file(Path.from_cstr(path), String.from(data))
|
|
346
324
|
);
|
|
347
325
|
|
|
348
326
|
// Write bytes to a file (creates or truncates) (Path version).
|
|
349
|
-
write_bytes :: (fn(path: Path, data: ArrayList(u8), using(io : IO)) -> Impl(Future(
|
|
350
|
-
io.async((using(io
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
write_result := io.await(file.write_bytes(data, using(io)));
|
|
355
|
-
io.await(file.close(using(io)));
|
|
356
|
-
match(write_result,
|
|
357
|
-
.Ok(_) => .Ok(()),
|
|
358
|
-
.Err(e) => .Err(e)
|
|
359
|
-
)
|
|
360
|
-
},
|
|
361
|
-
.Err(e) => .Err(e)
|
|
362
|
-
)
|
|
327
|
+
write_bytes :: (fn(path: Path, data: ArrayList(u8), using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
328
|
+
io.async((using(io, exn)) => {
|
|
329
|
+
file := io.await(File.open(path, .Write));
|
|
330
|
+
io.await(file.write_bytes(data));
|
|
331
|
+
io.await(file.close());
|
|
363
332
|
})
|
|
364
333
|
);
|
|
365
334
|
|
|
366
335
|
// Append a str to a file (creates if not exists) (Path version).
|
|
367
|
-
append_file :: (fn(path: Path, data:
|
|
368
|
-
io.async((using(io
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
write_result := io.await(file.write(String.from(data), using(io)));
|
|
373
|
-
io.await(file.close(using(io)));
|
|
374
|
-
match(write_result,
|
|
375
|
-
.Ok(_) => .Ok(()),
|
|
376
|
-
.Err(e) => .Err(e)
|
|
377
|
-
)
|
|
378
|
-
},
|
|
379
|
-
.Err(e) => .Err(e)
|
|
380
|
-
)
|
|
336
|
+
append_file :: (fn(path: Path, data: String, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
337
|
+
io.async((using(io, exn)) => {
|
|
338
|
+
file := io.await(File.open(path, .Append));
|
|
339
|
+
io.await(file.write_string(data));
|
|
340
|
+
io.await(file.close());
|
|
381
341
|
})
|
|
382
342
|
);
|
|
383
343
|
|
|
384
344
|
// Append a str to a file (str path version).
|
|
385
|
-
append_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(
|
|
386
|
-
append_file(Path.new(String.from(path)), data
|
|
345
|
+
append_file_str :: (fn(path: str, data: str, using(io : IO)) -> Impl(Future(unit, IO, Exception)))(
|
|
346
|
+
append_file(Path.new(String.from(path)), String.from(data))
|
|
387
347
|
);
|
|
388
348
|
|
|
349
|
+
extern "Yo",
|
|
350
|
+
__yo_statx_buf_size : (fn() -> usize)
|
|
351
|
+
;
|
|
352
|
+
|
|
389
353
|
// Check if a path exists (Path version).
|
|
390
|
-
|
|
354
|
+
// Does NOT use Exception — returns false for any error (including file not found).
|
|
355
|
+
exists :: (fn(path: Path, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
391
356
|
io.async((using(io : IO)) => {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
)
|
|
357
|
+
cstr_bytes := path.to_string().to_cstr();
|
|
358
|
+
cstr := cstr_bytes.ptr().unwrap();
|
|
359
|
+
buf_size := __yo_statx_buf_size();
|
|
360
|
+
buf := *(u8)(malloc(buf_size).unwrap());
|
|
361
|
+
result := io.await(IO_file.statx(AT_FDCWD, cstr, AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, buf));
|
|
362
|
+
free(.Some(*(void)(buf)));
|
|
363
|
+
(result >= i32(0))
|
|
400
364
|
})
|
|
401
365
|
);
|
|
402
366
|
|
|
403
367
|
// Check if a path exists (str version).
|
|
404
|
-
exists_str :: (fn(path: str, using(io : IO)) -> Impl(Future(
|
|
368
|
+
exists_str :: (fn(path: str, using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
405
369
|
exists(Path.new(String.from(path)), using(io))
|
|
406
370
|
);
|
|
407
371
|
|
|
408
372
|
// Check if a path exists (C string version).
|
|
409
|
-
exists_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(
|
|
373
|
+
exists_cstr :: (fn(path: *(u8), using(io : IO)) -> Impl(Future(bool, IO)))(
|
|
410
374
|
exists(Path.from_cstr(path), using(io))
|
|
411
375
|
);
|
|
412
376
|
|
|
413
377
|
export
|
|
414
|
-
|
|
378
|
+
read_string, read_string_str, read_string_cstr,
|
|
415
379
|
read_file, read_file_str, read_file_cstr,
|
|
416
380
|
write_file, write_file_str, write_file_cstr,
|
|
417
381
|
write_bytes,
|
package/std/fs/metadata.yo
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
// std/fs/metadata.yo - File metadata
|
|
2
2
|
//
|
|
3
3
|
// Wraps the low-level statx buffer with ergonomic accessors.
|
|
4
|
+
// Uses Exception effect for error handling.
|
|
4
5
|
//
|
|
5
6
|
// Example:
|
|
6
7
|
// { metadata } :: import "std/fs/metadata";
|
|
7
8
|
//
|
|
8
9
|
// main :: (fn(using(io : IO)) -> unit)({
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// );
|
|
10
|
+
// given(exn) : Exception = {
|
|
11
|
+
// throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
12
|
+
// { println(error.to_string()); exit(i32(1)); }
|
|
13
|
+
// )
|
|
14
|
+
// };
|
|
15
|
+
//
|
|
16
|
+
// m := io.await(metadata(Path.new(`/tmp/test.txt`)));
|
|
17
|
+
// printf("size: %lld\n", m.size());
|
|
18
|
+
// printf("is file: %d\n", i32(m.is_file()));
|
|
17
19
|
// });
|
|
18
20
|
|
|
19
21
|
{ GlobalAllocator } :: import "../allocator";
|
|
@@ -21,6 +23,7 @@
|
|
|
21
23
|
open import "../string";
|
|
22
24
|
{ Path } :: import "../path";
|
|
23
25
|
{ IOError } :: import "../sys/errors";
|
|
26
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
24
27
|
{ Statx } :: import "../sys/statx";
|
|
25
28
|
IO_file :: import "../sys/file";
|
|
26
29
|
{
|
|
@@ -126,8 +129,8 @@ extern "Yo",
|
|
|
126
129
|
// Internal helper to stat a path
|
|
127
130
|
// ============================================================================
|
|
128
131
|
|
|
129
|
-
_stat_path :: (fn(path: Path, flags: i32, using(io : IO)) -> Impl(Future(
|
|
130
|
-
io.async((using(io)) => {
|
|
132
|
+
_stat_path :: (fn(path: Path, flags: i32, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))(
|
|
133
|
+
io.async((using(io, exn)) => {
|
|
131
134
|
cstr_bytes := path.to_string().to_cstr();
|
|
132
135
|
cstr := cstr_bytes.ptr().unwrap();
|
|
133
136
|
buf_size := __yo_statx_buf_size();
|
|
@@ -136,34 +139,32 @@ _stat_path :: (fn(path: Path, flags: i32, using(io : IO)) -> Impl(Future(Result(
|
|
|
136
139
|
cond(
|
|
137
140
|
(result < i32(0)) => {
|
|
138
141
|
free(.Some(*(void)(buf)));
|
|
139
|
-
(
|
|
140
|
-
return ret;
|
|
142
|
+
exn.throw(dyn IOError.from_errno((i32(0) - result)))
|
|
141
143
|
},
|
|
142
144
|
true => {
|
|
143
145
|
sx := Statx(_buf_ptr: buf, _buf_size: buf_size);
|
|
144
|
-
|
|
145
|
-
return ret;
|
|
146
|
+
Metadata(_statx: sx, _buf_ptr: buf)
|
|
146
147
|
}
|
|
147
148
|
)
|
|
148
149
|
})
|
|
149
150
|
);
|
|
150
151
|
|
|
151
152
|
// Get metadata for a path (follows symlinks).
|
|
152
|
-
metadata :: (fn(path: Path, using(io : IO)) -> Impl(Future(
|
|
153
|
-
_stat_path(path, AT_STATX_SYNC_AS_STAT
|
|
153
|
+
metadata :: (fn(path: Path, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))
|
|
154
|
+
_stat_path(path, AT_STATX_SYNC_AS_STAT)
|
|
154
155
|
;
|
|
155
156
|
|
|
156
|
-
metadata_str :: (fn(path: str, using(io : IO)) -> Impl(Future(
|
|
157
|
-
metadata(Path.new(String.from(path))
|
|
157
|
+
metadata_str :: (fn(path: str, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))
|
|
158
|
+
metadata(Path.new(String.from(path)))
|
|
158
159
|
;
|
|
159
160
|
|
|
160
161
|
// Get metadata for a path (does NOT follow symlinks).
|
|
161
|
-
symlink_metadata :: (fn(path: Path, using(io : IO)) -> Impl(Future(
|
|
162
|
-
_stat_path(path, (AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT)
|
|
162
|
+
symlink_metadata :: (fn(path: Path, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))
|
|
163
|
+
_stat_path(path, (AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT))
|
|
163
164
|
;
|
|
164
165
|
|
|
165
|
-
symlink_metadata_str :: (fn(path: str, using(io : IO)) -> Impl(Future(
|
|
166
|
-
symlink_metadata(Path.new(String.from(path))
|
|
166
|
+
symlink_metadata_str :: (fn(path: str, using(io : IO)) -> Impl(Future(Metadata, IO, Exception)))
|
|
167
|
+
symlink_metadata(Path.new(String.from(path)))
|
|
167
168
|
;
|
|
168
169
|
|
|
169
170
|
export metadata, metadata_str, symlink_metadata, symlink_metadata_str;
|