@shd101wyy/yo 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/out/cjs/index.cjs +579 -573
- package/out/cjs/yo-cli.cjs +1413 -592
- package/out/esm/index.mjs +437 -431
- package/out/types/src/build-runner.d.ts +1 -1
- package/out/types/src/doc/builder.d.ts +21 -0
- package/out/types/src/doc/builder.test.d.ts +1 -0
- package/out/types/src/doc/extractor.d.ts +27 -0
- package/out/types/src/doc/extractor.test.d.ts +1 -0
- package/out/types/src/doc/model.d.ts +87 -0
- package/out/types/src/doc/render-html.d.ts +23 -0
- package/out/types/src/doc/render-html.test.d.ts +1 -0
- package/out/types/src/doc/render-json.d.ts +7 -0
- package/out/types/src/doc/render-json.test.d.ts +1 -0
- package/out/types/src/doc/render-markdown.d.ts +13 -0
- package/out/types/src/doc/render-markdown.test.d.ts +1 -0
- package/out/types/src/doc/sections.d.ts +7 -0
- package/out/types/src/doc/sections.test.d.ts +1 -0
- package/out/types/src/doc-command.d.ts +10 -0
- package/out/types/src/env.d.ts +1 -0
- package/out/types/src/evaluator/builtins/build.d.ts +17 -0
- package/out/types/src/evaluator/context.d.ts +1 -0
- package/out/types/src/evaluator/exprs/import.d.ts +2 -0
- package/out/types/src/expr.d.ts +2 -1
- package/out/types/src/tests/import-path.test.d.ts +1 -0
- package/out/types/src/token.d.ts +4 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/scripts/build-site.ts +461 -0
- package/std/alg/hash.yo +12 -24
- package/std/allocator.yo +21 -29
- package/std/async.yo +4 -2
- package/std/build.yo +188 -42
- package/std/cli/arg_parser.yo +37 -1
- package/std/collections/array_list.yo +8 -20
- package/std/collections/btree_map.yo +15 -20
- package/std/collections/deque.yo +13 -15
- package/std/collections/hash_map.yo +15 -54
- package/std/collections/hash_set.yo +14 -50
- package/std/collections/linked_list.yo +6 -23
- package/std/collections/priority_queue.yo +15 -17
- package/std/crypto/md5.yo +10 -9
- package/std/crypto/random.yo +14 -12
- package/std/crypto/sha256.yo +9 -8
- package/std/encoding/base64.yo +13 -15
- package/std/encoding/hex.yo +14 -10
- package/std/encoding/html.yo +14 -11
- package/std/encoding/html_char_utils.yo +14 -11
- package/std/encoding/html_entities.yo +7 -8
- package/std/encoding/json.yo +36 -19
- package/std/encoding/punycode.yo +21 -18
- package/std/encoding/toml.yo +23 -9
- package/std/encoding/utf16.yo +16 -9
- package/std/error.yo +10 -23
- package/std/fmt/display.yo +15 -17
- package/std/fmt/index.yo +6 -27
- package/std/fmt/to_string.yo +4 -10
- package/std/fmt/writer.yo +33 -34
- package/std/fs/dir.yo +37 -30
- package/std/fs/file.yo +77 -75
- package/std/fs/metadata.yo +25 -25
- package/std/fs/temp.yo +21 -27
- package/std/fs/types.yo +20 -23
- package/std/fs/walker.yo +26 -31
- package/std/gc.yo +5 -0
- package/std/glob/index.yo +3 -0
- package/std/http/client.yo +25 -11
- package/std/http/http.yo +20 -0
- package/std/http/index.yo +1 -0
- package/std/io/reader.yo +4 -8
- package/std/io/writer.yo +4 -7
- package/std/libc/assert.yo +2 -2
- package/std/libc/ctype.yo +1 -2
- package/std/libc/dirent.yo +1 -2
- package/std/libc/errno.yo +1 -2
- package/std/libc/fcntl.yo +2 -2
- package/std/libc/float.yo +1 -2
- package/std/libc/limits.yo +1 -2
- package/std/libc/math.yo +2 -0
- package/std/libc/signal.yo +1 -2
- package/std/libc/stdatomic.yo +1 -2
- package/std/libc/stdint.yo +4 -3
- package/std/libc/stdio.yo +2 -0
- package/std/libc/stdlib.yo +2 -0
- package/std/libc/string.yo +2 -0
- package/std/libc/sys/stat.yo +1 -2
- package/std/libc/time.yo +2 -2
- package/std/libc/unistd.yo +2 -0
- package/std/libc/wctype.yo +1 -2
- package/std/libc/windows.yo +2 -2
- package/std/log/index.yo +11 -26
- package/std/net/addr.yo +18 -11
- package/std/net/dns.yo +3 -2
- package/std/net/errors.yo +16 -2
- package/std/net/tcp.yo +25 -22
- package/std/net/udp.yo +14 -12
- package/std/os/env.yo +23 -18
- package/std/os/signal.yo +31 -19
- package/std/path.yo +23 -74
- package/std/prelude.yo +284 -113
- package/std/process.yo +23 -37
- package/std/regex/compiler.yo +3 -5
- package/std/regex/flags.yo +11 -11
- package/std/regex/index.yo +2 -13
- package/std/regex/match.yo +3 -5
- package/std/regex/node.yo +6 -6
- package/std/regex/parser.yo +2 -4
- package/std/regex/unicode.yo +5 -5
- package/std/regex/vm.yo +5 -5
- package/std/string/index.yo +2 -1
- package/std/string/rune.yo +25 -1
- package/std/string/string.yo +31 -19
- package/std/string/unicode.yo +14 -15
- package/std/sync/channel.yo +18 -28
- package/std/sync/cond.yo +4 -0
- package/std/sync/mutex.yo +4 -1
- package/std/sync/once.yo +17 -19
- package/std/sync/rwlock.yo +19 -22
- package/std/sync/waitgroup.yo +21 -23
- package/std/sys/advise.yo +4 -4
- package/std/sys/bufio/buf_reader.yo +19 -16
- package/std/sys/bufio/buf_writer.yo +14 -11
- package/std/sys/clock.yo +4 -4
- package/std/sys/constants.yo +5 -5
- package/std/sys/copy.yo +9 -8
- package/std/sys/dir.yo +9 -8
- package/std/sys/dns.yo +8 -8
- package/std/sys/errors.yo +35 -6
- package/std/sys/events.yo +3 -3
- package/std/sys/externs.yo +3 -3
- package/std/sys/fallocate.yo +4 -4
- package/std/sys/fcntl.yo +8 -6
- package/std/sys/file.yo +7 -8
- package/std/sys/future.yo +1 -3
- package/std/sys/iov.yo +4 -4
- package/std/sys/lock.yo +7 -7
- package/std/sys/mmap.yo +7 -8
- package/std/sys/path.yo +4 -7
- package/std/sys/perm.yo +8 -8
- package/std/sys/pipe.yo +9 -8
- package/std/sys/process.yo +8 -8
- package/std/sys/seek.yo +4 -4
- package/std/sys/signal.yo +4 -4
- package/std/sys/signals.yo +4 -4
- package/std/sys/socket.yo +4 -4
- package/std/sys/socketpair.yo +4 -4
- package/std/sys/sockinfo.yo +4 -4
- package/std/sys/statfs.yo +8 -8
- package/std/sys/statx.yo +4 -4
- package/std/sys/sysinfo.yo +4 -4
- package/std/sys/tcp.yo +8 -8
- package/std/sys/temp.yo +9 -8
- package/std/sys/time.yo +8 -8
- package/std/sys/timer.yo +7 -8
- package/std/sys/tty.yo +13 -10
- package/std/sys/udp.yo +8 -8
- package/std/sys/umask.yo +4 -4
- package/std/sys/unix.yo +5 -5
- package/std/testing/bench.yo +21 -10
- package/std/thread.yo +18 -9
- package/std/time/datetime.yo +12 -14
- package/std/time/duration.yo +12 -14
- package/std/time/instant.yo +13 -16
- package/std/time/sleep.yo +9 -8
- package/std/url/index.yo +3 -19
- package/std/worker.yo +10 -18
package/std/net/addr.yo
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//! Network address types — IP addresses and socket addresses.
|
|
1
2
|
// std/net/addr.yo - Network address types
|
|
2
3
|
//
|
|
3
4
|
// High-level IP address and socket address types.
|
|
@@ -25,14 +26,17 @@ _ASCII_DOT :: u8(46); // '.'
|
|
|
25
26
|
_ASCII_ZERO :: u8(48); // '0'
|
|
26
27
|
_ASCII_NINE :: u8(57); // '9'
|
|
27
28
|
|
|
29
|
+
/// An IP address, either IPv4 or IPv6.
|
|
28
30
|
IpAddr :: enum(
|
|
31
|
+
/// An IPv4 address represented as four octets.
|
|
29
32
|
V4(a: u8, b: u8, c: u8, d: u8),
|
|
33
|
+
/// An IPv6 address represented as eight 16-bit segments.
|
|
30
34
|
V6(segments: Array(u16, usize(8)))
|
|
31
35
|
);
|
|
32
36
|
|
|
33
37
|
impl(IpAddr,
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
/// Parse an IPv4 address from a dotted-decimal `String` (e.g. "127.0.0.1").
|
|
39
|
+
/// Throws on invalid input.
|
|
36
40
|
parse_v4 : (fn(s: String, using(exn : Exception)) -> IpAddr)({
|
|
37
41
|
bytes := s.as_bytes();
|
|
38
42
|
parts := Array(u8, usize(4)).fill(u8(0));
|
|
@@ -86,24 +90,24 @@ impl(IpAddr,
|
|
|
86
90
|
.V4(parts(usize(0)), parts(usize(1)), parts(usize(2)), parts(usize(3)))
|
|
87
91
|
}),
|
|
88
92
|
|
|
89
|
-
|
|
93
|
+
/// Return the IPv4 loopback address (127.0.0.1).
|
|
90
94
|
loopback_v4 : (fn() -> IpAddr)(
|
|
91
95
|
.V4(u8(127), u8(0), u8(0), u8(1))
|
|
92
96
|
),
|
|
93
97
|
|
|
94
|
-
|
|
98
|
+
/// Return the IPv6 loopback address (::1).
|
|
95
99
|
loopback_v6 : (fn() -> IpAddr)({
|
|
96
100
|
segs := Array(u16, usize(8)).fill(u16(0));
|
|
97
101
|
segs(usize(7)) = u16(1);
|
|
98
102
|
.V6(segs)
|
|
99
103
|
}),
|
|
100
104
|
|
|
101
|
-
|
|
105
|
+
/// Return the IPv4 unspecified address (0.0.0.0).
|
|
102
106
|
any_v4 : (fn() -> IpAddr)(
|
|
103
107
|
.V4(u8(0), u8(0), u8(0), u8(0))
|
|
104
108
|
),
|
|
105
109
|
|
|
106
|
-
|
|
110
|
+
/// Return `true` if this is a loopback address.
|
|
107
111
|
is_loopback : (fn(self: Self) -> bool)(
|
|
108
112
|
match(self,
|
|
109
113
|
.V4(a, _, _, _) => (a == u8(127)),
|
|
@@ -123,7 +127,7 @@ impl(IpAddr,
|
|
|
123
127
|
)
|
|
124
128
|
),
|
|
125
129
|
|
|
126
|
-
|
|
130
|
+
/// Return `true` if this is an IPv4 address.
|
|
127
131
|
is_v4 : (fn(self: Self) -> bool)(
|
|
128
132
|
match(self,
|
|
129
133
|
.V4(_, _, _, _) => true,
|
|
@@ -131,7 +135,7 @@ impl(IpAddr,
|
|
|
131
135
|
)
|
|
132
136
|
),
|
|
133
137
|
|
|
134
|
-
|
|
138
|
+
/// Return `true` if this is an IPv6 address.
|
|
135
139
|
is_v6 : (fn(self: Self) -> bool)(
|
|
136
140
|
match(self,
|
|
137
141
|
.V4(_, _, _, _) => false,
|
|
@@ -171,23 +175,26 @@ export IpAddr;
|
|
|
171
175
|
// SocketAddr
|
|
172
176
|
// ============================================================================
|
|
173
177
|
|
|
178
|
+
/// An IP address paired with a port number.
|
|
174
179
|
SocketAddr :: struct(
|
|
180
|
+
/// The IP address.
|
|
175
181
|
ip : IpAddr,
|
|
182
|
+
/// The port number.
|
|
176
183
|
port : u16
|
|
177
184
|
);
|
|
178
185
|
|
|
179
186
|
impl(SocketAddr,
|
|
180
|
-
|
|
187
|
+
/// Create a new socket address from an IP and port.
|
|
181
188
|
new : (fn(ip: IpAddr, port: u16) -> Self)(
|
|
182
189
|
Self(ip: ip, port: port)
|
|
183
190
|
),
|
|
184
191
|
|
|
185
|
-
|
|
192
|
+
/// Create an IPv4 loopback socket address (127.0.0.1) with the given port.
|
|
186
193
|
loopback : (fn(port: u16) -> Self)(
|
|
187
194
|
Self(ip: IpAddr.loopback_v4(), port: port)
|
|
188
195
|
),
|
|
189
196
|
|
|
190
|
-
|
|
197
|
+
/// Create an IPv4 unspecified socket address (0.0.0.0) with the given port.
|
|
191
198
|
any : (fn(port: u16) -> Self)(
|
|
192
199
|
Self(ip: IpAddr.any_v4(), port: port)
|
|
193
200
|
)
|
package/std/net/dns.yo
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//! Async DNS resolution.
|
|
1
2
|
// std/net/dns.yo - High-level DNS resolution
|
|
2
3
|
//
|
|
3
4
|
// Wraps std/sys/dns with typed DNS lookup functions.
|
|
@@ -36,7 +37,7 @@ IO_dns :: import "../sys/dns";
|
|
|
36
37
|
// DNS lookup
|
|
37
38
|
// ============================================================================
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
/// Resolve a hostname to a list of IP addresses.
|
|
40
41
|
lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(ArrayList(IpAddr), IO, Exception)))(
|
|
41
42
|
io.async((using(io : IO, exn : Exception)) => {
|
|
42
43
|
host_cstr_bytes := host.to_cstr();
|
|
@@ -84,7 +85,7 @@ lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(ArrayList(IpAddr
|
|
|
84
85
|
})
|
|
85
86
|
);
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
/// Resolve a hostname and port to a list of socket addresses.
|
|
88
89
|
resolve :: (fn(host: String, port: u16, using(io : IO)) -> Impl(Future(ArrayList(SocketAddr), IO, Exception)))(
|
|
89
90
|
io.async((using(io : IO, exn : Exception)) => {
|
|
90
91
|
addrs := io.await(lookup_host(host, using(io)));
|
package/std/net/errors.yo
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//! Network error types.
|
|
1
2
|
// std/net/errors.yo - Network error type
|
|
2
3
|
//
|
|
3
4
|
// Higher-level network error that wraps IOError with network-specific variants.
|
|
@@ -14,22 +15,34 @@ open import "../string";
|
|
|
14
15
|
// NetError
|
|
15
16
|
// ============================================================================
|
|
16
17
|
|
|
18
|
+
/// Network-specific error type wrapping lower-level I/O errors.
|
|
17
19
|
NetError :: enum(
|
|
20
|
+
/// The remote host refused the connection.
|
|
18
21
|
ConnectionRefused,
|
|
22
|
+
/// The connection was reset by the remote host.
|
|
19
23
|
ConnectionReset,
|
|
24
|
+
/// The connection was aborted locally.
|
|
20
25
|
ConnectionAborted,
|
|
26
|
+
/// The address is already in use.
|
|
21
27
|
AddrInUse,
|
|
28
|
+
/// The requested address is not available.
|
|
22
29
|
AddrNotAvailable,
|
|
30
|
+
/// The operation timed out.
|
|
23
31
|
TimedOut,
|
|
32
|
+
/// The remote host is unreachable.
|
|
24
33
|
HostUnreachable,
|
|
34
|
+
/// The network is unreachable.
|
|
25
35
|
NetworkUnreachable,
|
|
36
|
+
/// DNS resolution failed.
|
|
26
37
|
DNSFailed(msg: String),
|
|
38
|
+
/// A wrapped lower-level I/O error.
|
|
27
39
|
IO(err: IOError),
|
|
40
|
+
/// An unclassified network error with a message.
|
|
28
41
|
Other(msg: String)
|
|
29
42
|
);
|
|
30
43
|
|
|
31
44
|
impl(NetError,
|
|
32
|
-
|
|
45
|
+
/// Convert an `IOError` into the corresponding `NetError` variant.
|
|
33
46
|
from_io : (fn(err: IOError) -> Self)(
|
|
34
47
|
match(err,
|
|
35
48
|
.ConnectionRefused => .ConnectionRefused,
|
|
@@ -67,7 +80,8 @@ impl(NetError, ToString(
|
|
|
67
80
|
impl(NetError, Error());
|
|
68
81
|
|
|
69
82
|
impl(NetError,
|
|
70
|
-
|
|
83
|
+
/// Check a raw syscall result and throw on error.
|
|
84
|
+
/// Positive values are returned as-is; negative values are converted to a `NetError` and thrown.
|
|
71
85
|
check : (fn(result: i32, using(exn : Exception)) -> i32)(
|
|
72
86
|
cond(
|
|
73
87
|
(result >= i32(0)) => result,
|
package/std/net/tcp.yo
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//! Async TCP networking — listeners and streams with Exception-based error handling.
|
|
1
2
|
// std/net/tcp.yo - High-level TCP types
|
|
2
3
|
//
|
|
3
4
|
// Wraps std/sys/tcp with typed TcpListener and TcpStream objects.
|
|
@@ -63,6 +64,7 @@ _throw_io :: (fn(errno_val: i32, using(exn : Exception)) -> unit)(
|
|
|
63
64
|
// TcpStream (declared before TcpListener so accept can reference it)
|
|
64
65
|
// ============================================================================
|
|
65
66
|
|
|
67
|
+
/// A connected TCP stream for bidirectional data transfer.
|
|
66
68
|
TcpStream :: object(
|
|
67
69
|
_fd : i32,
|
|
68
70
|
_peer_addr : SocketAddr,
|
|
@@ -73,6 +75,7 @@ TcpStream :: object(
|
|
|
73
75
|
// TcpListener
|
|
74
76
|
// ============================================================================
|
|
75
77
|
|
|
78
|
+
/// A TCP socket that listens for incoming connections.
|
|
76
79
|
TcpListener :: object(
|
|
77
80
|
_fd : i32,
|
|
78
81
|
_local_addr : SocketAddr,
|
|
@@ -80,7 +83,7 @@ TcpListener :: object(
|
|
|
80
83
|
);
|
|
81
84
|
|
|
82
85
|
impl(TcpListener,
|
|
83
|
-
|
|
86
|
+
/// Bind to a socket address and start listening.
|
|
84
87
|
bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(TcpListener, IO, Exception)))(
|
|
85
88
|
io.async((using(io : IO, exn : Exception)) => {
|
|
86
89
|
domain := cond(
|
|
@@ -118,7 +121,7 @@ impl(TcpListener,
|
|
|
118
121
|
})
|
|
119
122
|
),
|
|
120
123
|
|
|
121
|
-
|
|
124
|
+
/// Accept an incoming connection, returning a new `TcpStream`.
|
|
122
125
|
accept : (fn(self: Self, using(io : IO)) -> Impl(Future(TcpStream, IO, Exception)))({
|
|
123
126
|
fd := self._fd;
|
|
124
127
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -148,12 +151,12 @@ impl(TcpListener,
|
|
|
148
151
|
})
|
|
149
152
|
}),
|
|
150
153
|
|
|
151
|
-
|
|
154
|
+
/// Get the local address this listener is bound to.
|
|
152
155
|
local_addr : (fn(self: Self) -> SocketAddr)(
|
|
153
156
|
self._local_addr
|
|
154
157
|
),
|
|
155
158
|
|
|
156
|
-
|
|
159
|
+
/// Close the listener socket.
|
|
157
160
|
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
158
161
|
fd := self._fd;
|
|
159
162
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -171,7 +174,7 @@ impl(TcpListener,
|
|
|
171
174
|
})
|
|
172
175
|
}),
|
|
173
176
|
|
|
174
|
-
|
|
177
|
+
/// Get the underlying file descriptor.
|
|
175
178
|
fd : (fn(self: Self) -> i32)(
|
|
176
179
|
self._fd
|
|
177
180
|
)
|
|
@@ -197,7 +200,7 @@ export TcpListener;
|
|
|
197
200
|
// ============================================================================
|
|
198
201
|
|
|
199
202
|
impl(TcpStream,
|
|
200
|
-
|
|
203
|
+
/// Connect to a remote address, returning a new `TcpStream`.
|
|
201
204
|
connect : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(TcpStream, IO, Exception)))(
|
|
202
205
|
io.async((using(io : IO, exn : Exception)) => {
|
|
203
206
|
domain := cond(
|
|
@@ -224,8 +227,8 @@ impl(TcpStream,
|
|
|
224
227
|
})
|
|
225
228
|
),
|
|
226
229
|
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
/// Read bytes from the stream into `buf`.
|
|
231
|
+
/// Returns the number of bytes read, or 0 if the peer closed the connection.
|
|
229
232
|
read : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
230
233
|
fd := self._fd;
|
|
231
234
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -234,8 +237,8 @@ impl(TcpStream,
|
|
|
234
237
|
})
|
|
235
238
|
}),
|
|
236
239
|
|
|
237
|
-
|
|
238
|
-
|
|
240
|
+
/// Write a `str` to the stream.
|
|
241
|
+
/// Returns the number of bytes written.
|
|
239
242
|
write_str : (fn(self: Self, data: str, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
240
243
|
fd := self._fd;
|
|
241
244
|
s := String.from(data);
|
|
@@ -246,8 +249,8 @@ impl(TcpStream,
|
|
|
246
249
|
})
|
|
247
250
|
}),
|
|
248
251
|
|
|
249
|
-
|
|
250
|
-
|
|
252
|
+
/// Write a `String` to the stream.
|
|
253
|
+
/// Returns the number of bytes written.
|
|
251
254
|
write_string : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
252
255
|
fd := self._fd;
|
|
253
256
|
data_bytes := data.as_bytes();
|
|
@@ -257,8 +260,8 @@ impl(TcpStream,
|
|
|
257
260
|
})
|
|
258
261
|
}),
|
|
259
262
|
|
|
260
|
-
|
|
261
|
-
|
|
263
|
+
/// Write raw bytes from an `ArrayList(u8)` to the stream.
|
|
264
|
+
/// Returns the number of bytes written.
|
|
262
265
|
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
263
266
|
fd := self._fd;
|
|
264
267
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -267,7 +270,7 @@ impl(TcpStream,
|
|
|
267
270
|
})
|
|
268
271
|
}),
|
|
269
272
|
|
|
270
|
-
|
|
273
|
+
/// Read all available data from the stream into a byte list.
|
|
271
274
|
read_bytes : (fn(self: Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
|
|
272
275
|
fd := self._fd;
|
|
273
276
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -300,8 +303,8 @@ impl(TcpStream,
|
|
|
300
303
|
})
|
|
301
304
|
}),
|
|
302
305
|
|
|
303
|
-
|
|
304
|
-
|
|
306
|
+
/// Shut down part or all of the connection.
|
|
307
|
+
/// `how`: 0 = read, 1 = write, 2 = both.
|
|
305
308
|
shutdown : (fn(self: Self, how: i32, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
306
309
|
fd := self._fd;
|
|
307
310
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -313,7 +316,7 @@ impl(TcpStream,
|
|
|
313
316
|
})
|
|
314
317
|
}),
|
|
315
318
|
|
|
316
|
-
|
|
319
|
+
/// Close the stream.
|
|
317
320
|
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
318
321
|
fd := self._fd;
|
|
319
322
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -331,17 +334,17 @@ impl(TcpStream,
|
|
|
331
334
|
})
|
|
332
335
|
}),
|
|
333
336
|
|
|
334
|
-
|
|
337
|
+
/// Get the remote peer's socket address.
|
|
335
338
|
peer_addr : (fn(self: Self) -> SocketAddr)(
|
|
336
339
|
self._peer_addr
|
|
337
340
|
),
|
|
338
341
|
|
|
339
|
-
|
|
342
|
+
/// Get the underlying file descriptor.
|
|
340
343
|
fd : (fn(self: Self) -> i32)(
|
|
341
344
|
self._fd
|
|
342
345
|
),
|
|
343
346
|
|
|
344
|
-
|
|
347
|
+
/// Enable or disable TCP_NODELAY (disables Nagle's algorithm).
|
|
345
348
|
set_nodelay : (fn(self: Self, nodelay: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
346
349
|
sock_fd := self._fd;
|
|
347
350
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -355,7 +358,7 @@ impl(TcpStream,
|
|
|
355
358
|
})
|
|
356
359
|
}),
|
|
357
360
|
|
|
358
|
-
|
|
361
|
+
/// Enable or disable SO_KEEPALIVE on the socket.
|
|
359
362
|
set_keepalive : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
360
363
|
sock_fd := self._fd;
|
|
361
364
|
io.async((using(io : IO, exn : Exception)) => {
|
package/std/net/udp.yo
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//! Async UDP networking — connectionless datagram sockets.
|
|
1
2
|
// std/net/udp.yo - High-level UDP socket
|
|
2
3
|
//
|
|
3
4
|
// Wraps std/sys/udp with typed UdpSocket object.
|
|
@@ -59,6 +60,7 @@ _throw_net_io :: (fn(errno_val: i32, using(exn : Exception)) -> unit)(
|
|
|
59
60
|
// UdpSocket
|
|
60
61
|
// ============================================================================
|
|
61
62
|
|
|
63
|
+
/// A UDP socket for sending and receiving datagrams.
|
|
62
64
|
UdpSocket :: object(
|
|
63
65
|
_fd : i32,
|
|
64
66
|
_local_addr : SocketAddr,
|
|
@@ -66,7 +68,7 @@ UdpSocket :: object(
|
|
|
66
68
|
);
|
|
67
69
|
|
|
68
70
|
impl(UdpSocket,
|
|
69
|
-
|
|
71
|
+
/// Create and bind a UDP socket to the given address.
|
|
70
72
|
bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(UdpSocket, IO, Exception)))(
|
|
71
73
|
io.async((using(io : IO, exn : Exception)) => {
|
|
72
74
|
domain := cond(
|
|
@@ -89,8 +91,8 @@ impl(UdpSocket,
|
|
|
89
91
|
})
|
|
90
92
|
),
|
|
91
93
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
/// Send a datagram to a specific address.
|
|
95
|
+
/// Returns the number of bytes sent.
|
|
94
96
|
send_to : (fn(self: Self, data: ArrayList(u8), addr: SocketAddr, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
95
97
|
fd := self._fd;
|
|
96
98
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -101,8 +103,8 @@ impl(UdpSocket,
|
|
|
101
103
|
})
|
|
102
104
|
}),
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
/// Receive a datagram into the provided buffer.
|
|
107
|
+
/// Returns the number of bytes received.
|
|
106
108
|
recv : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
107
109
|
fd := self._fd;
|
|
108
110
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -111,8 +113,8 @@ impl(UdpSocket,
|
|
|
111
113
|
})
|
|
112
114
|
}),
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
/// Receive a datagram and retrieve the sender's address.
|
|
117
|
+
/// Returns the number of bytes received.
|
|
116
118
|
recv_from : (fn(self: Self, buf: *(u8), size: usize, src_addr: *(u8), src_addr_len: *(u32), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
117
119
|
fd := self._fd;
|
|
118
120
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -121,7 +123,7 @@ impl(UdpSocket,
|
|
|
121
123
|
})
|
|
122
124
|
}),
|
|
123
125
|
|
|
124
|
-
|
|
126
|
+
/// Send data on a connected socket (requires prior connect).
|
|
125
127
|
send : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
126
128
|
fd := self._fd;
|
|
127
129
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -130,7 +132,7 @@ impl(UdpSocket,
|
|
|
130
132
|
})
|
|
131
133
|
}),
|
|
132
134
|
|
|
133
|
-
|
|
135
|
+
/// Close the socket.
|
|
134
136
|
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
135
137
|
fd := self._fd;
|
|
136
138
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -148,7 +150,7 @@ impl(UdpSocket,
|
|
|
148
150
|
})
|
|
149
151
|
}),
|
|
150
152
|
|
|
151
|
-
|
|
153
|
+
/// Enable or disable SO_BROADCAST on the socket.
|
|
152
154
|
set_broadcast : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
153
155
|
fd := self._fd;
|
|
154
156
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -162,12 +164,12 @@ impl(UdpSocket,
|
|
|
162
164
|
})
|
|
163
165
|
}),
|
|
164
166
|
|
|
165
|
-
|
|
167
|
+
/// Get the local address this socket is bound to.
|
|
166
168
|
local_addr : (fn(self: Self) -> SocketAddr)(
|
|
167
169
|
self._local_addr
|
|
168
170
|
),
|
|
169
171
|
|
|
170
|
-
|
|
172
|
+
/// Get the underlying file descriptor.
|
|
171
173
|
fd : (fn(self: Self) -> i32)(
|
|
172
174
|
self._fd
|
|
173
175
|
)
|
package/std/os/env.yo
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
//! Environment directory utilities.
|
|
2
|
+
//!
|
|
3
|
+
//! Provides platform-aware paths for home, config, cache, and temp directories.
|
|
4
|
+
//!
|
|
5
|
+
//! # Example
|
|
6
|
+
//!
|
|
7
|
+
//! ```rust
|
|
8
|
+
//! { home_dir, temp_dir } :: import "std/os/env";
|
|
9
|
+
//!
|
|
10
|
+
//! home := home_dir();
|
|
11
|
+
//! tmp := temp_dir();
|
|
12
|
+
//! ```
|
|
10
13
|
|
|
11
14
|
open import "../string";
|
|
12
15
|
{ platform, Platform, env } :: import "../process";
|
|
@@ -15,7 +18,7 @@ open import "../string";
|
|
|
15
18
|
// Directory helpers
|
|
16
19
|
// ============================================================================
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
/// Return the current user's home directory, or `.None` if unavailable.
|
|
19
22
|
home_dir :: (fn() -> Option(String))(
|
|
20
23
|
cond(
|
|
21
24
|
(platform == Platform.Windows) => match(env.get(`USERPROFILE`),
|
|
@@ -32,9 +35,10 @@ home_dir :: (fn() -> Option(String))(
|
|
|
32
35
|
)
|
|
33
36
|
);
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
/// Return the user-specific configuration directory.
|
|
39
|
+
///
|
|
40
|
+
/// - Linux/macOS: `$XDG_CONFIG_HOME` or `$HOME/.config`
|
|
41
|
+
/// - Windows: `%APPDATA%`
|
|
38
42
|
config_dir :: (fn() -> Option(String))(
|
|
39
43
|
cond(
|
|
40
44
|
(platform == Platform.Windows) => env.get(`APPDATA`),
|
|
@@ -48,10 +52,11 @@ config_dir :: (fn() -> Option(String))(
|
|
|
48
52
|
)
|
|
49
53
|
);
|
|
50
54
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
/// Return the user-specific cache directory.
|
|
56
|
+
///
|
|
57
|
+
/// - Linux: `$XDG_CACHE_HOME` or `$HOME/.cache`
|
|
58
|
+
/// - macOS: `$HOME/Library/Caches`
|
|
59
|
+
/// - Windows: `%LOCALAPPDATA%`
|
|
55
60
|
cache_dir :: (fn() -> Option(String))(
|
|
56
61
|
cond(
|
|
57
62
|
(platform == Platform.Windows) => env.get(`LOCALAPPDATA`),
|
|
@@ -69,7 +74,7 @@ cache_dir :: (fn() -> Option(String))(
|
|
|
69
74
|
)
|
|
70
75
|
);
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
/// Return the system temporary directory.
|
|
73
78
|
temp_dir :: (fn() -> String)(
|
|
74
79
|
cond(
|
|
75
80
|
(platform == Platform.Windows) => match(env.get(`TEMP`),
|
package/std/os/signal.yo
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
//! High-level signal handling.
|
|
2
|
+
//!
|
|
3
|
+
//! Wraps `std/sys/signal` with a typed `Signal` enum.
|
|
4
|
+
//!
|
|
5
|
+
//! # Example
|
|
6
|
+
//!
|
|
7
|
+
//! ```rust
|
|
8
|
+
//! { on_signal, off_signal, Signal, SignalHandler } :: import "std/os/signal";
|
|
9
|
+
//!
|
|
10
|
+
//! handler :: (fn(data: *(u8)) -> unit)({ println("Caught SIGINT"); });
|
|
11
|
+
//! on_signal(.Interrupt, handler);
|
|
12
|
+
//! ```
|
|
10
13
|
|
|
11
14
|
{ IOError } :: import "../sys/errors";
|
|
12
15
|
{
|
|
@@ -19,15 +22,24 @@
|
|
|
19
22
|
// Signal enum
|
|
20
23
|
// ============================================================================
|
|
21
24
|
|
|
25
|
+
/// Portable signal identifiers.
|
|
22
26
|
Signal :: enum(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
/// SIGINT — interrupt from keyboard (Ctrl-C).
|
|
28
|
+
Interrupt,
|
|
29
|
+
/// SIGTERM — termination request.
|
|
30
|
+
Terminate,
|
|
31
|
+
/// SIGHUP — terminal hangup.
|
|
32
|
+
Hangup,
|
|
33
|
+
/// SIGUSR1 — user-defined signal 1.
|
|
34
|
+
User1,
|
|
35
|
+
/// SIGUSR2 — user-defined signal 2.
|
|
36
|
+
User2,
|
|
37
|
+
/// SIGPIPE — broken pipe.
|
|
38
|
+
Pipe,
|
|
39
|
+
/// SIGALRM — timer alarm.
|
|
40
|
+
Alarm,
|
|
41
|
+
/// SIGCHLD — child process status change.
|
|
42
|
+
Child
|
|
31
43
|
);
|
|
32
44
|
|
|
33
45
|
export Signal;
|
|
@@ -73,7 +85,7 @@ _signal_num :: (fn(sig: Signal) -> i32)(
|
|
|
73
85
|
// on_signal / off_signal
|
|
74
86
|
// ============================================================================
|
|
75
87
|
|
|
76
|
-
|
|
88
|
+
/// Register a handler for the given signal.
|
|
77
89
|
on_signal :: (fn(sig: Signal, handler: SignalHandler, using(exn : Exception)) -> unit)({
|
|
78
90
|
num := _signal_num(sig);
|
|
79
91
|
r := _on_signal(num, handler);
|
|
@@ -85,7 +97,7 @@ on_signal :: (fn(sig: Signal, handler: SignalHandler, using(exn : Exception)) ->
|
|
|
85
97
|
);
|
|
86
98
|
});
|
|
87
99
|
|
|
88
|
-
|
|
100
|
+
/// Remove the handler for the given signal.
|
|
89
101
|
off_signal :: (fn(sig: Signal, using(exn : Exception)) -> unit)({
|
|
90
102
|
num := _signal_num(sig);
|
|
91
103
|
r := _off_signal(num);
|