feos_core/parameter/
identifier.rs1use serde::{Deserialize, Serialize};
2use std::hash::{Hash, Hasher};
3
4#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
6#[cfg_attr(feature = "python", pyo3::pyclass(eq))]
7pub enum IdentifierOption {
8 Cas,
9 Name,
10 IupacName,
11 Smiles,
12 Inchi,
13 Formula,
14}
15
16#[derive(Serialize, Deserialize, Debug, Clone, Default)]
18pub struct Identifier {
19 #[serde(default)]
21 #[serde(skip_serializing_if = "Option::is_none")]
22 pub cas: Option<String>,
23 #[serde(default)]
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub name: Option<String>,
27 #[serde(default)]
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub iupac_name: Option<String>,
31 #[serde(default)]
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub smiles: Option<String>,
35 #[serde(default)]
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub inchi: Option<String>,
39 #[serde(default)]
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub formula: Option<String>,
43}
44
45impl Identifier {
46 pub fn new(
61 cas: Option<&str>,
62 name: Option<&str>,
63 iupac_name: Option<&str>,
64 smiles: Option<&str>,
65 inchi: Option<&str>,
66 formula: Option<&str>,
67 ) -> Identifier {
68 Identifier {
69 cas: cas.map(Into::into),
70 name: name.map(Into::into),
71 iupac_name: iupac_name.map(Into::into),
72 smiles: smiles.map(Into::into),
73 inchi: inchi.map(Into::into),
74 formula: formula.map(Into::into),
75 }
76 }
77
78 pub fn as_string(&self, option: IdentifierOption) -> Option<String> {
79 match option {
80 IdentifierOption::Cas => self.cas.clone(),
81 IdentifierOption::Name => self.name.clone(),
82 IdentifierOption::IupacName => self.iupac_name.clone(),
83 IdentifierOption::Smiles => self.smiles.clone(),
84 IdentifierOption::Inchi => self.inchi.clone(),
85 IdentifierOption::Formula => self.formula.clone(),
86 }
87 }
88}
89
90impl std::fmt::Display for Identifier {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 let mut ids = Vec::new();
93 if let Some(n) = &self.cas {
94 ids.push(format!("cas={}", n));
95 }
96 if let Some(n) = &self.name {
97 ids.push(format!("name={}", n));
98 }
99 if let Some(n) = &self.iupac_name {
100 ids.push(format!("iupac_name={}", n));
101 }
102 if let Some(n) = &self.smiles {
103 ids.push(format!("smiles={}", n));
104 }
105 if let Some(n) = &self.inchi {
106 ids.push(format!("inchi={}", n));
107 }
108 if let Some(n) = &self.formula {
109 ids.push(format!("formula={}", n));
110 }
111 write!(f, "Identifier({})", ids.join(", "))
112 }
113}
114
115impl PartialEq for Identifier {
116 fn eq(&self, other: &Self) -> bool {
117 self.cas == other.cas
118 }
119}
120impl Eq for Identifier {}
121
122impl Hash for Identifier {
123 fn hash<H: Hasher>(&self, state: &mut H) {
124 self.cas.hash(state);
125 }
126}
127
128#[cfg(test)]
129mod test {
130 use super::*;
131
132 #[test]
133 fn test_fmt() {
134 let id = Identifier::new(None, Some("acetone"), None, Some("CC(=O)C"), None, None);
135 assert_eq!(id.to_string(), "Identifier(name=acetone, smiles=CC(=O)C)");
136 }
137}