如何在火箭中使用结构的方法作为处理程序
how to use methods of struct as handlers in rocket
#[derive(Debug, Clone)]
struct Author<T: Persister + Send + Sync + Clone> {
dao: T,
}
impl<T: Persister + Send + Sync + Clone> Author<T> {
fn new(dao: T) -> Self {
Author { dao: dao }
}
fn handle_sign_up<'r>(&self, request: &'r Request, data: Data) -> Outcome<'r> {
Outcome::Success(Response::new())
}
}
impl<T> Handler for Author<T>
where
T: Persister + Send + Sync + Clone + 'static,
{
fn handle<'r>(&self, request: &'r Request, data: Data) -> Outcome<'r> {
Outcome::Success(Response::new())
}
}
impl<T: Persister + Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
fn into(self) -> Vec<Route> {
vec![Route::new(rocket::http::Method::Post, "/", self)]
}
}
fn main() {
let dao = Dao::new("mysql://user:password@localhost/test".to_owned()).unwrap();
let author = Author::new(dao);
rocket::ignite().mount("/", author).launch();
}
我想使用 Author
(例如 Author::handle_sign_up
)的方法作为路由的处理程序,但它不是 works.I 我曾尝试像下面这样使用 clouser
impl<T: Persister + Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
fn into(self) -> Vec<Route> {
let p = |req, data| self.handle_sign_up(req, data);
vec![Route::new(rocket::http::Method::Post, "/", p)]
}
}
,编译器报告生命周期错误
mismatched types
expected type for<'r, 's> Fn<(&'r rocket::Request<'s>, rocket::Data)>
found type Fn<(&rocket::Request<'_>, rocket::Data)>
有什么实现方法吗?
|req, data| self.handle_sign_up(req, data)
的问题在于,编译器会推断参数类型的生命周期,但在这里出错了。 &'r Request
和Outcome<'r>
之间的关系是必需的和缺乏的。
不幸的是,。
一种解决方法(如上面 link 中的一个答案所建议的那样)是使用辅助函数,它不执行任何操作,但会鼓励编译器推断正确的签名:
fn as_handler_func<F>(f: F) -> F
where
F: for<'r> Fn(&'r Request, Data) -> Outcome<'r>,
{
f
}
impl<T: Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
fn into(self) -> Vec<Route> {
let p = as_handler_fn(move |req, data| self.handle_sign_up(req, data));
vec![Route::new(rocket::http::Method::Post, "/", p)]
}
}
附带说明:我不是 Rocket 方面的专家,但我相信如果你像这样为 Author
实现 Into<Vec<Route>>
,你可能不想 impl Handler
也是为了它。
#[derive(Debug, Clone)]
struct Author<T: Persister + Send + Sync + Clone> {
dao: T,
}
impl<T: Persister + Send + Sync + Clone> Author<T> {
fn new(dao: T) -> Self {
Author { dao: dao }
}
fn handle_sign_up<'r>(&self, request: &'r Request, data: Data) -> Outcome<'r> {
Outcome::Success(Response::new())
}
}
impl<T> Handler for Author<T>
where
T: Persister + Send + Sync + Clone + 'static,
{
fn handle<'r>(&self, request: &'r Request, data: Data) -> Outcome<'r> {
Outcome::Success(Response::new())
}
}
impl<T: Persister + Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
fn into(self) -> Vec<Route> {
vec![Route::new(rocket::http::Method::Post, "/", self)]
}
}
fn main() {
let dao = Dao::new("mysql://user:password@localhost/test".to_owned()).unwrap();
let author = Author::new(dao);
rocket::ignite().mount("/", author).launch();
}
我想使用 Author
(例如 Author::handle_sign_up
)的方法作为路由的处理程序,但它不是 works.I 我曾尝试像下面这样使用 clouser
impl<T: Persister + Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
fn into(self) -> Vec<Route> {
let p = |req, data| self.handle_sign_up(req, data);
vec![Route::new(rocket::http::Method::Post, "/", p)]
}
}
,编译器报告生命周期错误
mismatched types expected type
for<'r, 's> Fn<(&'r rocket::Request<'s>, rocket::Data)>
found typeFn<(&rocket::Request<'_>, rocket::Data)>
有什么实现方法吗?
|req, data| self.handle_sign_up(req, data)
的问题在于,编译器会推断参数类型的生命周期,但在这里出错了。 &'r Request
和Outcome<'r>
之间的关系是必需的和缺乏的。
不幸的是,
一种解决方法(如上面 link 中的一个答案所建议的那样)是使用辅助函数,它不执行任何操作,但会鼓励编译器推断正确的签名:
fn as_handler_func<F>(f: F) -> F
where
F: for<'r> Fn(&'r Request, Data) -> Outcome<'r>,
{
f
}
impl<T: Send + Sync + Clone + 'static> Into<Vec<Route>> for Author<T> {
fn into(self) -> Vec<Route> {
let p = as_handler_fn(move |req, data| self.handle_sign_up(req, data));
vec![Route::new(rocket::http::Method::Post, "/", p)]
}
}
附带说明:我不是 Rocket 方面的专家,但我相信如果你像这样为 Author
实现 Into<Vec<Route>>
,你可能不想 impl Handler
也是为了它。