1use std::cmp::Ordering;
2
3#[derive(Debug)]
4pub enum BondError {
5 InvalidBondChar(char),
6 AtomBondedToSelf,
7}
8
9#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
10pub enum BondType {
11 #[default]
12 Default,
13 Single,
14 Up,
15 Down,
16 Delocalized,
17 Double,
18 Triple,
19 Quadruple,
20 Dative,
21}
22
23impl TryFrom<char> for BondType {
24 type Error = BondError;
25
26 fn try_from(value: char) -> Result<Self, Self::Error> {
27 match value {
28 ' ' => Ok(BondType::Default),
29 '-' => Ok(BondType::Single),
30 '/' => Ok(BondType::Up),
31 '\\' => Ok(BondType::Down),
32 ':' => Ok(BondType::Delocalized),
33 '=' => Ok(BondType::Double),
34 '#' => Ok(BondType::Triple),
35 '$' => Ok(BondType::Quadruple),
36 _ => Err(BondError::InvalidBondChar(value)),
37 }
38 }
39}
40
41impl From<BondType> for char {
42 fn from(value: BondType) -> Self {
43 match value {
44 BondType::Default => ' ',
45 BondType::Single => '-',
46 BondType::Up => '/',
47 BondType::Down => '\\',
48 BondType::Delocalized => ':',
49 BondType::Double => '=',
50 BondType::Triple => '#',
51 BondType::Quadruple => '$',
52 BondType::Dative => unimplemented!(),
53 }
54 }
55}
56
57impl From<&BondType> for char {
58 fn from(value: &BondType) -> Self {
59 match value {
60 BondType::Default => ' ',
61 BondType::Single => '-',
62 BondType::Up => '/',
63 BondType::Down => '\\',
64 BondType::Delocalized => ':',
65 BondType::Double => '=',
66 BondType::Triple => '#',
67 BondType::Quadruple => '$',
68 BondType::Dative => unimplemented!(),
69 }
70 }
71}
72
73impl From<BondType> for f64 {
74 fn from(value: BondType) -> Self {
75 match value {
76 BondType::Default => 1.0,
77 BondType::Single => 1.0,
78 BondType::Up => 1.0,
79 BondType::Down => 1.0,
80 BondType::Delocalized => 1.5,
81 BondType::Double => 2.0,
82 BondType::Triple => 3.0,
83 BondType::Quadruple => 4.0,
84 BondType::Dative => unimplemented!(),
85 }
86 }
87}
88
89impl From<&BondType> for f64 {
90 fn from(value: &BondType) -> Self {
91 match value {
92 BondType::Default => 1.0,
93 BondType::Single => 1.0,
94 BondType::Up => 1.0,
95 BondType::Down => 1.0,
96 BondType::Delocalized => 1.5,
97 BondType::Double => 2.0,
98 BondType::Triple => 3.0,
99 BondType::Quadruple => 4.0,
100 BondType::Dative => unimplemented!(),
101 }
102 }
103}
104
105#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
106pub struct Bond {
107 pub i: usize,
108 pub j: usize,
109 pub bond_type: BondType,
110}
111
112impl Bond {
113 pub fn new(i: usize, j: usize, bond_type: char) -> Result<Bond, BondError> {
114 let bond_type = BondType::try_from(bond_type)?;
115 match i.cmp(&j) {
116 Ordering::Greater => Ok(Bond { j, i, bond_type }),
117 Ordering::Less => Ok(Bond { i, j, bond_type }),
118 Ordering::Equal => Err(BondError::AtomBondedToSelf),
119 }
120 }
121}