chem_name_resolver/
lib.rs1pub mod dict;
2pub mod normalizer;
3pub mod parser;
4mod error;
5
6#[cfg(feature = "wasm")]
7mod wasm;
8
9#[cfg(feature = "python")]
10mod py;
11
12pub use error::ResolveError;
13pub use parser::MolGraph;
14
15use std::borrow::Cow;
16
17#[derive(Debug, Clone, PartialEq, serde::Serialize)]
18pub enum ResolveSource {
19 Dictionary,
20 Parser,
21}
22
23#[derive(Debug, Clone, serde::Serialize)]
24pub struct ResolveResult {
25 pub smiles: String,
26 pub canonical_name: String,
27 pub source: ResolveSource,
28 pub molecular_formula: Option<String>,
31 pub molecular_weight: Option<f64>,
34}
35
36pub fn resolve(name: &str) -> Result<ResolveResult, ResolveError> {
40 let normalized = normalizer::normalize_lowercase(name);
41
42 if let Some(entry) = dict::lookup_synonym(&normalized) {
43 match entry {
44 dict::DictEntry::CanonicalName(canonical) => {
45 let graph = parser::parse_iupac(canonical)?;
46 let smiles = parser::smiles::to_smiles(&graph);
47 let molecular_formula = Some(parser::formula::molecular_formula(&graph));
48 let molecular_weight = Some(parser::formula::molecular_weight(&graph));
49 return Ok(ResolveResult {
50 smiles,
51 canonical_name: canonical.to_string(),
52 source: ResolveSource::Dictionary,
53 molecular_formula,
54 molecular_weight,
55 });
56 }
57 dict::DictEntry::DirectSmiles(smiles) => {
58 return Ok(ResolveResult {
59 smiles: smiles.to_string(),
60 canonical_name: normalized.clone(),
61 source: ResolveSource::Dictionary,
62 molecular_formula: None,
63 molecular_weight: None,
64 });
65 }
66 }
67 }
68
69 let graph = parser::parse_iupac(&normalized)?;
70 let smiles = parser::smiles::to_smiles(&graph);
71 let molecular_formula = Some(parser::formula::molecular_formula(&graph));
72 let molecular_weight = Some(parser::formula::molecular_weight(&graph));
73 Ok(ResolveResult {
74 smiles,
75 canonical_name: normalized,
76 source: ResolveSource::Parser,
77 molecular_formula,
78 molecular_weight,
79 })
80}
81
82pub fn resolve_batch(names: &[&str]) -> Vec<Result<ResolveResult, ResolveError>> {
84 names.iter().map(|&n| resolve(n)).collect()
85}
86
87pub fn normalize(name: &str) -> Cow<'_, str> {
89 normalizer::normalize(name)
90}
91
92pub fn lookup(name: &str) -> Option<dict::DictEntry<'static>> {
94 dict::lookup_synonym(name)
95}