Open sean-bennett112 opened 6 years ago
@DoumanAsh @Dowwie i think this should be fixed with latest serde_urlencoded?
@fafhrd91 No, Path
extract uses own deserializer
I don't see it using seder url encoded, we only can use it for query component of path.
In case of path, we just cannot handle enums at all
Oh, right
Any update here?
No updates. I won’t have any time in near future
Work around:
pub enum ArticleUid {
String(String),
Int(u64),
}
impl FromStr for ArticleUid {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s.parse::<u64>() {
Ok(uid) => ArticleUid::Int(uid),
Err(_) => ArticleUid::String(s.to_string())
})
}
}
#[get("/site_news/{uid}")]
pub async fn get_site_article(
req: HttpRequest
) -> HttpResponse {
let uid: Option<ArticleUid> = req.match_info().get("uid").and_then(|v| v.parse().ok());
// ...
}
Another workaround so one can actually keep the current structure and still use Path:
I'm new to rust so this may not be the ultimate top code or so... feel free to judge. :heart:
use serde::{Serialize};
/// Make sure you are not using Deserialize here.
#[derive(Debug, Serialize)]
#[serde(untagged)]
pub enum ProjectNameOrId {
Name(String),
Id(u64),
}
use serde::{de::Deserializer, Deserialize};
use std::str::FromStr;
// This can be left out if impl Deserialize is adjusted...
// but honestly I had already added it, so I just stuck to it.
impl FromStr for ProjectNameOrId {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Ok(id) = s.parse::<u64>() {
return Ok(ProjectNameOrId::Id(id));
}
Ok(ProjectNameOrId::Name(String::from(s)))
}
}
impl<'de> Deserialize<'de> for ProjectNameOrId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
ProjectNameOrId::from_str(&s).map_err(|_| serde::de::Error::custom("invalid ProjectNameOrId value"))
}
}
use crate::AppState;
use actix_web::{get, web, HttpResponse, Responder};
#[get("/schema")]
async fn get_schema(
data: web::Data<AppState>,
path: web::Path<ProjectNameOrId>
) -> impl Responder {
/* Your Code */
println!("{:#?}", &path);
}
It looks like the Path extractor doesn't currently work with enums. To illustrate, I’m getting
whenever I try to do the following:
It appears to never reach the handler, despite compiling fine. As soon as I convert it to a bare type or a struct it seems to work fine. Interestingly, Query extractors seem to work fine with this.