Skip to main content

use_compound/
compound_identifier.rs

1use std::fmt;
2
3use crate::{CompoundRegistry, CompoundValidationError};
4
5/// A lightweight compound registry identifier.
6#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
7pub struct CompoundIdentifier {
8    registry: CompoundRegistry,
9    value: String,
10}
11
12impl CompoundIdentifier {
13    /// Creates a CAS Registry Number identifier.
14    ///
15    /// # Errors
16    ///
17    /// Returns [`CompoundValidationError::EmptyIdentifierValue`] when `value` is empty after trimming.
18    pub fn cas_number(value: &str) -> Result<Self, CompoundValidationError> {
19        Self::new(CompoundRegistry::CasNumber, value)
20    }
21
22    /// Creates a PubChem CID identifier.
23    ///
24    /// # Errors
25    ///
26    /// Returns [`CompoundValidationError::EmptyIdentifierValue`] when `value` is empty after trimming.
27    pub fn pub_chem_cid(value: &str) -> Result<Self, CompoundValidationError> {
28        Self::new(CompoundRegistry::PubChemCid, value)
29    }
30
31    /// Creates an InChI identifier.
32    ///
33    /// # Errors
34    ///
35    /// Returns [`CompoundValidationError::EmptyIdentifierValue`] when `value` is empty after trimming.
36    pub fn inchi(value: &str) -> Result<Self, CompoundValidationError> {
37        Self::new(CompoundRegistry::Inchi, value)
38    }
39
40    /// Creates an InChIKey identifier.
41    ///
42    /// # Errors
43    ///
44    /// Returns [`CompoundValidationError::EmptyIdentifierValue`] when `value` is empty after trimming.
45    pub fn inchi_key(value: &str) -> Result<Self, CompoundValidationError> {
46        Self::new(CompoundRegistry::InchiKey, value)
47    }
48
49    /// Creates a SMILES identifier.
50    ///
51    /// # Errors
52    ///
53    /// Returns [`CompoundValidationError::EmptyIdentifierValue`] when `value` is empty after trimming.
54    pub fn smiles(value: &str) -> Result<Self, CompoundValidationError> {
55        Self::new(CompoundRegistry::Smiles, value)
56    }
57
58    /// Creates a custom registry identifier.
59    ///
60    /// # Errors
61    ///
62    /// Returns [`CompoundValidationError::EmptyIdentifierNamespace`] when `namespace` is empty after
63    /// trimming, or [`CompoundValidationError::EmptyIdentifierValue`] when `value` is empty after trimming.
64    pub fn custom(namespace: &str, value: &str) -> Result<Self, CompoundValidationError> {
65        let trimmed_namespace = namespace.trim();
66        if trimmed_namespace.is_empty() {
67            return Err(CompoundValidationError::EmptyIdentifierNamespace);
68        }
69
70        Self::new(
71            CompoundRegistry::Custom(trimmed_namespace.to_owned()),
72            value,
73        )
74    }
75
76    /// Creates an identifier from a registry and value.
77    ///
78    /// # Errors
79    ///
80    /// Returns [`CompoundValidationError::EmptyIdentifierValue`] when `value` is empty after trimming.
81    pub fn new(registry: CompoundRegistry, value: &str) -> Result<Self, CompoundValidationError> {
82        let trimmed_value = value.trim();
83        if trimmed_value.is_empty() {
84            Err(CompoundValidationError::EmptyIdentifierValue)
85        } else {
86            Ok(Self {
87                registry,
88                value: trimmed_value.to_owned(),
89            })
90        }
91    }
92
93    /// Returns the registry namespace.
94    #[must_use]
95    pub const fn registry(&self) -> &CompoundRegistry {
96        &self.registry
97    }
98
99    /// Returns the identifier value.
100    #[must_use]
101    pub fn value(&self) -> &str {
102        &self.value
103    }
104}
105
106impl fmt::Display for CompoundIdentifier {
107    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
108        write!(formatter, "{}:{}", self.registry, self.value)
109    }
110}