use crate::mol::atom::Element;
#[derive(Debug, Clone, PartialEq)]
pub enum AtomPrimitive {
Any,
AtomicNum(u8),
ElementAliphatic(Element),
ElementAromatic(Element),
Aromatic,
Aliphatic,
HCount(u8),
Charge(i8),
Ring(Option<usize>),
NotInRing,
Degree(u8),
}
#[derive(Debug, Clone, PartialEq)]
pub enum AtomExpr {
Primitive(AtomPrimitive),
Not(Box<AtomExpr>),
And(Box<AtomExpr>, Box<AtomExpr>),
Or(Box<AtomExpr>, Box<AtomExpr>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum SmartsBond {
Single,
Double,
Triple,
Aromatic,
Any,
Unspecified,
}
#[derive(Debug, Clone)]
pub struct SmartsAtom {
pub expr: AtomExpr,
}
#[derive(Debug, Clone, Default)]
pub struct SmartsPattern {
pub atoms: Vec<SmartsAtom>,
pub edges: Vec<(usize, usize, SmartsBond)>,
}
impl SmartsPattern {
pub fn new() -> Self {
Self::default()
}
pub fn num_atoms(&self) -> usize {
self.atoms.len()
}
pub fn neighbors(&self, idx: usize) -> impl Iterator<Item = (usize, &SmartsBond)> {
self.edges.iter().filter_map(move |(a, b, bond)| {
if *a == idx {
Some((*b, bond))
} else if *b == idx {
Some((*a, bond))
} else {
None
}
})
}
}