Can someone help me understand (or point to a topic that does) why the for loop works but the map does not?
This is my struct that implements TryFrom:
#[derive(Serialize, Deserialize)]
pub struct QualifiedValue<T> {
value: T,
t_stamp: NaiveDateTime,
qual: i64,
tag_name: String
}
impl TryFrom<&Row> for QualifiedValue<f64> {
type Error = pError;
fn try_from(row: &Row) -> Result<Self, Self::Error> {
Ok(Self {
value: row.try_get("float_val")?,
t_stamp: row.try_get("t_stamp")?,
qual: row.try_get("qual")?,
tag_name: row.try_get("tag_name")?
})
}
}
This function will not compile:
pub async fn get_hist_for(&self, tag_name: &str) -> Result<Vec<QualifiedValue<f64>>, Box< dyn Error>> {
let rows = self.client
.query(&self.statements.hist_flt, &[&tag_name])
.await?;
Ok(rows.iter().map(|r| QualifiedValue::try_from(r)?).collect())
}
But this one will:
pub async fn get_hist_for(&self, tag_name: &str) -> Result<Vec<QualifiedValue<f64>>, Box< dyn Error>> {
let rows = self.client
.query(&self.statements.hist_flt, &[&tag_name])
.await?;
let mut qvs = Vec::with_capacity(rows.len());
for r in rows {
let qv = QualifiedValue::try_from(&r)?;
qvs.push(qv);
}
Ok(qvs)
}
This is the compiler error I get:
error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> src/migr/qdb.rs:117:59
|
117 | Ok(rows.iter().map(|r| QualifiedValue::try_from(r)?).collect())
| --- ^ cannot use the `?` operator in a closure that returns `QualifiedValue<_>`
| |
| this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Result<Infallible, _>>` is not implemented for `QualifiedValue<_>`
Replacing the ?
with .unwrap()
lets the first function compile. But I'm trying to understand what the exact difference is between map() and just the for loop. Do I have to implement the Try trait for my struct as well? If so, why don't I have to for the for loop?