Skip to content

Commit 227fdb5

Browse files
committed
refactor: replace Promise-based async handling with async/await syntax in server and main modules, enhancing error handling and code clarity
1 parent a4c25a2 commit 227fdb5

4 files changed

Lines changed: 123 additions & 166 deletions

File tree

moon.mod.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "oboard/mocket",
3-
"version": "0.2.1",
3+
"version": "0.2.2",
44
"deps": {
55
"oboard/mimetype": "0.1.4",
66
"yj-qin/regexp": "0.3.2",

src/lib/promise.mbt

Lines changed: 0 additions & 78 deletions
This file was deleted.

src/lib/server.mbt

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
///|
2+
type! IOError derive(Show)
3+
4+
///|
5+
type! NetworkError derive(Show)
6+
7+
///|
8+
type! ExecError derive(Show)
9+
10+
///|
11+
// fn run_async(f : async() -> Unit) -> Unit = "%async.run"
12+
13+
///|
14+
async fn suspend[T, E : Error](f : ((T) -> Unit, (E) -> Unit) -> Unit) -> T!E = "%async.suspend"
15+
116
///|
217
pub struct HeavenBinding {
318
mut listen : (String, (Json) -> Unit) -> Unit
@@ -298,20 +313,17 @@ pub fn end(self : HttpResponse, body : Json) -> Unit {
298313
])
299314
}
300315

301-
// pub fn readDir(callback : (Json) -> Unit, path : String) -> Unit {
302-
// (binding.call)("fs.readDirSync", String(path), callback)
303-
// }
304-
305316
///|
306-
pub fn readDir(path : String) -> Promise[Json] {
307-
Promise::new(fn(resolve : (Json) -> Unit, _reject : (Json) -> Unit) {
317+
pub async fn readDir(path : String) -> Json!Error {
318+
suspend!!(fn(resolve, _reject) {
308319
(binding.call)("fs.readDir", String(path), resolve)
309320
})
310321
}
311322

323+
// ///|
312324
///|
313-
pub fn readFile(path : String) -> Promise[Bytes] {
314-
Promise::new(fn(resolve, reject) {
325+
pub async fn readFile(path : String) -> Bytes!Error {
326+
suspend!!(fn(resolve, reject) {
315327
(binding.call)("fs.readFile", String(path), fn {
316328
Array(bytes) =>
317329
bytes.map(fn {
@@ -321,7 +333,17 @@ pub fn readFile(path : String) -> Promise[Bytes] {
321333
|> FixedArray::from_array
322334
|> Bytes::of
323335
|> resolve
324-
_ => reject(Bytes::new(0))
336+
_ => reject(IOError)
337+
})
338+
})
339+
}
340+
341+
///|
342+
pub async fn exec(cmd : String) -> String!Error {
343+
suspend!!(fn(resolve, reject) {
344+
(binding.call)("os.exec", String(cmd), fn {
345+
String(s) => resolve(s)
346+
_ => reject(ExecError)
325347
})
326348
})
327349
}
@@ -341,16 +363,6 @@ pub fn resource(self : HttpServer, from : String, to : String) -> Unit {
341363
}
342364
}
343365

344-
///|
345-
pub fn exec(cmd : String) -> Promise[String] {
346-
Promise::new(fn(resolve, reject) {
347-
(binding.call)("os.exec", String(cmd), fn {
348-
String(s) => resolve(s)
349-
_ => reject("")
350-
})
351-
})
352-
}
353-
354366
///|
355367
pub(all) enum FetchCredentials {
356368
Omit
@@ -375,15 +387,15 @@ struct FetchResponse {
375387
} derive(ToJson, Show, Eq)
376388

377389
///|
378-
pub fn fetch(
390+
pub async fn fetch(
379391
url : String,
380392
reqMethod? : String,
381393
body? : String,
382394
headers? : Map[String, String],
383395
credentials? : FetchCredentials,
384396
mode? : FetchMode
385-
) -> Promise[FetchResponse] {
386-
Promise::new(fn(resolve, reject) {
397+
) -> FetchResponse!NetworkError {
398+
suspend!!(fn(resolve, reject) {
387399
let options : Map[String, Json] = {}
388400
match reqMethod {
389401
Some(str) => options["method"] = String(str)
@@ -437,13 +449,7 @@ pub fn fetch(
437449
|> Map::from_array,
438450
data,
439451
})
440-
_ =>
441-
reject(FetchResponse::{
442-
status: 0,
443-
headers: {},
444-
statusText: "",
445-
data: "",
446-
})
452+
_ => reject(NetworkError)
447453
})
448454
})
449455
}

src/main/main.mbt

Lines changed: 87 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,105 @@
11
// Example usage of mocket package in MoonBit
22

3+
// `run_async` spawn a new coroutine and execute an async function in it
4+
///|
5+
fn run_async(f : async() -> Unit) -> Unit = "%async.run"
6+
7+
// `suspend` will suspend the execution of the current coroutine.
8+
// The suspension will be handled by a callback passed to `suspend`
9+
///|
10+
// async fn suspend[T, E : Error](
11+
// // `f` is a callback for handling suspension
12+
// // the first parameter of `f` is used to resume the execution of the coroutine normally
13+
// // the second parameter of `f` is used to cancel the execution of the current coroutine
14+
// // by throwing an error at suspension point
15+
// f : ((T) -> Unit, (E) -> Unit) -> Unit
16+
// ) -> T!E = "%async.suspend"
17+
18+
///|
319
fn main {
420
println("Starting server...")
521
let port = 4000
622
let server = @mocket.listen(get_context(), port)
723
listen_event("echo", fn(json) { println(json) })
8-
// readFile example
9-
// @mocket.readFile("./logo.jpg").finally(
10-
// fn(data : Bytes) { println(data.length()) },
11-
// )
12-
// html response example
13-
server.get(
14-
"/",
15-
fn(_req : @mocket.HttpRequest, _res : @mocket.HttpResponse) {
16-
@mocket.html("<h1>Hello, World!</h1>")
17-
},
18-
)
24+
25+
// 修改文件读取示例
26+
// try {
27+
// let data = @mocket.readFile!!("./logo.jpg")
28+
// println(data.length())
29+
// } catch {
30+
// err => println("Error reading file: \{err}")
31+
// }
32+
33+
server.get("/", fn(_req : @mocket.HttpRequest, _res : @mocket.HttpResponse) {
34+
@mocket.html("<h1>Hello, World!</h1>")
35+
})
1936
// string response example
20-
server.get(
21-
"/text",
22-
fn(_req : @mocket.HttpRequest, _res : @mocket.HttpResponse) {
23-
String("<h1>Hello, World!</h1>")
24-
},
25-
)
37+
server.get("/text", fn(
38+
_req : @mocket.HttpRequest,
39+
_res : @mocket.HttpResponse
40+
) {
41+
String("<h1>Hello, World!</h1>")
42+
})
2643
// json data example
27-
server.get(
28-
"/data",
29-
fn(_req : @mocket.HttpRequest, _res : @mocket.HttpResponse) {
30-
{ "name": "John Doe", "age": 30, "city": "New York" }
31-
},
32-
)
44+
server.get("/data", fn(
45+
_req : @mocket.HttpRequest,
46+
_res : @mocket.HttpResponse
47+
) {
48+
{ "name": "John Doe", "age": 30, "city": "New York" }
49+
})
3350
// echo server example
34-
server.post(
35-
"/echo",
36-
fn(req : @mocket.HttpRequest, _res : @mocket.HttpResponse) {
37-
match req.body {
38-
Some(data) => data
39-
_ => String("No data received")
40-
}
41-
},
42-
)
51+
server.post("/echo", fn(
52+
req : @mocket.HttpRequest,
53+
_res : @mocket.HttpResponse
54+
) {
55+
match req.body {
56+
Some(data) => data
57+
_ => String("No data received")
58+
}
59+
})
4360
// file serving example
44-
server.get(
45-
"/image",
46-
fn(_req : @mocket.HttpRequest, _res : @mocket.HttpResponse) {
47-
@mocket.file("logo.jpg")
48-
},
49-
)
61+
server.get("/image", fn(
62+
_req : @mocket.HttpRequest,
63+
_res : @mocket.HttpResponse
64+
) {
65+
@mocket.file("logo.jpg")
66+
})
5067

5168
// buffer serving example
52-
server.get(
53-
"/buffer",
54-
fn(_req : @mocket.HttpRequest, _res : @mocket.HttpResponse) {
55-
@mocket.buffer(
56-
[
57-
72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 32, 84, 104, 105,
58-
115, 32, 105, 115, 32, 97, 32, 116, 101, 115, 116, 32, 115, 116, 114, 105,
59-
110, 103, 32, 102, 111, 114, 32, 116, 101, 115, 116, 105, 110, 103, 32,
60-
112, 117, 114, 112, 111, 115, 101,
61-
].map(fn(x) { x.to_byte() })
62-
|> Bytes::from_array,
63-
)
64-
},
65-
)
69+
server.get("/buffer", fn(
70+
_req : @mocket.HttpRequest,
71+
_res : @mocket.HttpResponse
72+
) {
73+
@mocket.buffer(
74+
[
75+
72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 32, 84, 104, 105,
76+
115, 32, 105, 115, 32, 97, 32, 116, 101, 115, 116, 32, 115, 116, 114, 105,
77+
110, 103, 32, 102, 111, 114, 32, 116, 101, 115, 116, 105, 110, 103, 32, 112,
78+
117, 114, 112, 111, 115, 101,
79+
].map(fn(x) { x.to_byte() })
80+
|> Bytes::from_array,
81+
)
82+
})
6683

6784
// static file serving example
6885
// Example: http://localhost:4000/static/logo.jpg => ./logo.jpg
6986
server.resource("/static/", "./")
70-
71-
// exec example
72-
@mocket.exec("ls").finally(println)
73-
74-
// fetch example
75-
@mocket.fetch("https://api64.ipify.org/").finally(println)
87+
run_async(fn() {
88+
// 修改exec示例
89+
try {
90+
let result = @mocket.exec!!("ls")
91+
println(result)
92+
} catch {
93+
err => println("Error executing command: \{err}")
94+
}
95+
})
96+
run_async(fn() {
97+
// 修改fetch示例
98+
try {
99+
let response = @mocket.fetch!!("https://api64.ipify.org/")
100+
println(response)
101+
} catch {
102+
err => println("Error fetching data: \{err}")
103+
}
104+
})
76105
}

0 commit comments

Comments
 (0)