I'm trying to code a simple Warp server.
type Cache = Arc<RwLock<HashMap<String, String>>>;
pub struct App {
cache: Cache,
// other fields
}
impl App {
pub async fn new() -> App { /* App init */ }
pub async fn run(self) {
let filter = warp::path!("cache" / String)
.and(warp::any().map(move || self.cache.clone()))
.and_then(handler);
tokio::join!(
foo(self.cache),
warp::serve(filter).run(self.server_socket)
)
unreachable!()
}
}
async fn handler(id: String, cache: Cache) -> Result<impl warp::Reply, warp::Rejection> {
/* does stuff */
}
async fn foo(cache: Cache) { /* does stuff */ }
When I try to compile it I get this error
error[E0382]: use of moved value: `self.cache`
foo(self.cache),
^^^^^^^^^^ value used here after move
Ok, no problem. Trying cloning self.cache
and then moving it to the filter
.
pub async fn run(self) {
let cache = self.cache.clone(); // cloning cache
let filter =
warp::path!("cache" / String)
.and(warp::any().map(move || cache)) // trying to move cache
.and_then(handler);
tokio::join!(
foo(self.cache),
warp::serve(filter).run(self.server_socket)
)
unreachable!()
}
And now I get this error
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
.and(warp::any().map(move || cache))
--- ^^^^^^^------
| | |
| | closure is `FnOnce` because it moves the variable `cache` out of its environment
| this closure implements `FnOnce`, not `Fn`
| the requirement to implement `Fn` derives from here
required by a bound introduced by this call
I didn't find any ways to move cloned cache
into filter
. The only way I got this to work was by cloning cache
two times.
pub async fn run(self) {
let cache = self.cache.clone(); // first cloning
let filter =
warp::path!("cache" / String)
.and(warp::any().map(move || cache.clone())) // second cloning
.and_then(handler);
tokio::join!(
foo(self.cache),
warp::serve(filter).run(self.server_socket)
)
unreachable!()
}
I clone cache
two times but the first clone is used just to perform the second cloning so I think this is wrong way to solve this problem. How to avoid double cloning?