Hello,
I am new to rust and new to this forum. As a starting learning project I am making a simple CFD solver in rust. I decided to use Yaml for the input file format like this:
nodes:
1: [1.0, 2.0, 3.0]
2: [4.0, 3.0, 2.0]
3: [5.0, 4.0, 3.0]
4: [6.0, 3.0, 2.0]
I want to load this into a vector of structs like below:
[
Point {
id: 1,
x: 1.0,
y: 2.0,
z: 3.0
},
Point {
id: 2,
x: 4.0,
y: 3.0,
z: 2.0
},
Point {
id: 3,
x: 5.0,
y: 4.0,
z: 3.0
},
Point {
id: 4,
x: 6.0,
y: 3.0,
z: 2.0
}
]
After much time banging my head against the wall I came up with this working code:
use yaml_rust::{Yaml, YamlLoader};
use yaml_rust::{Yaml, YamlLoader};
#[derive(Debug)]
struct Point {
id: i64,
x: f64,
y: f64,
z: f64
}
fn parse_deck(doc: &Yaml) -> Vec<Point> {
let mut res = Vec::new();
match *doc {
Yaml::Hash(ref h) => {
for (k, v) in h {
match k.as_str() {
Some("nodes") => match v {
Yaml::Hash(ref g) => {
for (nid, xyz) in g {
let id = nid.as_i64().unwrap();
let w = match xyz {
Yaml::Array(ref v) => v,
_ => panic!("malformed input file: coordinates should be floating point numbers")
};
let t = w.iter().map(|x| x.as_f64().unwrap()).collect::<Vec<f64>>();
let p = Point {id:id, x:t[0], y:t[1], z:t[2]};
res.push(p);
}
},
_ => panic!("malformed input file: format should be [node-id, x, y, z]")
},
_ => panic!("malformed input file: unsuported section.")
};
}
}
_ => {
panic!("malformed input file: top level must be in key: value format");
}
};
res
}
fn main() {
let s = "
nodes:
1: [1.0, 2.0, 3.0]
2: [4.0, 3.0, 2.0]
3: [5.0, 4.0, 3.0]
4: [6.0, 3.0, 2.0]
";
let docs = YamlLoader::load_from_str(&s).unwrap();
let doc = &docs[0];
dbg!(parse_deck(&doc));
}
I am not at all happy with this code. There has got to be a more elegant way of doing this. Can you give me some pointers in the right direction?
EDIT: I streamlined my working example a bit to make it shorter and clearer.