Skip to content

Commit caf1a58

Browse files
authored
feat: update axum to v0.8.1 (tuono-labs#595)
1 parent 059f3d6 commit caf1a58

File tree

11 files changed

+103
-20
lines changed

11 files changed

+103
-20
lines changed

crates/tuono/src/app.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ mod tests {
362362
("/about", "/about"),
363363
("/posts/index", "/posts"),
364364
("/posts/any-post", "/posts/any-post"),
365-
("/posts/[post]", "/posts/:post"),
365+
("/posts/[post]", "/posts/{post}"),
366366
];
367367

368368
results.into_iter().for_each(|(path, expected_path)| {

crates/tuono/src/route.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ impl AxumInfo {
4646
}
4747

4848
if route.is_dynamic {
49+
let dyn_re = Regex::new(r"\[(.*?)\]").expect("Failed to create dyn regex");
50+
let catch_all_re =
51+
Regex::new(r"\{\.\.\.(.*?)\}").expect("Failed to create catch all regex");
52+
53+
let dyn_result = dyn_re.replace_all(&axum_route, |caps: &regex::Captures| {
54+
format!("{{{}}}", &caps[1])
55+
});
56+
57+
let axum_route = catch_all_re
58+
.replace_all(&dyn_result, |caps: &regex::Captures| {
59+
format!("{{*{}}}", &caps[1])
60+
})
61+
.to_string();
62+
4963
return AxumInfo {
5064
module_import: module
5165
.as_str()
@@ -55,10 +69,7 @@ impl AxumInfo {
5569
.replace('[', "dyn_")
5670
.replace("...", "catch_all_")
5771
.replace(']', ""),
58-
axum_route: axum_route
59-
.replace("[...", "*")
60-
.replace('[', ":")
61-
.replace(']', ""),
72+
axum_route,
6273
};
6374
}
6475

@@ -296,7 +307,7 @@ mod tests {
296307

297308
let dyn_info = AxumInfo::new(&Route::new("/[posts]".to_string()));
298309

299-
assert_eq!(dyn_info.axum_route, "/:posts");
310+
assert_eq!(dyn_info.axum_route, "/{posts}");
300311
assert_eq!(dyn_info.module_import, "dyn_posts");
301312
}
302313

crates/tuono/tests/cli_build.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,19 @@ fn it_successfully_create_catch_all_routes() {
127127
assert!(temp_main_rs_content.contains("mod dyn_catch_all_all_routes;"));
128128

129129
assert!(temp_main_rs_content.contains(
130-
r#".route("/api/*all_apis", post(api_dyn_catch_all_all_apis::post_tuono_internal_api))"#
130+
r#".route("/api/{*all_apis}", post(api_dyn_catch_all_all_apis::post_tuono_internal_api))"#
131131
));
132132

133133
assert!(temp_main_rs_content.contains(
134-
r#".route("/*all_routes", get(dyn_catch_all_all_routes::tuono_internal_route))"#
134+
r#".route("/{*all_routes}", get(dyn_catch_all_all_routes::tuono_internal_route))"#
135135
));
136136

137137
assert!(temp_main_rs_content.contains(
138-
r#".route("/*all_routes", get(dyn_catch_all_all_routes::tuono_internal_route))"#
138+
r#".route("/{*all_routes}", get(dyn_catch_all_all_routes::tuono_internal_route))"#
139139
));
140140

141141
assert!(temp_main_rs_content.contains(
142-
r#".route("/__tuono/data/*all_routes", get(dyn_catch_all_all_routes::tuono_internal_api))"#
142+
r#".route("/__tuono/data/{*all_routes}", get(dyn_catch_all_all_routes::tuono_internal_api))"#
143143
));
144144
}
145145

crates/tuono_lib/Cargo.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ include = [
1818

1919
[dependencies]
2020
ssr_rs = "0.8.1"
21-
axum = {version = "0.7.5", features = ["json", "ws"]}
22-
axum-extra = {version = "0.9.6", features = ["cookie"]}
21+
axum = {version = "0.8.1", features = ["json", "ws"]}
22+
axum-extra = {version = "0.10.0", features = ["cookie"]}
2323
tokio = { version = "1.37.0", features = ["full"] }
2424
serde = { version = "1.0.202", features = ["derive"] }
2525
erased-serde = "0.4.5"
@@ -35,9 +35,9 @@ colored = "2.1.0"
3535
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.17.8"}
3636
tuono_internal = {path = "../tuono_internal", version = "0.17.8"}
3737
# Match the same version used by axum
38-
tokio-tungstenite = "0.24.0"
38+
tokio-tungstenite = "0.26.0"
3939
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
40-
tungstenite = "0.24.0"
40+
tungstenite = "0.26.0"
4141
http = "1.1.0"
4242
pin-project = "1.1.7"
4343
tower = "0.5.1"

crates/tuono_lib/src/server.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl Server {
6464
.to_owned()
6565
.layer(LoggerLayer::new())
6666
.route("/vite-server/", get(vite_websocket_proxy))
67-
.route("/vite-server/*path", get(vite_reverse_proxy))
67+
.route("/vite-server/{*path}", get(vite_reverse_proxy))
6868
.fallback_service(
6969
ServeDir::new(DEV_PUBLIC_DIR)
7070
.fallback(get(catch_all).layer(LoggerLayer::new())),

crates/tuono_lib/src/vite_websocket_proxy.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::config::GLOBAL_CONFIG;
2-
use axum::extract::ws::{self, WebSocket, WebSocketUpgrade};
2+
use axum::extract::ws::{self, Utf8Bytes as AxumUtf8Bytes, WebSocket, WebSocketUpgrade};
33
use axum::response::IntoResponse;
44
use futures_util::{SinkExt, StreamExt};
55
use tokio_tungstenite::connect_async;
@@ -64,7 +64,7 @@ async fn handle_socket(mut tuono_socket: WebSocket) {
6464
while let Some(msg) = tuono_receiver.next().await {
6565
if let Ok(msg) = msg {
6666
let msg_to_vite = match msg.clone() {
67-
ws::Message::Text(str) => Message::Text(str),
67+
ws::Message::Text(str) => Message::Text(str.to_string().into()),
6868
ws::Message::Pong(payload) => Message::Pong(payload),
6969
ws::Message::Ping(payload) => Message::Ping(payload),
7070
ws::Message::Binary(payload) => Message::Binary(payload),
@@ -91,7 +91,7 @@ async fn handle_socket(mut tuono_socket: WebSocket) {
9191
tokio::spawn(async move {
9292
while let Some(Ok(msg)) = vite_receiver.next().await {
9393
let msg_to_browser = match msg {
94-
Message::Text(str) => ws::Message::Text(str),
94+
Message::Text(str) => ws::Message::Text(AxumUtf8Bytes::from(str.to_string())),
9595
Message::Ping(payload) => ws::Message::Ping(payload),
9696
Message::Pong(payload) => ws::Message::Pong(payload),
9797
Message::Binary(payload) => ws::Message::Binary(payload),
@@ -100,7 +100,7 @@ async fn handle_socket(mut tuono_socket: WebSocket) {
100100
Message::Close(_) => ws::Message::Close(None),
101101
_ => {
102102
eprintln!("Unexpected message from the vite WebSocket to the browser: {msg:?}");
103-
ws::Message::Text("Unhandled".to_string())
103+
ws::Message::Text("Unhandled".to_string().into())
104104
}
105105
};
106106

crates/tuono_lib/tests/server_test.rs

+44
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,47 @@ async fn api_route_route() {
103103
"{\"data\":\"{}\",\"info\":{\"redirect_destination\":null}}"
104104
);
105105
}
106+
107+
#[tokio::test]
108+
#[serial]
109+
async fn it_reads_the_catch_all_path_parameter() {
110+
let app = MockTuonoServer::spawn().await;
111+
112+
let client = reqwest::Client::builder()
113+
.redirect(reqwest::redirect::Policy::none())
114+
.build()
115+
.unwrap();
116+
117+
let server_url = format!("http://{}:{}", &app.address, &app.port);
118+
119+
let response = client
120+
.get(format!("{server_url}/catch_all/url_parameter"))
121+
.send()
122+
.await
123+
.expect("Failed to execute request.");
124+
125+
assert!(response.status().is_success());
126+
assert_eq!(response.text().await.unwrap(), "url_parameter");
127+
}
128+
129+
#[tokio::test]
130+
#[serial]
131+
async fn it_reads_the_path_parameter() {
132+
let app = MockTuonoServer::spawn().await;
133+
134+
let client = reqwest::Client::builder()
135+
.redirect(reqwest::redirect::Policy::none())
136+
.build()
137+
.unwrap();
138+
139+
let server_url = format!("http://{}:{}", &app.address, &app.port);
140+
141+
let response = client
142+
.get(format!("{server_url}/dynamic/url_parameter"))
143+
.send()
144+
.await
145+
.expect("Failed to execute request.");
146+
147+
assert!(response.status().is_success());
148+
assert_eq!(response.text().await.unwrap(), "url_parameter");
149+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use tuono_lib::Request;
2+
3+
#[tuono_lib::api(GET)]
4+
async fn read_catch_all_parameter(req: Request) -> String {
5+
let param = req
6+
.params
7+
.get("catch_all")
8+
.expect("Failed to get the catch_all param");
9+
10+
param.to_string()
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use tuono_lib::Request;
2+
3+
#[tuono_lib::api(GET)]
4+
async fn read_dynamic_parameter(req: Request) -> String {
5+
let param = req
6+
.params
7+
.get("parameter")
8+
.expect("Failed to get the catch_all param");
9+
10+
param.to_string()
11+
}

crates/tuono_lib/tests/utils/mock_server.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use tempfile::{tempdir, TempDir};
77
use tuono_lib::axum::routing::get;
88
use tuono_lib::{axum::Router, tuono_internal_init_v8_platform, Mode, Server};
99

10+
use crate::utils::catch_all::get_tuono_internal_api as catch_all;
11+
use crate::utils::dynamic_parameter::get_tuono_internal_api as dynamic_parameter;
1012
use crate::utils::health_check::get_tuono_internal_api as health_check;
1113
use crate::utils::route as html_route;
1214
use crate::utils::route::tuono_internal_api as route_api;
@@ -76,7 +78,9 @@ impl MockTuonoServer {
7678
.route("/", get(html_route::tuono_internal_route))
7779
.route("/tuono/data", get(html_route::tuono_internal_api))
7880
.route("/health_check", get(health_check))
79-
.route("/route-api", get(route_api));
81+
.route("/route-api", get(route_api))
82+
.route("/catch_all/{*catch_all}", get(catch_all))
83+
.route("/dynamic/{parameter}", get(dynamic_parameter));
8084

8185
let server = Server::init(router, Mode::Prod).await;
8286

crates/tuono_lib/tests/utils/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
pub mod catch_all;
2+
pub mod dynamic_parameter;
13
pub mod health_check;
24
pub mod mock_server;
35
pub mod route;

0 commit comments

Comments
 (0)