1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum BondOrder {
6 Single,
8 Double,
10 Triple,
12 Quadruple,
14 Aromatic,
16 Up,
18 Down,
20 Zero,
22 Dative,
24 QueryAny,
26 QuerySingleOrDouble,
28 QuerySingleOrAromatic,
30 QueryDoubleOrAromatic,
32}
33
34impl BondOrder {
35 pub fn order_value(self) -> Option<f32> {
37 match self {
38 Self::Single => Some(1.0),
39 Self::Double => Some(2.0),
40 Self::Triple => Some(3.0),
41 Self::Quadruple => Some(4.0),
42 Self::Zero => Some(0.0),
43 Self::Dative => Some(1.0),
44 Self::Aromatic => None,
45 Self::Up | Self::Down => Some(1.0),
46 Self::QueryAny
47 | Self::QuerySingleOrDouble
48 | Self::QuerySingleOrAromatic
49 | Self::QueryDoubleOrAromatic => None,
50 }
51 }
52
53 pub fn order_int(self) -> u8 {
56 match self {
57 Self::Zero => 0,
58 Self::Single
59 | Self::Up
60 | Self::Down
61 | Self::Aromatic
62 | Self::Dative
63 | Self::QueryAny
64 | Self::QuerySingleOrDouble
65 | Self::QuerySingleOrAromatic
66 | Self::QueryDoubleOrAromatic => 1,
67 Self::Double => 2,
68 Self::Triple => 3,
69 Self::Quadruple => 4,
70 }
71 }
72
73 pub fn smiles_token(self) -> &'static str {
75 match self {
76 Self::Single => "-",
77 Self::Double => "=",
78 Self::Triple => "#",
79 Self::Quadruple => "$",
80 Self::Aromatic => ":",
81 Self::Up => "/",
82 Self::Down => "\\",
83 Self::Dative => "->",
84 Self::Zero | Self::QueryAny => "~",
85 Self::QuerySingleOrDouble
86 | Self::QuerySingleOrAromatic
87 | Self::QueryDoubleOrAromatic => "~",
88 }
89 }
90
91 pub fn smiles_char(self) -> char {
93 self.smiles_token().as_bytes()[0] as char
94 }
95}
96
97impl core::fmt::Display for BondOrder {
98 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
99 write!(f, "{}", self.smiles_token())
100 }
101}
102
103#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct BondEntry {
108 pub atom1: crate::molecule::AtomIdx,
109 pub atom2: crate::molecule::AtomIdx,
110 pub order: BondOrder,
111}
112
113impl BondEntry {
114 pub fn other(&self, idx: crate::molecule::AtomIdx) -> Option<crate::molecule::AtomIdx> {
116 if self.atom1 == idx {
117 Some(self.atom2)
118 } else if self.atom2 == idx {
119 Some(self.atom1)
120 } else {
121 None
122 }
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129 use crate::molecule::AtomIdx;
130
131 #[test]
132 fn test_bond_order_values() {
133 assert_eq!(BondOrder::Single.order_value(), Some(1.0));
134 assert_eq!(BondOrder::Double.order_value(), Some(2.0));
135 assert_eq!(BondOrder::Triple.order_value(), Some(3.0));
136 assert_eq!(BondOrder::Aromatic.order_value(), None);
137 }
138
139 #[test]
140 fn test_bond_other() {
141 let b = BondEntry {
142 atom1: AtomIdx(0),
143 atom2: AtomIdx(1),
144 order: BondOrder::Single,
145 };
146 assert_eq!(b.other(AtomIdx(0)), Some(AtomIdx(1)));
147 assert_eq!(b.other(AtomIdx(1)), Some(AtomIdx(0)));
148 assert_eq!(b.other(AtomIdx(2)), None);
149 }
150}