#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PreselectCheck {
pub abs_meas_idx: usize,
pub expected: bool,
}
#[derive(Debug, Clone)]
pub struct PreselectSchedule {
pub checks: Vec<PreselectCheck>,
}
impl PreselectSchedule {
pub fn is_empty(&self) -> bool {
self.checks.is_empty()
}
}
pub fn extract_preselect_schedule(stim_text: &str) -> PreselectSchedule {
let mut checks = Vec::new();
for line in stim_text.lines() {
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
if let Some(rest) = trimmed.strip_prefix("#!preselect_expect") {
let rest = rest.trim();
let mut parts = rest.split_whitespace();
let abs_idx: usize = parts.next().and_then(|s| s.parse().ok()).unwrap_or_else(|| {
panic!(
"#!preselect_expect directive has invalid abs_meas_idx: {rest}\n\
Expected: #!preselect_expect <abs_idx> <0|1>"
)
});
let expected_int: u8 = parts.next().and_then(|s| s.parse().ok()).unwrap_or_else(|| {
panic!(
"#!preselect_expect directive has invalid expected value: {rest}\n\
Expected: #!preselect_expect <abs_idx> <0|1>"
)
});
checks.push(PreselectCheck {
abs_meas_idx: abs_idx,
expected: expected_int != 0,
});
}
}
PreselectSchedule { checks }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_input() {
let schedule = extract_preselect_schedule("");
assert!(schedule.is_empty());
}
#[test]
fn no_preselect_directives() {
let schedule = extract_preselect_schedule("H 0\nM 0\n#!delay 0.5\n");
assert!(schedule.is_empty());
}
#[test]
fn single_check() {
let schedule = extract_preselect_schedule("M 0\n#!preselect_expect 0 0\n");
assert_eq!(schedule.checks.len(), 1);
assert_eq!(
schedule.checks[0],
PreselectCheck {
abs_meas_idx: 0,
expected: false,
}
);
}
#[test]
fn multiple_checks_with_begin() {
let text = "\
R 0 1\n\
#!preselect_begin\n\
H 0\n\
M 0\n\
#!preselect_expect 0 0\n\
H 1\n\
M 1\n\
#!preselect_expect 1 1\n\
";
let schedule = extract_preselect_schedule(text);
assert_eq!(schedule.checks.len(), 2);
assert_eq!(schedule.checks[0].abs_meas_idx, 0);
assert!(!schedule.checks[0].expected);
assert_eq!(schedule.checks[1].abs_meas_idx, 1);
assert!(schedule.checks[1].expected);
}
}