use crate::{AdjacencyList, Atom, Bond};
use core::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SmilesParseError {
NotImplemented,
ParseError(String),
}
impl fmt::Display for SmilesParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotImplemented => f.write_str("SMILES parser is not implemented yet"),
Self::ParseError(message) => f.write_str(message),
}
}
}
impl std::error::Error for SmilesParseError {}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Molecule {
pub atoms: Vec<Atom>,
pub bonds: Vec<Bond>,
pub adjacency: Option<AdjacencyList>,
}
impl Molecule {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn add_atom(&mut self, atom: Atom) -> usize {
let index = self.atoms.len();
let mut atom = atom;
atom.index = index;
self.atoms.push(atom);
self.adjacency = None;
index
}
pub fn add_bond(&mut self, bond: Bond) -> usize {
let index = self.bonds.len();
let mut bond = bond;
bond.index = index;
self.bonds.push(bond);
self.adjacency = None;
index
}
pub fn rebuild_adjacency(&mut self) {
self.adjacency = Some(AdjacencyList::from_topology(self.atoms.len(), &self.bonds));
}
pub fn from_smiles(smiles: &str) -> Result<Self, SmilesParseError> {
crate::smiles::parse_smiles(smiles)
}
#[must_use]
pub fn atomic_numbers(&self) -> Vec<u8> {
self.atoms.iter().map(|atom| atom.atomic_num).collect()
}
}