Is there a good way to map a Vec containing the fields of a struct to a struct. I have something like F and I want to convert it to S
struct F{
k: String,
v_s: Option<String>,
v_b: Option<bool>,
}
struct S {
a: String,
b: bool,
}
let vals = vec![F{k:"a",v_s:Some("1"),v_b:None}, F{k:"b",v_s:None,v_b:Some(true)};
// what I want is
S{a: "1", b: true}
For reference, bellow is the actual code and my WIP.
#[macro_use]
extern crate anyhow;
use anyhow::Result;
use rusoto_rds_data::{ColumnMetadata, Field};
use std::convert::TryFrom;
#[derive(Debug)]
pub struct Job {
pub id: i32,
}
impl TryFrom<(Vec<ColumnMetadata>, Vec<Field>)> for Job {
type Error = anyhow::Error;
fn try_from((columns, fields): (Vec<ColumnMetadata>, Vec<Field>)) -> Result<Self, Self::Error> {
let mut rslt = Job { id: 1 };
fn perform_map(acc: &mut Job, column: &ColumnMetadata, field: Field) -> Result<Job> {
match (acc, column, field) {
(acc, ColumnMetadata { name: Some(n), .. }, v) if "id" == n => {
acc.id = v.long_value.ok_or(anyhow!("Invalid Id field"))? as i32;
Ok(*acc)
}
(_, _, _) => Err(anyhow!("invalid field")),
}
}
let jb = columns
.iter()
.zip(fields)
.fold(Ok(rslt), |acc, (column, field)| {
if let Ok(job) = acc {
perform_map(job.borrow_mut(), column, field)
} else {
acc
}
});
Ok(rslt)
}
}
fn main() -> Result<()> {
let from = (
vec![ColumnMetadata {
name: Some(String::from("id")),
..Default::default()
}],
vec![Field {
long_value: Some(1),
..Default::default()
}],
);
Ok(println!("{:?}", Job::try_from(from)))
}
Any advice would be greatly appreciated.