rust - 在actix-web中用作查询参数时,如何将无效的枚举变量转换为“无”

标签 rust serde actix-web

通过documentation中提供的actix_web::web::Query示例,当提供未知变体时,如何使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的响应:

Query deserialize error: unknown variant foo, expected Token or 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);

关于rust - 在actix-web中用作查询参数时,如何将无效的枚举变量转换为“无”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65675602/

相关文章:

rust - 如何在不调用克隆的情况下将多个值移出装箱值?

makefile - 配置编译选项和编译器 autoconf

rust - 不满足特征边界 `&' a chain::Chain <'a>: Deserialize<' _>`

rust - 如何使用Serde反序列化Prost枚举?

rust - 如何将JSON模式作为数据传递给Actix Web?

windows - 为什么我不能从Actix文档样本中加载页面?

rust - 如何配置 actix websocket 服务器的有效负载限制

rust - 如何使用构建器模式生成的数据

rust - 如何获取子切片?

rust - 为什么没有为明确实现的类型实现特征?