I'm relatively new to Rust still but I'm trying to allow multiple type inputs for actix::web::Json
.
The enum:
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum AreaInput {
Text(String),
SingleArray(Vec<[f64; 2]>),
MultiArray(Vec<Vec<[f64; 2]>>),
SingleStruct(Vec<LatLon>),
MultiStruct(Vec<Vec<LatLon>>),
}
The type passed into actix::web::Json<RouteGeneration>
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RouteGeneration {
pub area: Option<AreaInput>,
pub fast: Option<bool>,
}
Normalizing the input:
pub fn area_input(area: AreaInput) -> (Vec<Vec<[f64; 2]>>, ReturnType) {
match area {
AreaInput::Text(area) => (arrays::parse_flat_text(area.as_str()), ReturnType::Text),
AreaInput::SingleArray(area) => (vec![area], ReturnType::SingleArray),
AreaInput::MultiArray(area) => (area, ReturnType::MultiArray),
AreaInput::SingleStruct(area) => {
(vec![arrays::coord_to_array(area)], ReturnType::SingleStruct)
}
AreaInput::MultiStruct(area) => (
area.into_iter().map(arrays::coord_to_array).collect(),
ReturnType::MultiStruct,
),
}
}
I'm not 100% sure if this is the "correct" way to handle a value that could have multiple types or if it is and there's just an extra step I need to do since this is going through Actix web's json deserialization first.
Example route:
#[post("/bootstrap")]
async fn bootstrap(
conn: web::Data<DatabaseConnection>,
scanner_type: web::Data<String>,
payload: web::Json<RouteGeneration>,
) -> Result<HttpResponse, Error> {
let RouteGeneration {
area,
fast,
} = payload.into_inner();
let (area, default_return_type) =
normalize::area_input(area.unwrap_or(AreaInput::SingleArray(vec![])));
// ...do more stuff
}
If I pass in any sort of string for area
, I get:
Json deserialize error: unknown variant `1.0 2.0, 2.0 3.0`, expected one of `Text`, `SingleArray`, `MultiArray`, `SingleStruct`, `MultiStruct` at line 3 column 28
If I pass in any kind of the "supported" arrays, I get:
Json deserialize error: expected value at line 3 column 11
Everything compiles fine so I'm guessing this is just something I need to do differently with actix to account for an enum input type.
Thanks!