如何解决在actix-web中用作查询参数时,如何将无效的枚举变体转换为None
使用 actix_web::web::Query
的 documentation 中提供的示例,在提供未知变体时如何让 response_type
求助于 None
?
如果我有以下几点:
use actix_web::{web,App,HttpServer};
use serde::Deserialize;
#[derive(Debug,Deserialize)]
pub enum ResponseType {
Token,Code,}
#[derive(Deserialize)]
pub struct AuthRequest {
id: u64,response_type: Option<ResponseType>,}
async fn index(web::Query(info): web::Query<AuthRequest>) -> String {
format!(
"Authorization request for client with id={} and type={:?}!",info.id,info.response_type
)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().route("/",web::get().to(index)))
.bind(("127.0.0.1",8080))?
.run()
.await
}
然后我访问 http://localhost:8080/?id=1&response_type=foo
,我得到了这个 400 响应:
查询反序列化错误:未知变体 foo
,预期为 Token
或 Code
当我希望它只接受 Enum 的值作为有效值时,如果没有提供任何值或无效值,我希望将其设置为 None
。
解决方法
这可以处理deserialize_with。
use actix_web::{web,App,HttpServer};
use serde::Deserialize;
use serde::de::{Deserializer};
#[derive(Debug,Deserialize)]
pub enum ResponseType {
Token,Code,}
fn from_response_type<'de,D>(deserializer: D) -> Result<Option<ResponseType>,D::Error>
where
D: Deserializer<'de>,{
let res: Option<ResponseType> = Deserialize::deserialize(deserializer).unwrap_or(None);
Ok(res)
}
#[derive(Debug,Deserialize)]
pub struct AuthRequest {
id: u64,#[serde(deserialize_with = "from_response_type")]
response_type: Option<ResponseType>,}
async fn index(web::Query(info): web::Query<AuthRequest>) -> String {
format!(
"Authorization request for client with id={} and type={:?}!",info.id,info.response_type
)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().route("/",web::get().to(index)))
.bind(("127.0.0.1",8080))?
.run()
.await
}
任何无效值都被视为 None
。关键是
let res: Option<ResponseType> = Deserialize::deserialize(deserializer).unwrap_or(None);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。