I wrote this Rust code to parse my financials from a YAML file and my main concern is the large match
branches (although general code review is welcome; still a Rust beginner):
extern crate yaml_rust;
use yaml_rust::{Yaml, YamlLoader};
fn main() -> Result<(), std::io::Error> {
let doc = std::fs::read_to_string("finances.yaml")?;
let data = YamlLoader::load_from_str(&doc).unwrap();
let doc = &data[0];
let map = doc.as_hash().unwrap();
for (k, v) in map.iter() {
println!("{}: ", k.as_str().unwrap());
let sum = unwrap_value(v);
println!("== {}", sum);
println!();
}
Ok(())
}
fn unwrap_value(v: &Yaml) -> f32 {
match v {
Yaml::Hash(v) => {
let mut sum = 0.;
for (k, vv) in v.iter() {
match vv {
Yaml::String(_vv) => {
print!("\t\t {}: ", k.as_str().unwrap());
}
Yaml::Integer(_vv) => {
print!("\t\t {}: ", k.as_str().unwrap());
}
_ => {
println!("\t* {}:", k.as_str().unwrap());
}
}
sum += unwrap_value(vv);
}
sum
}
Yaml::Array(v) => {
let mut sub_sum = 0.;
for h in v.iter() {
sub_sum += unwrap_value(h);
}
println!("\t= {}", sub_sum);
sub_sum
}
Yaml::String(v) => {
let tot: f32 = v
.split("+")
.fold(0., |sum, s| sum + s.trim().parse::<f32>().unwrap());
println!("{}", tot);
tot
}
Yaml::Integer(v) => {
println!("{}", v);
*v as f32
}
_ => 0.,
}
}
Here's a sample YAML of the file I'm parsing:
---
'2021-01-01':
apartment:
- rent: 2750
transportation:
- uber: 87.69 + 55.36 + 26 + 42 + 42 + 34.92 + 25.76 + 42 + 42
- bus: 12
'2021-02-01':
apartment:
- rent: 2750
bills:
- elctricity: 27
transportation:
- uber: 87.69 + 55.36 + 26 + 42 + 42 + 34.92 + 25.76 + 42 + 42
- bus: 12
and this is the output for the example above:
2021-01-01:
* apartment:
rent: 2750
= 2750
* transportation:
uber: 397.73
bus: 12
= 409.73
== 3159.73
2021-02-01:
* apartment:
rent: 2750
= 2750
* bills:
elctricity: 27
= 27
* transportation:
uber: 397.73
bus: 12
= 409.73
== 3186.73
-
s turn the innermost structure into a sequence of strings instead of a map. Is that intentional? \$\endgroup\$ledger-cli
or similar applications. \$\endgroup\$