Hi, I'm still a newb with Rust - everything is pretty confusing for me still.
I'm building a webserver with Axum in Rust, and the project (refactor
branch) is on GitHub. This is the spot where I would put a link to it, but since I am a new user I am unable to link more than two links in a post.
You can browse the full breadth of my codebase here - it's very experimental and I am in no ways a good Rust programmer (yet). The most important lines for my question are linked below.
I thought it would be relatively simple to return many different types of responses composed of specific status codes, headers, and body types, but it appears things are not so. I was sure that using impl IntoResponse
in my return type would work, but it didn't.
It appears that the compiler gets most heated whenever I mix IntoResponse
with Response::builder()
, or whenever I mix a body types like Bytes
with Full<T>
for any T
, Bytes
or String
. Besides not knowing how to fix the error, I'm really confused why the API is so precise/strict with the types of the response body. It feels like I'm fighting Axum to get it to do what I want more than anything else.
The most consistent and arguably, difficult compiler error is below:
error[E0308]: mismatched types
--> src\routes.rs:73:16
|
47 | pub async fn implicit_handler(Path(path): Path<String>) -> impl IntoResponse {
| ----------------- expected because this return type...
...
54 | return (StatusCode::BAD_REQUEST, Full::from(format!("Failed to parse epoch :: {}", parsed_epoch.unwrap_err()))).into_response();
| ------------------------------------------------------------------------------------------------------------------------ ...is found to be `Response<http_body::combinators::box_body::UnsyncBoxBody<axum::body::Bytes, axum::Error>>` here
...
73 | return Response::builder()
| ________________^
74 | | .status(StatusCode::INTERNAL_SERVER_ERROR)
75 | | .body(Full::from(
76 | | format!("Template Could Not Be Rendered :: {}", rendered_template.err().unwrap())
77 | | ))
78 | | .unwrap();
| |_____________________^ expected `Response<UnsyncBoxBody<Bytes, ...>>`, found `Response<Full<_>>`
|
= note: expected struct `Response<http_body::combinators::box_body::UnsyncBoxBody<axum::body::Bytes, axum::Error>>`
found struct `Response<axum::body::Full<_>>`
note: return type inferred to be `Response<http_body::combinators::box_body::UnsyncBoxBody<axum::body::Bytes, axum::Error>>` here
--> src\routes.rs:54:16
|
54 | return (StatusCode::BAD_REQUEST, Full::from(format!("Failed to parse epoch :: {}", parsed_epoch.unwrap_err()))).into_response();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: to return `impl Trait`, all returned values must be of the same type
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
= help: if the trait `IntoResponse` were object safe, you could return a boxed trait object
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
= help: you could instead create a new `enum` with a variant for each returned type
The full compiler output with my codebase is linked <I would put it here, but again, I can only put two links in my post since I am a new user>.