I have a nested object in mongodb that I want to deserialize/decode back into a struct. Here's the structure :
pub struct ItemUnit {
/// unit's name like PCS, DOZEN, PACK, etc
pub name: String,
/// denote this unit value
pub multiplier: f64,
/// item's price in this unit
pub price: Option<f64>,
}
pub struct Item {
/// item's name
pub name: String,
/// available unit types available for this item, in an array format
pub units: Vec<ItemUnit>,
}
as you can see the struct is nested and units is an array (Vec<ItemUnit>).
As Rust have a culture of "not letting you go with error possibility", this quickly becomes tricky. In Rust mongodb driver, you have to deserialize/decode them back from 'bson' document into "native type" such as String, f64, and so on. Each deserialize operation returns Result<> since there's a possibility of error in it.
I have a problem with nested object with an array of another object in it:
// doc is the data from a single `Item`
// since `get_array` might throw a ValueAccess error, I map it into my own custom Error type
// so `units_bson` is now a `Vec<mongodb::bson::Bson>` type
let units_bson = doc.get_array("units").map_err(Self::map_mongodb_err)?;
// in the next step, I need to decode the mongodb::bson::Bson for each element in this array
/// here's I use map() with closure
let units: Vec<ItemUnit> = units_bson.iter().map(|u| {
// get_str() returns Result<T,E> but since ItemUnit only accepts a string not Result<> type
// I had to handle the error possibilities here in the closure/map function
// but the ? operator only available on a function that returns `Result` or `Option`
// (or another type that implements `Try`)
let name = u.as_document().unwrap().get_str("name").map_err(Self::map_mongodb_err);
return ItemUnit { name, multiplier, p_buy };
}).collect();
So my question is how do you catch an error inside a closure?
Or is there any other workaround like try-catch block that can also catch any error inside a closure ?