use anyhow::Result; use csv::Writer; use indexmap::IndexSet; use serde::Serialize; use std::path::PathBuf; use structopt::StructOpt; use tfrecord::{ protobuf::{event::What, summary::value::Value::SimpleValue, Summary}, EventIter, }; #[derive(StructOpt)] struct Args { #[structopt(long, short, default_value = "./sample_event")] event: String, #[structopt(long, short)] tags: Option>, #[structopt(long, short, default_value = "./output")] output: PathBuf, } struct TagData { step: i64, tag: String, value: f32, } #[derive(Serialize, Debug)] struct Data { step: i64, value: f32, } impl From<&TagData> for Data { fn from(data: &TagData) -> Self { Self { step: data.step, value: data.value, } } } fn main() -> Result<()> { let Args { event: event_file, tags: query_tags, output: output_dir, } = Args::from_args(); let reader = EventIter::open(&event_file, Default::default())?; std::fs::create_dir_all(&output_dir)?; let history: Vec = reader .into_iter() .map(|result| -> Result<_> { let event = result?; let tag = match event.what { Some(What::Summary(Summary { value })) => { let val = &value[0]; match val.value { Some(SimpleValue(value)) => Some(TagData { step: event.step, tag: val.tag.clone(), value, }), _ => None, } } _ => None, }; Ok(tag) }) .filter_map(|result| result.transpose()) .collect::>()?; let tag_list = { let mut tags: IndexSet<_> = history.iter().map(|tag_data| &tag_data.tag).collect(); tags.sort(); tags }; if let Some(query_tags) = query_tags { query_tags.iter().try_for_each(|tag| -> Result<_> { if !tag_list.contains(&tag) { eprintln!( "Warning: The tag {:?} is not found in valid tags {:#?}", tag, tag_list ); return Ok(()); } let output_file = output_dir.join(format!("{}.csv", tag.replace("/", "-"))); let mut wtr = Writer::from_path(&output_file)?; history .iter() .filter(|data| &data.tag == tag) .try_for_each(|data| wtr.serialize(Data::from(data)))?; wtr.flush()?; println!("The tag data is saved to {}", output_file.display()); Ok(()) })?; } else { println!("The tags inside this event file are {:#?}", tag_list); println!("Please specify the tags to be extracted."); } Ok(()) }