gchemol_core/bond.rs
1// imports
2
3// [[file:~/Workspace/Programming/gchemol-rs/gchemol-core/gchemol-core.note::*imports][imports:1]]
4use serde::*;
5
6use crate::property::PropertyStore;
7// imports:1 ends here
8
9// core
10
11// [[file:~/Workspace/Programming/gchemol-rs/gchemol-core/gchemol-core.note::*core][core:1]]
12/// https://en.wikipedia.org/wiki/Bond_order
13#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Deserialize, Serialize)]
14pub enum BondKind {
15 /// dummy bond
16 Dummy,
17 /// partial bond
18 Partial,
19 /// single bond
20 Single,
21 /// aromatic bond
22 Aromatic,
23 /// double bond,
24 Double,
25 /// triple bond
26 Triple,
27 /// quadruple bond
28 Quadruple,
29}
30
31/// There is a chemical bond between two atoms or groups of atoms in the case
32/// that the forces acting between them are such as to lead to the formation of
33/// an aggregate with sufficient stability to make it convenient for the chemist
34/// to consider it as an independent 'molecular species'.
35///
36/// # Reference
37/// https://goldbook.iupac.org/html/B/B00697.html
38///
39#[derive(Debug, Clone, Deserialize, Serialize)]
40pub struct Bond {
41 /// Arbitrary property stored in key-value pair. Key is a string type, but
42 /// it is the responsibility of the user to correctly interpret the value.
43 pub properties: PropertyStore,
44
45 /// bond type
46 kind: BondKind,
47
48 /// bond label
49 label: String,
50
51 /// set this attribute for arbitrary bond order
52 order: Option<f64>,
53}
54// core:1 ends here
55
56// constructors
57
58// [[file:~/Workspace/Programming/gchemol-rs/gchemol-core/gchemol-core.note::*constructors][constructors:1]]
59/// default `Bond` constructor
60impl Default for Bond {
61 fn default() -> Self {
62 Bond {
63 kind: BondKind::Single,
64 label: String::new(),
65 order: None,
66 properties: PropertyStore::default(),
67 }
68 }
69}
70
71/// `Bond` constructors
72impl Bond {
73 /// Create a single bond
74 pub fn single() -> Self {
75 Bond {
76 kind: BondKind::Single,
77 ..Default::default()
78 }
79 }
80
81 /// Create a double bond
82 pub fn double() -> Self {
83 Bond {
84 kind: BondKind::Double,
85 ..Default::default()
86 }
87 }
88
89 /// Create a triple bond
90 pub fn triple() -> Self {
91 Bond {
92 kind: BondKind::Triple,
93 ..Default::default()
94 }
95 }
96
97 /// Create an aromatic bond
98 pub fn aromatic() -> Self {
99 Bond {
100 kind: BondKind::Aromatic,
101 ..Default::default()
102 }
103 }
104
105 /// Create a weak bond
106 pub fn partial() -> Self {
107 Bond {
108 kind: BondKind::Partial,
109 ..Default::default()
110 }
111 }
112
113 /// Create a quadruple bond
114 pub fn quadruple() -> Self {
115 Bond {
116 kind: BondKind::Quadruple,
117 ..Default::default()
118 }
119 }
120
121 /// Create a dummy bond
122 pub fn dummy() -> Self {
123 Bond {
124 kind: BondKind::Dummy,
125 ..Default::default()
126 }
127 }
128}
129// constructors:1 ends here
130
131// base
132
133// [[file:~/Workspace/Programming/gchemol-rs/gchemol-core/gchemol-core.note::*base][base:1]]
134/// Basic methods for `Bond`
135impl Bond {
136 /// Returns bond kind/type.
137 pub fn kind(&self) -> BondKind {
138 self.kind
139 }
140
141 /// Change bond kind/type.
142 pub fn set_kind(&mut self, k: BondKind) {
143 self.kind = k;
144 }
145
146 /// Change current bond order to `o`.
147 pub fn set_order(&mut self, o: f64) {
148 debug_assert!(o >= 0.0);
149 self.order = Some(o);
150 }
151
152 /// Change bond label.
153 pub fn set_label<T: Into<String>>(&mut self, l: T) {
154 self.label = l.into();
155 }
156
157 /// Returns bond label.
158 pub fn label(&self) -> &str {
159 &self.label
160 }
161
162 /// Return true if `Bond` is a dummy bond.
163 pub fn is_dummy(&self) -> bool {
164 self.kind == BondKind::Dummy
165 }
166
167 /// Return true if `Bond` is a single bond.
168 pub fn is_single(&self) -> bool {
169 self.kind == BondKind::Single
170 }
171
172 /// Return true if `Bond` is a double bond.
173 pub fn is_double(&self) -> bool {
174 self.kind == BondKind::Double
175 }
176
177 /// Return bond order
178 pub fn order(&self) -> f64 {
179 if let Some(order) = self.order {
180 order
181 } else {
182 match self.kind {
183 BondKind::Dummy => 0.0,
184 BondKind::Partial => 0.5,
185 BondKind::Single => 1.0,
186 BondKind::Aromatic => 1.5,
187 BondKind::Double => 2.0,
188 BondKind::Triple => 3.0,
189 BondKind::Quadruple => 4.0,
190 }
191 }
192 }
193}
194// base:1 ends here
195
196// test
197
198// [[file:~/Workspace/Programming/gchemol-rs/gchemol-core/gchemol-core.note::*test][test:1]]
199#[test]
200fn test_bond() {
201 let b = Bond::default();
202 assert_eq!(1.0, b.order());
203 assert_eq!(1.0, Bond::single().order());
204 assert_eq!(2.0, Bond::double().order());
205 assert_eq!(3.0, Bond::triple().order());
206}
207// test:1 ends here