Skip to content

Commit 12e307f

Browse files
authored
Allow suppressing or forcing generation of IntoResponse implementation (#64)
Allow suppressing and forcing IntoResponse implementation
1 parent f437d2b commit 12e307f

File tree

9 files changed

+89
-13
lines changed

9 files changed

+89
-13
lines changed

.github/workflows/ci.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ jobs:
4343
4444
- run: |
4545
rustup target add thumbv6m-none-eabi
46-
cargo build --no-default-features --target thumbv6m-none-eabi
46+
cargo build --target thumbv6m-none-eabi --package boilerplate
47+
cargo build --target thumbv6m-none-eabi --package boilerplate-tests
4748
4849
lint:
4950
runs-on: ubuntu-latest

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/boilerplate-macros/src/boilerplate.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::*;
33
#[derive(FromDeriveInput)]
44
#[darling(attributes(boilerplate))]
55
pub(crate) struct Boilerplate {
6+
axum: Option<bool>,
67
filename: Option<String>,
78
generics: Generics,
89
ident: Ident,
@@ -40,12 +41,13 @@ impl Boilerplate {
4041
let guess = new_mime_guess::from_path(&filename).first_or_text_plain();
4142

4243
let mime = if guess.type_() == mime::TEXT && guess.get_param(mime::CHARSET).is_none() {
43-
format!("{guess}; charset=utf-8").parse().unwrap()
44+
format!("{guess};charset=utf-8").parse().unwrap()
4445
} else {
4546
guess
4647
};
4748

4849
Template {
50+
axum: self.axum,
4951
escape,
5052
generics: self.generics,
5153
ident: self.ident,

crates/boilerplate-macros/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ pub fn boilerplate(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
2525

2626
quote! {
2727
{
28+
extern crate alloc;
29+
2830
use ::core::fmt::Write;
2931

3032
let boilerplate_text = &[ #(#text),* ];
31-
let mut boilerplate_output = ::std::string::String::new();
33+
let mut boilerplate_output = alloc::string::String::new();
3234

3335
#body
3436

crates/boilerplate-macros/src/template.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::*;
22

33
pub(crate) struct Template {
4+
pub(crate) axum: Option<bool>,
45
pub(crate) escape: bool,
56
pub(crate) generics: Generics,
67
pub(crate) ident: Ident,
@@ -12,7 +13,7 @@ impl Template {
1213
pub(crate) fn impls(self) -> TokenStream {
1314
let display_impl = self.display_impl();
1415

15-
let axum_into_response_impl = if cfg!(feature = "axum") {
16+
let axum_into_response_impl = if self.axum.unwrap_or(cfg!(feature = "axum")) {
1617
Some(self.axum_into_response_impl())
1718
} else {
1819
None
@@ -113,6 +114,8 @@ impl Template {
113114
quote! {
114115
impl #impl_generics ::axum::response::IntoResponse for #ident #ty_generics #where_clause {
115116
fn into_response(self) -> ::axum::response::Response {
117+
extern crate alloc;
118+
use alloc::string::ToString;
116119
(
117120
[(::axum::http::header::CONTENT_TYPE, #content_type)],
118121
self.to_string(),
@@ -161,11 +164,12 @@ mod tests {
161164

162165
assert_eq!(
163166
Template {
164-
ident: Ident::new("Foo", Span::call_site()),
165-
source: Source::Literal(LitStr::new("", Span::call_site())),
166-
mime: mime::TEXT_PLAIN,
167+
axum: None,
167168
escape: false,
168169
generics: Generics::default(),
170+
ident: Ident::new("Foo", Span::call_site()),
171+
mime: mime::TEXT_PLAIN,
172+
source: Source::Literal(LitStr::new("", Span::call_site())),
169173
}
170174
.display_impl()
171175
.to_string(),
@@ -327,17 +331,21 @@ mod tests {
327331
fn axum_into_response_impl() {
328332
assert_eq!(
329333
Template {
330-
ident: Ident::new("Foo", Span::call_site()),
331-
source: Source::Literal(LitStr::new("", Span::call_site())),
332-
mime: mime::TEXT_PLAIN,
334+
axum: Some(true),
333335
escape: false,
334336
generics: Generics::default(),
337+
ident: Ident::new("Foo", Span::call_site()),
338+
mime: mime::TEXT_PLAIN,
339+
source: Source::Literal(LitStr::new("", Span::call_site())),
335340
}
336341
.axum_into_response_impl()
337342
.to_string(),
338343
quote!(
339344
impl ::axum::response::IntoResponse for Foo {
340345
fn into_response(self) -> ::axum::response::Response {
346+
extern crate alloc;
347+
use alloc::string::ToString;
348+
341349
(
342350
[(::axum::http::header::CONTENT_TYPE, "text/plain")],
343351
self.to_string(),
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "boilerplate-tests"
3+
version = "0.0.0"
4+
authors.workspace = true
5+
categories.workspace = true
6+
edition.workspace = true
7+
homepage.workspace = true
8+
license.workspace = true
9+
repository.workspace = true
10+
11+
[dependencies]
12+
boilerplate = { path = "../../" }
13+
14+
[lints]
15+
workspace = true
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![no_std]
2+
3+
#[allow(unused)]
4+
#[derive(boilerplate::Boilerplate)]
5+
#[boilerplate(axum = false, text = "Hello, {{ self.name }}!")]
6+
struct Context {
7+
name: &'static str,
8+
}
9+
10+
#[allow(unused)]
11+
fn foo() {
12+
boilerplate::boilerplate!("Hello!");
13+
}

justfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ ci:
77
cargo test --all
88
cargo test --all --features axum
99
cargo test --all --features reload
10-
cargo build --no-default-features --target thumbv6m-none-eabi
10+
cargo build --target thumbv6m-none-eabi --package boilerplate
11+
cargo build --target thumbv6m-none-eabi --package boilerplate-tests
1112

1213
# publish current GitHub master branch
1314
publish:

src/lib.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@
363363
//! .headers()
364364
//! .get("content-type")
365365
//! .unwrap(),
366-
//! "text/html; charset=utf-8",
366+
//! "text/html;charset=utf-8",
367367
//! );
368368
//! }
369369
//! ```
@@ -380,11 +380,38 @@
380380
//! .headers()
381381
//! .get("content-type")
382382
//! .unwrap(),
383-
//! "text/plain; charset=utf-8",
383+
//! "text/plain;charset=utf-8",
384384
//! );
385385
//! }
386386
//! ```
387387
//!
388+
//! The `axum` attribute can be used to suppress or force generation of
389+
//! `IntoResponse` implementations, regardless of whether the `axum` feature is
390+
//! enabled:
391+
//!
392+
//! ```
393+
//! use axum::response::IntoResponse;
394+
//! #[derive(boilerplate::Boilerplate)]
395+
//! #[boilerplate(axum = true)]
396+
//! struct GuessHtml {}
397+
//! assert_eq!(
398+
//! GuessHtml {}
399+
//! .into_response()
400+
//! .headers()
401+
//! .get("content-type")
402+
//! .unwrap(),
403+
//! "text/html;charset=utf-8",
404+
//! );
405+
//! ```
406+
//!
407+
//! ```rust,compile_fail
408+
//! use axum::response::IntoResponse;
409+
//! #[derive(boilerplate::Boilerplate)]
410+
//! #[boilerplate(axum = false)]
411+
//! struct GuessHtml {}
412+
//! GuessHtml {}.into_response();
413+
//! ```
414+
//!
388415
//! ### Reloading Templates
389416
//!
390417
//! When the `reload` feature is enabled, templates support a limited form of

0 commit comments

Comments
 (0)