use std::collections::HashMap;
use crate::io::smiles::chem::ast::{Chain, ChainElement, SmilesIR, Span};
use crate::io::smiles::error::{SmilesError, SmilesErrorKind};
pub(crate) fn validate_ring_closures(mol: &SmilesIR, input: &str) -> Result<(), SmilesError> {
let mut open: HashMap<u16, Span> = HashMap::new();
for component in &mol.components {
collect_ring_closures(component, &mut open);
}
if let Some((&rnum, &span)) = open.iter().next() {
return Err(SmilesError::new(
SmilesErrorKind::UnmatchedRingClosure(rnum),
span,
input,
));
}
Ok(())
}
fn collect_ring_closures(chain: &Chain, open: &mut HashMap<u16, Span>) {
for elem in &chain.tail {
match elem {
ChainElement::RingClosure { rnum, span, .. } => {
if open.remove(rnum).is_none() {
open.insert(*rnum, *span);
}
}
ChainElement::Branch { chain, .. } => {
collect_ring_closures(chain, open);
}
ChainElement::BondedAtom { .. } => {}
}
}
}