Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 4a7068d

Browse files
valkumdjc
authored andcommitted
exchange hyper features From<Template> for hyper::Body with TryFrom
The previous implementation hid the error returned by render, which made it impossible for callers to react to rendering errors. While having a simple way to call into would be nice, there is not way to have both implementations without adding any manual specialization. Thus, the From impl is replaced by the TryFrom impl.
1 parent c9613ff commit 4a7068d

File tree

2 files changed

+16
-29
lines changed

2 files changed

+16
-29
lines changed

askama_derive/src/generator.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -450,24 +450,22 @@ impl<'a> Generator<'a> {
450450
buf.writeln("}")?;
451451
buf.writeln("}")?;
452452

453-
// From<Template> for hyper::Body
453+
// TryFrom<Template> for hyper::Body
454454
buf.writeln(&format!(
455455
"{} {{",
456456
quote!(
457-
impl #impl_generics ::core::convert::From<&#ident #orig_ty_generics>
457+
impl #impl_generics ::core::convert::TryFrom<&#ident #orig_ty_generics>
458458
for ::askama_hyper::hyper::Body
459459
#where_clause
460460
)
461461
))?;
462+
buf.writeln("type Error = ::askama::Error;")?;
462463
buf.writeln("#[inline]")?;
463464
buf.writeln(&format!(
464465
"{} {{",
465-
quote!(fn from(value: &#ident #orig_ty_generics) -> Self)
466+
quote!(fn try_from(value: &#ident #orig_ty_generics) -> Result<Self, Self::Error>)
466467
))?;
467-
buf.writeln(
468-
"::askama::Template::render(value).ok().map(Into::into)\
469-
.unwrap_or_else(|| ::askama_hyper::hyper::Body::empty())",
470-
)?;
468+
buf.writeln("::askama::Template::render(value).map(Into::into)")?;
471469
buf.writeln("}")?;
472470
buf.writeln("}")
473471
}

askama_hyper/tests/basic.rs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ async fn hello_handler(req: Request<Body>) -> Result<Response<Body>, Infallible>
2222
Ok(template.into())
2323
}
2424

25-
async fn body_handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
25+
async fn try_body_handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
2626
let name = req.param("name").unwrap();
2727
let template = &HelloTemplate { name: &name };
28-
Ok(Builder::new().body(template.into()).unwrap())
28+
Ok(Builder::new().body(template.try_into().unwrap()).unwrap())
2929
}
3030

3131
fn router() -> Router<Body, Infallible> {
3232
Router::builder()
3333
.get("/hello/:name", hello_handler)
34-
.get("/body/:name", body_handler)
34+
.get("/try_body/:name", try_body_handler)
3535
.build()
3636
.unwrap()
3737
}
@@ -43,15 +43,12 @@ async fn test_hyper() {
4343
let server = Server::bind(&addr).serve(service);
4444
let local_addr = server.local_addr();
4545

46-
let (tx1, rx1) = tokio::sync::oneshot::channel::<()>();
47-
let (tx2, rx2) = tokio::sync::oneshot::channel::<()>();
46+
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel::<()>();
4847
let serve = async move {
49-
let server = server.with_graceful_shutdown(async {
50-
rx1.await.expect("Could not await signal to stop");
51-
rx2.await.expect("Could not await signal to stop");
52-
});
48+
let server = server.with_graceful_shutdown(async { while rx.recv().await.is_some() {} });
5349
server.await.expect("Could not serve");
5450
};
51+
let hello_tx = tx.clone();
5552
let hello_query = async move {
5653
let uri = format!("http://{local_addr}/hello/world")
5754
.parse()
@@ -73,32 +70,24 @@ async fn test_hyper() {
7370
let body = std::str::from_utf8(&body).expect("Body was not UTF-8");
7471
assert_eq!(body, "Hello, world!");
7572

76-
tx1.send(()).unwrap();
73+
hello_tx.send(()).unwrap();
7774
};
7875

79-
let body_query = async move {
80-
let uri = format!("http://{local_addr}/hello/world")
76+
let try_body_query = async move {
77+
let uri = format!("http://{local_addr}/try_body/world")
8178
.parse()
8279
.expect("Could not format URI");
8380
let client = Client::new();
8481

8582
let res = client.get(uri).await.expect("Could not query client");
8683
assert_eq!(res.status(), hyper::StatusCode::OK);
8784

88-
let content_type = res
89-
.headers()
90-
.get("content-type")
91-
.expect("Response did not contain content-type header")
92-
.to_str()
93-
.expect("Content-type was not a UTF-8 string");
94-
assert_eq!(content_type, mime::TEXT_HTML_UTF_8.to_string());
95-
9685
let body = to_bytes(res).await.expect("No body returned");
9786
let body = std::str::from_utf8(&body).expect("Body was not UTF-8");
9887
assert_eq!(body, "Hello, world!");
9988

100-
tx2.send(()).unwrap();
89+
tx.send(()).unwrap();
10190
};
10291

103-
tokio::join!(serve, body_query, hello_query);
92+
tokio::join!(serve, try_body_query, hello_query);
10493
}

0 commit comments

Comments
 (0)