@shd101wyy/yo 0.0.25 → 0.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/out/cjs/index.cjs +568 -563
- package/out/cjs/yo-cli.cjs +569 -564
- package/out/esm/index.mjs +487 -482
- package/out/types/src/codegen/async/state-machine.d.ts +1 -1
- package/out/types/src/codegen/exprs/await.d.ts +1 -0
- package/out/types/src/codegen/exprs/downcast.d.ts +3 -0
- package/out/types/src/codegen/exprs/return.d.ts +1 -0
- package/out/types/src/codegen/exprs/typeid.d.ts +3 -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/types/dyn.d.ts +1 -0
- package/out/types/src/codegen/types/generation.d.ts +1 -1
- package/out/types/src/codegen/utils/index.d.ts +1 -0
- package/out/types/src/evaluator/async/await-analysis.d.ts +1 -0
- package/out/types/src/evaluator/builtins/downcast.d.ts +8 -0
- package/out/types/src/evaluator/builtins/rc-fns.d.ts +5 -0
- package/out/types/src/evaluator/builtins/typeid.d.ts +8 -0
- package/out/types/src/evaluator/context.d.ts +2 -0
- package/out/types/src/expr.d.ts +3 -0
- package/out/types/src/function-value.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +3 -1
- package/out/types/src/types/definitions.d.ts +3 -1
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/crypto/random.yo +25 -13
- 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/error.yo +39 -23
- package/std/fs/dir.yo +106 -103
- package/std/fs/file.yo +122 -158
- package/std/fs/metadata.yo +23 -22
- package/std/fs/temp.yo +41 -47
- 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/signal.yo +13 -8
- package/std/prelude.yo +21 -16
- package/std/sys/errors.yo +45 -33
- package/std/url/url.yo +19 -32
- package/out/types/src/codegen/effects/effect-state-machine.d.ts +0 -34
package/std/fs/temp.yo
CHANGED
|
@@ -7,14 +7,15 @@
|
|
|
7
7
|
// { TempDir } :: import "std/fs/temp";
|
|
8
8
|
//
|
|
9
9
|
// main :: (fn(using(io : IO)) -> unit)({
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// );
|
|
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
|
+
// dir := io.await(TempDir.new());
|
|
17
|
+
// println(dir.path());
|
|
18
|
+
// io.await(dir.remove());
|
|
18
19
|
// });
|
|
19
20
|
|
|
20
21
|
{ GlobalAllocator } :: import "../allocator";
|
|
@@ -23,6 +24,7 @@ open import "../string";
|
|
|
23
24
|
open import "../fmt";
|
|
24
25
|
{ Path } :: import "../path";
|
|
25
26
|
{ IOError } :: import "../sys/errors";
|
|
27
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
26
28
|
_file_mod :: import "./file";
|
|
27
29
|
_dir_mod :: import "./dir";
|
|
28
30
|
IO_temp :: import "../sys/temp";
|
|
@@ -61,8 +63,8 @@ TempDir :: object(
|
|
|
61
63
|
|
|
62
64
|
impl(TempDir,
|
|
63
65
|
// Create a temporary directory in the given parent directory.
|
|
64
|
-
new_in : (fn(parent: Path, using(io : IO)) -> Impl(Future(
|
|
65
|
-
io.async((using(io
|
|
66
|
+
new_in : (fn(parent: Path, using(io : IO)) -> Impl(Future(TempDir, IO, Exception)))(
|
|
67
|
+
io.async((using(io, exn)) => {
|
|
66
68
|
// Build template: parent/yo_tmp_XXXXXX
|
|
67
69
|
template_path := parent.join(Path.new(`yo_tmp_XXXXXX`));
|
|
68
70
|
template_str := template_path.to_string();
|
|
@@ -76,22 +78,19 @@ impl(TempDir,
|
|
|
76
78
|
cond(
|
|
77
79
|
(result < i32(0)) => {
|
|
78
80
|
free(.Some(*(void)(buf)));
|
|
79
|
-
(
|
|
80
|
-
return ret;
|
|
81
|
+
exn.throw(dyn IOError.from_errno((i32(0) - result)));
|
|
81
82
|
},
|
|
82
|
-
true =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
)
|
|
83
|
+
true => ()
|
|
84
|
+
);
|
|
85
|
+
path_str := String.from_cstr(buf).unwrap();
|
|
86
|
+
free(.Some(*(void)(buf)));
|
|
87
|
+
TempDir(_path: Path.new(path_str), _removed: false)
|
|
89
88
|
})
|
|
90
89
|
),
|
|
91
90
|
|
|
92
91
|
// Create a temporary directory in the system temp dir.
|
|
93
|
-
new : (fn(using(io : IO)) -> Impl(Future(
|
|
94
|
-
TempDir.new_in(Path.new(_default_tmp_dir())
|
|
92
|
+
new : (fn(using(io : IO)) -> Impl(Future(TempDir, IO, Exception)))(
|
|
93
|
+
TempDir.new_in(Path.new(_default_tmp_dir()))
|
|
95
94
|
),
|
|
96
95
|
|
|
97
96
|
// Get the path of the temporary directory.
|
|
@@ -100,15 +99,14 @@ impl(TempDir,
|
|
|
100
99
|
),
|
|
101
100
|
|
|
102
101
|
// Remove the temporary directory.
|
|
103
|
-
remove : (fn(self: Self, using(io : IO)) -> Impl(Future(
|
|
102
|
+
remove : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
104
103
|
self_path := self._path;
|
|
105
|
-
io.async((using(io
|
|
104
|
+
io.async((using(io, exn)) =>
|
|
106
105
|
cond(
|
|
107
|
-
self._removed =>
|
|
106
|
+
self._removed => (),
|
|
108
107
|
true => {
|
|
109
|
-
|
|
108
|
+
io.await(_dir_mod.remove_dir(self_path));
|
|
110
109
|
self._removed = true;
|
|
111
|
-
return result;
|
|
112
110
|
}
|
|
113
111
|
)
|
|
114
112
|
)
|
|
@@ -129,8 +127,8 @@ TempFile :: object(
|
|
|
129
127
|
|
|
130
128
|
impl(TempFile,
|
|
131
129
|
// Create a temporary file in the given parent directory.
|
|
132
|
-
new_in : (fn(parent: Path, using(io : IO)) -> Impl(Future(
|
|
133
|
-
io.async((using(io
|
|
130
|
+
new_in : (fn(parent: Path, using(io : IO)) -> Impl(Future(TempFile, IO, Exception)))(
|
|
131
|
+
io.async((using(io, exn)) => {
|
|
134
132
|
// Build template: parent/yo_tmp_XXXXXX
|
|
135
133
|
template_path := parent.join(Path.new(`yo_tmp_XXXXXX`));
|
|
136
134
|
template_str := template_path.to_string();
|
|
@@ -143,24 +141,21 @@ impl(TempFile,
|
|
|
143
141
|
cond(
|
|
144
142
|
(fd < i32(0)) => {
|
|
145
143
|
free(.Some(*(void)(buf)));
|
|
146
|
-
(
|
|
147
|
-
return ret;
|
|
144
|
+
exn.throw(dyn IOError.from_errno((i32(0) - fd)));
|
|
148
145
|
},
|
|
149
|
-
true =>
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
)
|
|
146
|
+
true => ()
|
|
147
|
+
);
|
|
148
|
+
path_str := String.from_cstr(buf).unwrap();
|
|
149
|
+
free(.Some(*(void)(buf)));
|
|
150
|
+
path := Path.new(path_str);
|
|
151
|
+
file := _file_mod.File(_fd: fd, _path: path, _is_closed: false);
|
|
152
|
+
TempFile(_file: file, _path: path, _removed: false)
|
|
158
153
|
})
|
|
159
154
|
),
|
|
160
155
|
|
|
161
156
|
// Create a temporary file in the system temp dir.
|
|
162
|
-
new : (fn(using(io : IO)) -> Impl(Future(
|
|
163
|
-
TempFile.new_in(Path.new(_default_tmp_dir())
|
|
157
|
+
new : (fn(using(io : IO)) -> Impl(Future(TempFile, IO, Exception)))(
|
|
158
|
+
TempFile.new_in(Path.new(_default_tmp_dir()))
|
|
164
159
|
),
|
|
165
160
|
|
|
166
161
|
// Get the underlying File object.
|
|
@@ -174,17 +169,16 @@ impl(TempFile,
|
|
|
174
169
|
),
|
|
175
170
|
|
|
176
171
|
// Remove the temporary file.
|
|
177
|
-
remove : (fn(self: Self, using(io : IO)) -> Impl(Future(
|
|
172
|
+
remove : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
178
173
|
self_file := self._file;
|
|
179
174
|
self_path := self._path;
|
|
180
|
-
io.async((using(io
|
|
175
|
+
io.async((using(io, exn)) =>
|
|
181
176
|
cond(
|
|
182
|
-
self._removed =>
|
|
177
|
+
self._removed => (),
|
|
183
178
|
true => {
|
|
184
|
-
io.await(self_file.close(
|
|
185
|
-
|
|
179
|
+
io.await(self_file.close());
|
|
180
|
+
io.await(_dir_mod.remove_file(self_path));
|
|
186
181
|
self._removed = true;
|
|
187
|
-
return result;
|
|
188
182
|
}
|
|
189
183
|
)
|
|
190
184
|
)
|
package/std/fs/walker.yo
CHANGED
|
@@ -6,24 +6,26 @@
|
|
|
6
6
|
// { walk, WalkEntry } :: import "std/fs/walker";
|
|
7
7
|
//
|
|
8
8
|
// main :: (fn(using(io : IO)) -> unit)({
|
|
9
|
+
// given(exn) : Exception = {
|
|
10
|
+
// throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
11
|
+
// { println(error.to_string()); exit(i32(1)); }
|
|
12
|
+
// )
|
|
13
|
+
// };
|
|
14
|
+
//
|
|
9
15
|
// entries := io.await(walk(`/tmp`));
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// i = (i + usize(1));
|
|
17
|
-
// };
|
|
18
|
-
// },
|
|
19
|
-
// .Err(e) => println(e.to_string())
|
|
20
|
-
// );
|
|
16
|
+
// i := usize(0);
|
|
17
|
+
// while runtime((i < entries.len())), {
|
|
18
|
+
// e := entries.get(i).unwrap();
|
|
19
|
+
// println(e.path);
|
|
20
|
+
// i = (i + usize(1));
|
|
21
|
+
// };
|
|
21
22
|
// });
|
|
22
23
|
|
|
23
24
|
{ ArrayList } :: import "../collections/array_list";
|
|
24
25
|
open import "../string";
|
|
25
26
|
{ Path } :: import "../path";
|
|
26
27
|
{ IOError } :: import "../sys/errors";
|
|
28
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
27
29
|
{ FileType } :: import "./dir";
|
|
28
30
|
{ DirEntry } :: import "./dir";
|
|
29
31
|
_dir :: import "./dir";
|
|
@@ -79,9 +81,9 @@ _join_path :: (fn(base: String, name: String) -> String)(
|
|
|
79
81
|
// ============================================================================
|
|
80
82
|
|
|
81
83
|
// Walk a directory tree with custom options.
|
|
82
|
-
walk_with :: (fn(root: Path, options: WalkOptions, using(io : IO)) -> Impl(Future(
|
|
84
|
+
walk_with :: (fn(root: Path, options: WalkOptions, using(io : IO)) -> Impl(Future(ArrayList(WalkEntry), IO, Exception)))({
|
|
83
85
|
root_s := root.to_string();
|
|
84
|
-
io.async((using(io
|
|
86
|
+
io.async((using(io, exn)) => {
|
|
85
87
|
results := ArrayList(WalkEntry).new();
|
|
86
88
|
// Stack of (path, depth) pairs to process
|
|
87
89
|
stack := ArrayList(struct(path: String, depth: u32)).new();
|
|
@@ -100,67 +102,58 @@ walk_with :: (fn(root: Path, options: WalkOptions, using(io : IO)) -> Impl(Futur
|
|
|
100
102
|
|
|
101
103
|
cond(
|
|
102
104
|
should_continue => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
.
|
|
112
|
-
cond(
|
|
113
|
-
options.include_dirs => {
|
|
114
|
-
results.push(WalkEntry(
|
|
115
|
-
path: Path.new(entry_path),
|
|
116
|
-
name: entry.name,
|
|
117
|
-
depth: cur_depth,
|
|
118
|
-
file_type: .Directory
|
|
119
|
-
));
|
|
120
|
-
},
|
|
121
|
-
true => ()
|
|
122
|
-
);
|
|
123
|
-
// Push subdirectory for processing
|
|
124
|
-
stack.push({ path: entry_path, depth: (cur_depth + u32(1)) });
|
|
125
|
-
},
|
|
126
|
-
_ => {
|
|
105
|
+
entries := io.await(_dir.read_dir(Path.new(cur_path)));
|
|
106
|
+
i := usize(0);
|
|
107
|
+
while runtime((i < entries.len())), {
|
|
108
|
+
entry := entries.get(i).unwrap();
|
|
109
|
+
entry_path := _join_path(cur_path, entry.name);
|
|
110
|
+
match(entry.file_type,
|
|
111
|
+
.Directory => {
|
|
112
|
+
cond(
|
|
113
|
+
options.include_dirs => {
|
|
127
114
|
results.push(WalkEntry(
|
|
128
115
|
path: Path.new(entry_path),
|
|
129
116
|
name: entry.name,
|
|
130
117
|
depth: cur_depth,
|
|
131
|
-
file_type:
|
|
118
|
+
file_type: .Directory
|
|
132
119
|
));
|
|
133
|
-
}
|
|
120
|
+
},
|
|
121
|
+
true => ()
|
|
134
122
|
);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
123
|
+
// Push subdirectory for processing
|
|
124
|
+
stack.push({ path: entry_path, depth: (cur_depth + u32(1)) });
|
|
125
|
+
},
|
|
126
|
+
_ => {
|
|
127
|
+
results.push(WalkEntry(
|
|
128
|
+
path: Path.new(entry_path),
|
|
129
|
+
name: entry.name,
|
|
130
|
+
depth: cur_depth,
|
|
131
|
+
file_type: entry.file_type
|
|
132
|
+
));
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
i = (i + usize(1));
|
|
136
|
+
};
|
|
143
137
|
},
|
|
144
138
|
true => ()
|
|
145
139
|
);
|
|
146
140
|
};
|
|
147
141
|
|
|
148
|
-
|
|
149
|
-
return ret;
|
|
142
|
+
results
|
|
150
143
|
})
|
|
151
144
|
});
|
|
152
145
|
|
|
153
|
-
walk_with_cstr :: (fn(root: *(u8), options: WalkOptions, using(io : IO)) -> Impl(Future(
|
|
154
|
-
walk_with(Path.from_cstr(root), options
|
|
146
|
+
walk_with_cstr :: (fn(root: *(u8), options: WalkOptions, using(io : IO)) -> Impl(Future(ArrayList(WalkEntry), IO, Exception)))(
|
|
147
|
+
walk_with(Path.from_cstr(root), options)
|
|
155
148
|
);
|
|
156
149
|
|
|
157
150
|
// Walk a directory tree with default options.
|
|
158
|
-
walk :: (fn(root: Path, using(io : IO)) -> Impl(Future(
|
|
159
|
-
walk_with(root, WalkOptions.defaults()
|
|
151
|
+
walk :: (fn(root: Path, using(io : IO)) -> Impl(Future(ArrayList(WalkEntry), IO, Exception)))
|
|
152
|
+
walk_with(root, WalkOptions.defaults())
|
|
160
153
|
;
|
|
161
154
|
|
|
162
|
-
walk_cstr :: (fn(root: *(u8), using(io : IO)) -> Impl(Future(
|
|
163
|
-
walk(Path.from_cstr(root)
|
|
155
|
+
walk_cstr :: (fn(root: *(u8), using(io : IO)) -> Impl(Future(ArrayList(WalkEntry), IO, Exception)))
|
|
156
|
+
walk(Path.from_cstr(root))
|
|
164
157
|
;
|
|
165
158
|
|
|
166
159
|
export walk, walk_cstr, walk_with, walk_with_cstr;
|
package/std/net/addr.yo
CHANGED
|
@@ -14,6 +14,7 @@ open import "../string";
|
|
|
14
14
|
{ snprintf } :: import "../libc/stdio";
|
|
15
15
|
{ GlobalAllocator } :: import "../allocator";
|
|
16
16
|
{ malloc, free } :: GlobalAllocator;
|
|
17
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
17
18
|
|
|
18
19
|
// ============================================================================
|
|
19
20
|
// IpAddr
|
|
@@ -32,7 +33,7 @@ IpAddr :: enum(
|
|
|
32
33
|
impl(IpAddr,
|
|
33
34
|
// Parse an IPv4 address from a String like "127.0.0.1".
|
|
34
35
|
// Only supports IPv4 dotted-decimal notation.
|
|
35
|
-
parse_v4 : (fn(s: String) ->
|
|
36
|
+
parse_v4 : (fn(s: String, using(exn : Exception)) -> IpAddr)({
|
|
36
37
|
bytes := s.as_bytes();
|
|
37
38
|
parts := Array(u8, usize(4)).fill(u8(0));
|
|
38
39
|
part_idx := usize(0);
|
|
@@ -45,13 +46,13 @@ impl(IpAddr,
|
|
|
45
46
|
// '.' separator
|
|
46
47
|
cond(
|
|
47
48
|
(part_idx >= usize(3)) => {
|
|
48
|
-
|
|
49
|
+
exn.throw(dyn NetError.Other(String.from("invalid IPv4 address")));
|
|
49
50
|
},
|
|
50
51
|
true => ()
|
|
51
52
|
);
|
|
52
53
|
cond(
|
|
53
54
|
(val > u32(255)) => {
|
|
54
|
-
|
|
55
|
+
exn.throw(dyn NetError.Other(String.from("IPv4 octet out of range")));
|
|
55
56
|
},
|
|
56
57
|
true => ()
|
|
57
58
|
);
|
|
@@ -64,25 +65,25 @@ impl(IpAddr,
|
|
|
64
65
|
val = ((val * u32(10)) + u32((ch - _ASCII_ZERO)));
|
|
65
66
|
},
|
|
66
67
|
true => {
|
|
67
|
-
|
|
68
|
+
exn.throw(dyn NetError.Other(String.from("invalid character in IPv4 address")));
|
|
68
69
|
}
|
|
69
70
|
);
|
|
70
71
|
i = (i + usize(1));
|
|
71
72
|
};
|
|
72
73
|
cond(
|
|
73
74
|
(part_idx != usize(3)) => {
|
|
74
|
-
|
|
75
|
+
exn.throw(dyn NetError.Other(String.from("invalid IPv4 address")));
|
|
75
76
|
},
|
|
76
77
|
true => ()
|
|
77
78
|
);
|
|
78
79
|
cond(
|
|
79
80
|
(val > u32(255)) => {
|
|
80
|
-
|
|
81
|
+
exn.throw(dyn NetError.Other(String.from("IPv4 octet out of range")));
|
|
81
82
|
},
|
|
82
83
|
true => ()
|
|
83
84
|
);
|
|
84
85
|
parts(usize(3)) = u8(val);
|
|
85
|
-
|
|
86
|
+
.V4(parts(usize(0)), parts(usize(1)), parts(usize(2)), parts(usize(3)))
|
|
86
87
|
}),
|
|
87
88
|
|
|
88
89
|
// IPv4 loopback address (127.0.0.1).
|
package/std/net/dns.yo
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
// std/net/dns.yo - High-level DNS resolution
|
|
2
2
|
//
|
|
3
3
|
// Wraps std/sys/dns with typed DNS lookup functions.
|
|
4
|
+
// Uses the Exception effect for error handling.
|
|
4
5
|
//
|
|
5
6
|
// Example:
|
|
6
7
|
// { lookup_host } :: import "std/net/dns";
|
|
7
8
|
// { IpAddr } :: import "std/net/addr";
|
|
9
|
+
// { Exception } :: import "std/error";
|
|
8
10
|
//
|
|
9
11
|
// main :: (fn(using(io : IO)) -> unit)({
|
|
12
|
+
// given(exn) := Exception(throw : ((err) -> {
|
|
13
|
+
// println(err.message());
|
|
14
|
+
// escape ();
|
|
15
|
+
// }));
|
|
10
16
|
// addrs := io.await(lookup_host(`localhost`));
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// i = (i + usize(1));
|
|
17
|
-
// };
|
|
18
|
-
// },
|
|
19
|
-
// .Err(e) => println(e.to_string())
|
|
20
|
-
// );
|
|
17
|
+
// i := usize(0);
|
|
18
|
+
// while runtime((i < addrs.len())), {
|
|
19
|
+
// println(addrs.get(i).unwrap().to_string());
|
|
20
|
+
// i = (i + usize(1));
|
|
21
|
+
// };
|
|
21
22
|
// });
|
|
22
23
|
|
|
23
24
|
{ GlobalAllocator } :: import "../allocator";
|
|
@@ -27,6 +28,7 @@ open import "../string";
|
|
|
27
28
|
open import "../fmt";
|
|
28
29
|
{ NetError } :: import "./errors";
|
|
29
30
|
{ IpAddr, SocketAddr } :: import "./addr";
|
|
31
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
30
32
|
IO_dns :: import "../sys/dns";
|
|
31
33
|
{ AF_INET, AF_INET6 } :: import "../sys/socket";
|
|
32
34
|
|
|
@@ -35,8 +37,8 @@ IO_dns :: import "../sys/dns";
|
|
|
35
37
|
// ============================================================================
|
|
36
38
|
|
|
37
39
|
// Resolve a hostname to a list of IP addresses.
|
|
38
|
-
lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(
|
|
39
|
-
io.async((using(io : IO)) => {
|
|
40
|
+
lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(ArrayList(IpAddr), IO, Exception)))(
|
|
41
|
+
io.async((using(io : IO, exn : Exception)) => {
|
|
40
42
|
host_cstr_bytes := host.to_cstr();
|
|
41
43
|
host_cstr := host_cstr_bytes.ptr().unwrap();
|
|
42
44
|
result_ptr := IO_dns.alloc_result();
|
|
@@ -44,8 +46,7 @@ lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(Result(ArrayList
|
|
|
44
46
|
cond(
|
|
45
47
|
(ret != i32(0)) => {
|
|
46
48
|
IO_dns.free_result(result_ptr);
|
|
47
|
-
(
|
|
48
|
-
return err_ret;
|
|
49
|
+
exn.throw(dyn NetError.DNSFailed(host));
|
|
49
50
|
},
|
|
50
51
|
true => ()
|
|
51
52
|
);
|
|
@@ -79,29 +80,22 @@ lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(Result(ArrayList
|
|
|
79
80
|
.None => ()
|
|
80
81
|
);
|
|
81
82
|
IO_dns.free_result(result_ptr);
|
|
82
|
-
|
|
83
|
-
return ok_ret;
|
|
83
|
+
return addrs;
|
|
84
84
|
})
|
|
85
85
|
);
|
|
86
86
|
|
|
87
87
|
// Resolve a hostname and port to a list of socket addresses.
|
|
88
|
-
resolve :: (fn(host: String, port: u16, using(io : IO)) -> Impl(Future(
|
|
89
|
-
io.async((using(io : IO)) => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
};
|
|
100
|
-
.Ok(result)
|
|
101
|
-
},
|
|
102
|
-
.Err(e) => .Err(e)
|
|
103
|
-
);
|
|
104
|
-
return ret;
|
|
88
|
+
resolve :: (fn(host: String, port: u16, using(io : IO)) -> Impl(Future(ArrayList(SocketAddr), IO, Exception)))(
|
|
89
|
+
io.async((using(io : IO, exn : Exception)) => {
|
|
90
|
+
addrs := io.await(lookup_host(host, using(io)));
|
|
91
|
+
result := ArrayList(SocketAddr).new();
|
|
92
|
+
i := usize(0);
|
|
93
|
+
while runtime((i < addrs.len())), {
|
|
94
|
+
ip := addrs.get(i).unwrap();
|
|
95
|
+
result.push(SocketAddr.new(ip, port));
|
|
96
|
+
i = (i + usize(1));
|
|
97
|
+
};
|
|
98
|
+
return result;
|
|
105
99
|
})
|
|
106
100
|
);
|
|
107
101
|
|
package/std/net/errors.yo
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
open import "../string";
|
|
9
9
|
{ IOError } :: import "../sys/errors";
|
|
10
10
|
{ ToString } :: import "../fmt";
|
|
11
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
11
12
|
|
|
12
13
|
// ============================================================================
|
|
13
14
|
// NetError
|
|
@@ -41,14 +42,6 @@ impl(NetError,
|
|
|
41
42
|
.NetworkUnreachable => .NetworkUnreachable,
|
|
42
43
|
_ => .IO(err)
|
|
43
44
|
)
|
|
44
|
-
),
|
|
45
|
-
|
|
46
|
-
// Convert a raw result (positive = ok, negative = -errno) to Result.
|
|
47
|
-
from_result : (fn(result: i32) -> Result(i32, Self))(
|
|
48
|
-
cond(
|
|
49
|
-
(result >= i32(0)) => .Ok(result),
|
|
50
|
-
true => .Err(Self.from_io(IOError.from_errno((i32(0) - result))))
|
|
51
|
-
)
|
|
52
45
|
)
|
|
53
46
|
);
|
|
54
47
|
|
|
@@ -71,4 +64,16 @@ impl(NetError, ToString(
|
|
|
71
64
|
})
|
|
72
65
|
));
|
|
73
66
|
|
|
67
|
+
impl(NetError, Error());
|
|
68
|
+
|
|
69
|
+
impl(NetError,
|
|
70
|
+
// Check a raw result (positive = ok, negative = -errno) and throw on error.
|
|
71
|
+
check : (fn(result: i32, using(exn : Exception)) -> i32)(
|
|
72
|
+
cond(
|
|
73
|
+
(result >= i32(0)) => result,
|
|
74
|
+
true => exn.throw(dyn Self.from_io(IOError.from_errno((i32(0) - result))))
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
|
|
74
79
|
export NetError;
|