use crate::descriptor::Descriptor;
use crate::error::MordredError;
use crate::molecule::Molecule;
pub struct AtomCount;
impl Descriptor for AtomCount {
fn name(&self) -> &str {
"nAtom"
}
fn description(&self) -> &str {
"Total atom count (including implicit H)"
}
fn calculate(&self, mol: &Molecule) -> Result<f64, MordredError> {
Ok(mol.total_atom_count() as f64)
}
}
pub struct HeavyAtomCount;
impl Descriptor for HeavyAtomCount {
fn name(&self) -> &str {
"nHeavyAtom"
}
fn description(&self) -> &str {
"Heavy atom count (non-hydrogen)"
}
fn calculate(&self, mol: &Molecule) -> Result<f64, MordredError> {
Ok(mol.heavy_atom_count() as f64)
}
}
pub struct BondCount;
impl Descriptor for BondCount {
fn name(&self) -> &str {
"nBond"
}
fn description(&self) -> &str {
"Bond count (between explicit atoms)"
}
fn calculate(&self, mol: &Molecule) -> Result<f64, MordredError> {
Ok(mol.bond_count() as f64)
}
}
pub struct MolecularWeight;
impl Descriptor for MolecularWeight {
fn name(&self) -> &str {
"MW"
}
fn description(&self) -> &str {
"Molecular weight (average isotope)"
}
fn calculate(&self, mol: &Molecule) -> Result<f64, MordredError> {
Ok(mol.molecular_weight())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::molecule::parse_smiles;
#[test]
fn test_methane_atom_count() {
let mol = parse_smiles("C").unwrap();
assert_eq!(AtomCount.calculate(&mol).unwrap(), 5.0); }
#[test]
fn test_methane_heavy_atom_count() {
let mol = parse_smiles("C").unwrap();
assert_eq!(HeavyAtomCount.calculate(&mol).unwrap(), 1.0);
}
#[test]
fn test_ethanol_bond_count() {
let mol = parse_smiles("CCO").unwrap();
assert_eq!(BondCount.calculate(&mol).unwrap(), 2.0);
}
#[test]
fn test_methane_mw() {
let mol = parse_smiles("C").unwrap();
let mw = MolecularWeight.calculate(&mol).unwrap();
assert!((mw - 16.043).abs() < 0.01);
}
#[test]
fn test_water_mw() {
let mol = parse_smiles("O").unwrap();
let mw = MolecularWeight.calculate(&mol).unwrap();
assert!((mw - 18.015).abs() < 0.01);
}
}