use omgkit_core::ChiralTag;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AtomPrim {
Any,
Aromatic,
Aliphatic,
Element {
z: u8,
aromatic: Option<bool>,
},
Degree(u32),
TotalDegree(u32),
TotalHs(u32),
ImplicitHs(u32),
RingCount(Option<u32>),
RingSize(Option<u32>),
RingBondCount(Option<u32>),
Valence(u32),
Charge(i32),
Isotope(u16),
AtomMap(u16),
Chirality(ChiralTag),
Recursive(Box<super::QueryMol>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AtomExpr {
Prim(AtomPrim),
Not(Box<AtomExpr>),
And(Vec<AtomExpr>),
Or(Vec<AtomExpr>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BondPrim {
Any,
Single,
Double,
Triple,
Quadruple,
Aromatic,
InRing,
UpRight,
DownRight,
Dative,
DativeReversed,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BondExpr {
Prim(BondPrim),
Not(Box<BondExpr>),
And(Vec<BondExpr>),
Or(Vec<BondExpr>),
}
impl BondExpr {
#[must_use]
pub fn default_bond() -> Self {
Self::Or(vec![
Self::Prim(BondPrim::Single),
Self::Prim(BondPrim::Aromatic),
])
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn expressions_compare_structurally() {
let c = AtomExpr::Prim(AtomPrim::Element {
z: 6,
aromatic: Some(false),
});
let n = AtomExpr::Prim(AtomPrim::Element {
z: 7,
aromatic: Some(false),
});
assert_eq!(c.clone(), c.clone());
assert_ne!(c.clone(), n.clone());
assert_ne!(
AtomExpr::And(vec![c.clone(), n.clone()]),
AtomExpr::Or(vec![c.clone(), n.clone()]),
);
assert_ne!(
AtomExpr::And(vec![c.clone(), n.clone()]),
AtomExpr::And(vec![n, c]),
"顺序不同即不同 —— 归一化是另一回事,不能在这里悄悄发生"
);
}
#[test]
fn default_bond_is_single_or_aromatic() {
assert_eq!(
BondExpr::default_bond(),
BondExpr::Or(vec![
BondExpr::Prim(BondPrim::Single),
BondExpr::Prim(BondPrim::Aromatic),
])
);
}
}