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