Rocket 的 Responder 特性没有为 Result 实现
Rocket's Responder trait is not implemented for Result
我最近开始学习 Rust,目前正在尝试创建一个小的 API;我已经为 API 响应创建了自己的结构,并为错误创建了枚举:
// API Response Structure
pub struct ApiResponse {
pub body: JsonValue,
pub status: Status,
}
// Enum for my "custom errors"
#[derive(Debug, Snafu, Clone, Serialize)]
pub enum Errors {
#[snafu(display("Unable to retrieve the specified entry."))]
NotFound,
#[snafu(display("Internal Server Error, unable to process the data."))]
ISE,
}
然后我为我的 API 响应结构实现了 Responder<'_>
特征:
impl<'r> Responder<'r> for ApiResponse {
fn respond_to(self, req: &Request) -> Result<Response<'r>, Status> {
Response::build_from(self.body.respond_to(req).unwrap())
.status(self.status)
.header(ContentType::JSON)
.ok()
}
}
但是,当我尝试使用上述功能时,似乎我无法使用 return 和 Result<JsonValue, Errors>
的功能。我不太确定这个问题,我也没有 Rust 经验,所以任何 documentation/pointers 将不胜感激。
这是 return 响应类型的函数。
#[put("/users/<user_id>", format = "json", data = "<new_user>")]
pub fn update_user(
conn: DbConnection,
user_id: i32,
new_user: Json<NewUser>,
) -> Result<JsonValue, ApiResponse> {
match users::table.find(user_id).load::<User>(&*conn) {
Ok(result) => {
if result.len() < 1 {
let response = ApiResponse {
body: json!({
"message": Errors::NotFound
}),
status: Status::NotFound
};
return Err(response)
}
},
Err(e) => {
let response = ApiResponse {
body: json!({
"message": Errors::ISE
}),
status: Status::InternalServerError
};
return Err(response);
},
}
match diesel::update(users::table.filter(id.eq(user_id)))
.set((
user_name.eq(new_user.user_name.to_string()),
age.eq(new_user.age),
gender.eq(new_user.gender.to_string()),
))
.get_result::<User>(&*conn)
{
Ok(result) => Ok(json!(result)),
Err(_) => {
let res = ApiResponse {
body: json!({
"message": Errors::ISE
}),
status: Status::InternalServerError
};
return Err(res);
},
}
}
旁注:请记住,我仍然是 Rust 的初学者,我的错误处理/代码通常不是最好的。
编辑:我忘记包含错误堆栈:
error[E0277]: the trait bound `std::result::Result<rocket_contrib::json::JsonValue, api_cont::ApiResponse>: rocket::response::Responder<'_>` is not satisfied
--> src/routes.rs:72:6
|
72 | ) -> Result<JsonValue, ApiResponse> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `std::result::Result<rocket_contrib::json::JsonValue, api_cont::ApiResponse>`
|
::: /home/kenneth/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.4/src/handler.rs:202:20
|
202 | pub fn from<T: Responder<'r>>(req: &Request, responder: T) -> Outcome<'r> {
| ------------- required by this bound in `rocket::handler::<impl rocket::Outcome<rocket::Response<'r>, rocket::http::Status, rocket::Data>>::from`
|
= help: the following implementations were found:
<std::result::Result<R, E> as rocket::response::Responder<'r>>
<std::result::Result<R, E> as rocket::response::Responder<'r>>
我也 运行 遇到过这个错误。
API Docs中提到以下内容:
A type implementing Responder
should implement the Debug
trait when possible. This is because the Responder
implementation for Result
requires its Err
type to implement Debug
. Therefore, a type implementing Debug
can more easily be composed.
这意味着您必须实现 Debug,因为您将 ApiResponse
用作 Err
类型。
#[derive(Debug)]
pub struct ApiResponse {
pub body: JsonValue,
pub status: Status,
}
我最近开始学习 Rust,目前正在尝试创建一个小的 API;我已经为 API 响应创建了自己的结构,并为错误创建了枚举:
// API Response Structure
pub struct ApiResponse {
pub body: JsonValue,
pub status: Status,
}
// Enum for my "custom errors"
#[derive(Debug, Snafu, Clone, Serialize)]
pub enum Errors {
#[snafu(display("Unable to retrieve the specified entry."))]
NotFound,
#[snafu(display("Internal Server Error, unable to process the data."))]
ISE,
}
然后我为我的 API 响应结构实现了 Responder<'_>
特征:
impl<'r> Responder<'r> for ApiResponse {
fn respond_to(self, req: &Request) -> Result<Response<'r>, Status> {
Response::build_from(self.body.respond_to(req).unwrap())
.status(self.status)
.header(ContentType::JSON)
.ok()
}
}
但是,当我尝试使用上述功能时,似乎我无法使用 return 和 Result<JsonValue, Errors>
的功能。我不太确定这个问题,我也没有 Rust 经验,所以任何 documentation/pointers 将不胜感激。
这是 return 响应类型的函数。
#[put("/users/<user_id>", format = "json", data = "<new_user>")]
pub fn update_user(
conn: DbConnection,
user_id: i32,
new_user: Json<NewUser>,
) -> Result<JsonValue, ApiResponse> {
match users::table.find(user_id).load::<User>(&*conn) {
Ok(result) => {
if result.len() < 1 {
let response = ApiResponse {
body: json!({
"message": Errors::NotFound
}),
status: Status::NotFound
};
return Err(response)
}
},
Err(e) => {
let response = ApiResponse {
body: json!({
"message": Errors::ISE
}),
status: Status::InternalServerError
};
return Err(response);
},
}
match diesel::update(users::table.filter(id.eq(user_id)))
.set((
user_name.eq(new_user.user_name.to_string()),
age.eq(new_user.age),
gender.eq(new_user.gender.to_string()),
))
.get_result::<User>(&*conn)
{
Ok(result) => Ok(json!(result)),
Err(_) => {
let res = ApiResponse {
body: json!({
"message": Errors::ISE
}),
status: Status::InternalServerError
};
return Err(res);
},
}
}
旁注:请记住,我仍然是 Rust 的初学者,我的错误处理/代码通常不是最好的。
编辑:我忘记包含错误堆栈:
error[E0277]: the trait bound `std::result::Result<rocket_contrib::json::JsonValue, api_cont::ApiResponse>: rocket::response::Responder<'_>` is not satisfied
--> src/routes.rs:72:6
|
72 | ) -> Result<JsonValue, ApiResponse> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `std::result::Result<rocket_contrib::json::JsonValue, api_cont::ApiResponse>`
|
::: /home/kenneth/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.4/src/handler.rs:202:20
|
202 | pub fn from<T: Responder<'r>>(req: &Request, responder: T) -> Outcome<'r> {
| ------------- required by this bound in `rocket::handler::<impl rocket::Outcome<rocket::Response<'r>, rocket::http::Status, rocket::Data>>::from`
|
= help: the following implementations were found:
<std::result::Result<R, E> as rocket::response::Responder<'r>>
<std::result::Result<R, E> as rocket::response::Responder<'r>>
我也 运行 遇到过这个错误。 API Docs中提到以下内容:
A type implementing
Responder
should implement theDebug
trait when possible. This is because theResponder
implementation forResult
requires itsErr
type to implementDebug
. Therefore, a type implementingDebug
can more easily be composed.
这意味着您必须实现 Debug,因为您将 ApiResponse
用作 Err
类型。
#[derive(Debug)]
pub struct ApiResponse {
pub body: JsonValue,
pub status: Status,
}