Recently, I've started to learn Rust to build some simple web apps with Axum. However, I ended having an unexplained error while building the app, and I could not find the reason of it.
The failing to be built application code is the following:
use axum::{
body::{Body, boxed, StreamBody},
Extension,
http::Request,
response::Response,
Router,
routing::get,
};
use std::{
path::PathBuf,
sync::{Arc, RwLock},
};
type Cache = Arc<RwLock<PathBuf>>;
async fn handle_proxy(
cache: Extension<Cache>,
req: Request<Body>,
) -> Response {
let cache = cache.read().unwrap();
if let Some(object_key) = req.uri().path().rsplitn(2, '/').next() {
// later the cache variable will be used to build the given path
let file = tokio::fs::File::open("/tmp/testaroo").await;
let buf_reader = tokio::io::BufReader::new(file.unwrap());
let stream = tokio_util::io::ReaderStream::new(buf_reader);
return Response::builder().body(boxed(StreamBody::new(stream))).unwrap();
}
// The function is not fully built here, there will be more code later, useless to demo the error.
Response::builder().body(boxed("".to_string())).unwrap()
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/:key", get(handle_proxy));
let addr = "0.0.0.0:8080";
axum::Server::bind(&addr.parse().unwrap()).serve(app.into_make_service()).await.unwrap();
}
When the let cache = cache.read().unwrap();
line is present (not commented above), the program is no longer building with the following error:
> cargo clippy
Checking hello-rs-axum-failure v0.1.0 (/home/mycroft/tmp/broken-thing)
error[E0277]: the trait bound `fn(axum::Extension<std::sync::Arc<std::sync::RwLock<std::path::PathBuf>>>, axum::http::Request<axum::body::Body>) -> impl std::future::Future<Output = axum::http::Response<http_body::combinators::box_body::UnsyncBoxBody<axum::body::Bytes, axum::Error>>> {handle_proxy}: axum::handler::Handler<_, _, _>` is not satisfied
--> src/main.rs:34:48
|
34 | let app = Router::new().route("/:key", get(handle_proxy));
| --- ^^^^^^^^^^^^ the trait `axum::handler::Handler<_, _, _>` is not implemented for fn item `fn(axum::Extension<std::sync::Arc<std::sync::RwLock<std::path::PathBuf>>>, axum::http::Request<axum::body::Body>) -> impl std::future::Future<Output = axum::http::Response<http_body::combinators::box_body::UnsyncBoxBody<axum::body::Bytes, axum::Error>>> {handle_proxy}`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `axum::handler::Handler<T, S, B>`:
<axum::handler::Layered<L, H, T, S, B, B2> as axum::handler::Handler<T, S, B2>>
<axum::routing::MethodRouter<S, B> as axum::handler::Handler<(), S, B>>
note: required by a bound in `axum::routing::get`
--> /home/mycroft/.cargo/registry/src/github.com-1ecc6299db9ec823/axum-0.6.18/src/routing/method_routing.rs:403:1
|
403 | top_level_handler_fn!(get, GET);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `get`
= note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0277`.
error: could not compile `hello-rs-axum-failure` due to previous error
I understand that adding the line is breaking something, but why? I found out limiting the scope of the declaration (ie: putting the instruction in its own scope and copying the underlying variable) will help, but I'd really like to know why the error is happening.