use serde::{Deserialize, Serialize};
use std::hash::{Hash, Hasher};
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
#[cfg_attr(feature = "python", pyo3::pyclass)]
pub enum IdentifierOption {
Cas,
Name,
IupacName,
Smiles,
Inchi,
Formula,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Identifier {
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub cas: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub iupac_name: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub smiles: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub inchi: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub formula: Option<String>,
}
impl Identifier {
pub fn new(
cas: Option<&str>,
name: Option<&str>,
iupac_name: Option<&str>,
smiles: Option<&str>,
inchi: Option<&str>,
formula: Option<&str>,
) -> Identifier {
Identifier {
cas: cas.map(Into::into),
name: name.map(Into::into),
iupac_name: iupac_name.map(Into::into),
smiles: smiles.map(Into::into),
inchi: inchi.map(Into::into),
formula: formula.map(Into::into),
}
}
pub fn as_string(&self, option: IdentifierOption) -> Option<String> {
match option {
IdentifierOption::Cas => self.cas.clone(),
IdentifierOption::Name => self.name.clone(),
IdentifierOption::IupacName => self.iupac_name.clone(),
IdentifierOption::Smiles => self.smiles.clone(),
IdentifierOption::Inchi => self.inchi.clone(),
IdentifierOption::Formula => self.formula.clone(),
}
}
}
impl std::fmt::Display for Identifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut ids = Vec::new();
if let Some(n) = &self.cas {
ids.push(format!("cas={}", n));
}
if let Some(n) = &self.name {
ids.push(format!("name={}", n));
}
if let Some(n) = &self.iupac_name {
ids.push(format!("iupac_name={}", n));
}
if let Some(n) = &self.smiles {
ids.push(format!("smiles={}", n));
}
if let Some(n) = &self.inchi {
ids.push(format!("inchi={}", n));
}
if let Some(n) = &self.formula {
ids.push(format!("formula={}", n));
}
write!(f, "Identifier({})", ids.join(", "))
}
}
impl PartialEq for Identifier {
fn eq(&self, other: &Self) -> bool {
self.cas == other.cas
}
}
impl Eq for Identifier {}
impl Hash for Identifier {
fn hash<H: Hasher>(&self, state: &mut H) {
self.cas.hash(state);
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_fmt() {
let id = Identifier::new(None, Some("acetone"), None, Some("CC(=O)C"), None, None);
assert_eq!(id.to_string(), "Identifier(name=acetone, smiles=CC(=O)C)");
}
}