netlist_db/parser/
data_meas.rs1use std::{collections::HashMap, path::PathBuf};
2
3use super::{
4 BEGIN_TITLE,
5 utils::{name_str, space, space_newline},
6};
7use crate::{err::ParseError, span::LocatedSpan};
8use nom::{
9 IResult, Parser,
10 branch::alt,
11 bytes::complete::{tag, take_until},
12 character::complete::char,
13 combinator::{map, opt},
14 multi::{many1, separated_list1},
15 sequence::delimited,
16};
17use tokio::fs::read_to_string;
18
19const FAILED_MEAS: &str = "failed";
20
21#[inline]
22fn float(i: LocatedSpan) -> IResult<LocatedSpan, Option<f64>> {
23 alt((
24 map(super::utils::float, Some),
25 map(tag(FAILED_MEAS), |_| None),
26 ))
27 .parse_complete(i)
28}
29
30#[inline]
31fn data_meas_csv_nom<'a>(
32 i: LocatedSpan<'a>,
33 data_prefix: Option<&str>,
34) -> IResult<LocatedSpan<'a>, HashMap<String, Vec<Option<f64>>>> {
35 map(
36 (
37 take_until(BEGIN_TITLE),
38 take_until("\n"),
39 space_newline,
40 separated_list1((space, char(','), space), map(name_str, |(s, _)| s)),
41 opt(char('#')),
42 opt((space, char(','))),
43 many1(delimited(
44 space_newline,
45 separated_list1((space, char(','), space), float),
46 opt((space, char(','))),
47 )),
48 ),
49 |(_, _, _, names, _, _, value_table): (_, _, _, Vec<&str>, _, _, Vec<Vec<Option<f64>>>)| {
50 names
51 .into_iter()
52 .enumerate()
53 .filter_map(|(name_idx, name)| {
54 if let Some(prefix) = data_prefix {
55 if !name.starts_with(prefix) {
56 return None;
57 }
58 }
59 Some((
60 name.to_owned(),
61 value_table.iter().map(|values| values[name_idx]).collect(),
62 ))
63 })
64 .collect()
65 },
66 )
67 .parse_complete(i)
68}
69
70#[inline]
71pub async fn data_meas_csv(
72 path: PathBuf,
73 data_prefix: Option<&str>,
74) -> Result<HashMap<String, Vec<Option<f64>>>, ()> {
75 match read_to_string(&path).await {
76 Ok(s) => {
77 let (_, out) = data_meas_csv_nom(s.as_str().into(), data_prefix).map_err(|e| {
78 let err: ParseError = e.into();
79 err.report(&mut true, &crate::FileId::Include { path }, &s);
80 })?;
81 Ok(out)
82 }
83 Err(e) => {
84 let err: ParseError = e.into();
85 err.report(&mut true, &crate::FileId::Include { path }, "");
86 Err(())
87 }
88 }
89}
90
91#[tokio::test]
92async fn sim_mt0_csv() {
93 crate::utlis::test::init_logger();
94 const DATA: &str = include_str!("../../tests/sim.mt0.csv");
95 _ = dbg!(data_meas_csv_nom(DATA.into(), None));
96 _ = dbg!(
97 data_meas_csv("tests/sim.mt0.csv".into(), Some("kcell"))
98 .await
99 .unwrap()
100 );
101}