use std::{convert, fmt};
use super::{Charge, Error};
#[derive(PartialEq, Debug, Clone)]
pub enum Element {
H,
He,
Li,
Be,
B,
C,
N,
O,
F,
Ne,
Na,
Mg,
Al,
Si,
P,
S,
Cl,
Ar,
K,
Ca,
Sc,
Ti,
V,
Cr,
Mn,
Fe,
Co,
Ni,
Cu,
Zn,
Ga,
Ge,
As,
Se,
Br,
Kr,
Rb,
Sr,
Y,
Zr,
Nb,
Mo,
Tc,
Ru,
Rh,
Pd,
Ag,
Cd,
In,
Sn,
Sb,
Te,
I,
Xe,
Cs,
Ba,
La,
Ce,
Pr,
Nd,
Pm,
Sm,
Eu,
Gd,
Tb,
Dy,
Ho,
Er,
Tm,
Yb,
Lu,
Hf,
Ta,
W,
Re,
Os,
Ir,
Pt,
Au,
Hg,
Tl,
Pb,
Bi,
Po,
At,
Rn,
Fr,
Ra,
Ac,
Th,
Pa,
U,
Np,
Pu,
Am,
Cm,
Bk,
Cf,
Es,
Fm,
Md,
No,
Lr,
}
impl fmt::Display for Element {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl convert::TryFrom<u16> for Element {
type Error = Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
match u32::try_from(value) {
Ok(value) => value.try_into(),
Err(_) => Err(Error::InvalidElement),
}
}
}
impl convert::TryFrom<u32> for Element {
type Error = Error;
fn try_from(value: u32) -> Result<Self, Self::Error> {
Ok(match value {
1 => Self::H,
2 => Self::He,
3 => Self::Li,
4 => Self::Be,
5 => Self::B,
6 => Self::C,
7 => Self::N,
8 => Self::O,
9 => Self::F,
10 => Self::Ne,
11 => Self::Na,
12 => Self::Mg,
13 => Self::Al,
14 => Self::Si,
15 => Self::P,
16 => Self::S,
17 => Self::Cl,
18 => Self::Ar,
19 => Self::K,
20 => Self::Ca,
21 => Self::Sc,
22 => Self::Ti,
23 => Self::V,
24 => Self::Cr,
25 => Self::Mn,
26 => Self::Fe,
27 => Self::Co,
28 => Self::Ni,
29 => Self::Cu,
30 => Self::Zn,
31 => Self::Ga,
32 => Self::Ge,
33 => Self::As,
34 => Self::Se,
35 => Self::Br,
36 => Self::Kr,
37 => Self::Rb,
38 => Self::Sr,
39 => Self::Y,
40 => Self::Zr,
41 => Self::Nb,
42 => Self::Mo,
43 => Self::Tc,
44 => Self::Ru,
45 => Self::Rh,
46 => Self::Pd,
47 => Self::Ag,
48 => Self::Cd,
49 => Self::In,
50 => Self::Sn,
51 => Self::Sb,
52 => Self::Te,
53 => Self::I,
54 => Self::Xe,
55 => Self::Cs,
56 => Self::Ba,
57 => Self::La,
58 => Self::Ce,
59 => Self::Pr,
60 => Self::Nd,
61 => Self::Pm,
62 => Self::Sm,
63 => Self::Eu,
64 => Self::Gd,
65 => Self::Tb,
66 => Self::Dy,
67 => Self::Ho,
68 => Self::Er,
69 => Self::Tm,
70 => Self::Yb,
71 => Self::Lu,
72 => Self::Hf,
73 => Self::Ta,
74 => Self::W,
75 => Self::Re,
76 => Self::Os,
77 => Self::Ir,
78 => Self::Pt,
79 => Self::Au,
80 => Self::Hg,
81 => Self::Tl,
82 => Self::Pb,
83 => Self::Bi,
84 => Self::Po,
85 => Self::At,
86 => Self::Rn,
87 => Self::Fr,
88 => Self::Ra,
89 => Self::Ac,
90 => Self::Tl,
91 => Self::Pa,
92 => Self::U,
93 => Self::Np,
94 => Self::Pu,
95 => Self::Am,
96 => Self::Cm,
97 => Self::Bk,
98 => Self::Cf,
99 => Self::Es,
100 => Self::Fm,
101 => Self::Md,
102 => Self::No,
103 => Self::Lr,
_ => return Err(Error::InvalidElement),
})
}
}
impl Element {
pub fn default_valences(&self) -> Option<&[usize]> {
match self {
Element::H => Some(&[1]),
Element::B => Some(&[3]),
Element::C => Some(&[4]),
Element::N => Some(&[3]),
Element::O => Some(&[2]),
Element::F => Some(&[1]),
Element::Si => Some(&[4]),
Element::P => Some(&[3, 5]),
Element::S => Some(&[2, 4, 6]),
Element::Cl => Some(&[1, 3, 5, 7]),
Element::As => Some(&[3, 5]),
Element::Se => Some(&[2, 4, 6]),
Element::Br => Some(&[1]),
Element::Te => Some(&[2, 4, 6]),
Element::I => Some(&[1, 3, 5, 7]),
Element::At => Some(&[1, 3, 5, 7]),
_ => None,
}
}
pub fn isoelectronic(&self, charge: &Charge) -> Option<Self> {
let effective_charge: i8 = charge.into();
match effective_charge {
-15 => match self {
Element::H => Some(Element::P),
Element::He => Some(Element::Ar),
_ => None,
},
-14 => match self {
Element::H => Some(Element::Si),
Element::He => Some(Element::P),
Element::B => Some(Element::Ar),
_ => None,
},
-13 => match self {
Element::B => Some(Element::Cl),
Element::C => Some(Element::Ar),
_ => None,
},
-12 => match self {
Element::B => Some(Element::S),
Element::C => Some(Element::Cl),
Element::N => Some(Element::Ar),
_ => None,
},
-11 => match self {
Element::B => Some(Element::P),
Element::C => Some(Element::S),
Element::N => Some(Element::Cl),
Element::O => Some(Element::Ar),
_ => None,
},
-10 => match self {
Element::B => Some(Element::Si),
Element::C => Some(Element::P),
Element::N => Some(Element::S),
Element::O => Some(Element::Cl),
Element::F => Some(Element::Ar),
_ => None,
},
-9 => match self {
Element::H => Some(Element::Ne),
_ => None,
},
-8 => match self {
Element::H => Some(Element::F),
Element::He => Some(Element::Ne),
Element::Ne => Some(Element::Cl),
_ => None,
},
-7 => match self {
Element::H => Some(Element::O),
Element::He => Some(Element::F),
Element::Ne => Some(Element::S),
_ => None,
},
-6 => match self {
Element::H => Some(Element::N),
Element::He => Some(Element::O),
Element::Ne => Some(Element::P),
_ => None,
},
-5 => match self {
Element::H => Some(Element::B),
Element::He => Some(Element::N),
Element::B => Some(Element::Ne),
Element::Ne => Some(Element::Si),
_ => None,
},
-4 => match self {
Element::H => Some(Element::B),
Element::He => Some(Element::C),
Element::B => Some(Element::F),
Element::C => Some(Element::Ne),
Element::N | Element::O | Element::F | Element::Ne => None,
Element::Si => Some(Element::Ar),
_ => None,
},
-3 => match self {
Element::H => Some(Element::C),
Element::He => Some(Element::B),
Element::B => Some(Element::O),
Element::C => Some(Element::F),
Element::N => Some(Element::Ne),
Element::O | Element::F | Element::Ne => None,
Element::Si => Some(Element::Cl),
Element::P => Some(Element::Ar),
Element::S | Element::Cl | Element::Ar => None,
Element::As => Some(Element::Kr),
Element::Se | &Element::Br | Element::Kr => None,
_ => None,
},
-2 => match self {
Element::H => Some(Element::B),
Element::He => None,
Element::B => Some(Element::N),
Element::C => Some(Element::O),
Element::N => Some(Element::F),
Element::O => Some(Element::Ne),
Element::F => None,
Element::Ne => None,
Element::Si => Some(Element::S),
Element::P => Some(Element::Cl),
Element::S => Some(Element::Ar),
Element::Cl => None,
Element::Ar => None,
Element::As => Some(Element::Br),
Element::Se => Some(Element::Kr),
Element::Br => None,
Element::Kr => None,
Element::Te => Some(Element::Xe),
_ => None,
},
-1 => match self {
Element::H => Some(Element::He),
Element::B => Some(Element::C),
Element::C => Some(Element::N),
Element::N => Some(Element::O),
Element::O => Some(Element::F),
Element::F => Some(Element::Ne),
Element::Al => Some(Element::Si),
Element::Si => Some(Element::P),
Element::P => Some(Element::S),
Element::S => Some(Element::Cl),
Element::Cl => Some(Element::Ar),
Element::As => Some(Element::Se),
Element::Se => Some(Element::Br),
Element::Br => Some(Element::Kr),
Element::Te => Some(Element::I),
Element::I => Some(Element::Xe),
Element::At => Some(Element::Rn),
_ => None,
},
0 => Some(self.clone()),
1 => match self {
Element::H => None,
Element::B => None,
Element::C => Some(Element::B),
Element::N => Some(Element::C),
Element::O => Some(Element::N),
Element::F => Some(Element::O),
Element::Ne => Some(Element::F),
Element::P => Some(Element::Si),
Element::S => Some(Element::P),
Element::Cl => Some(Element::S),
Element::Ar => Some(Element::Cl),
Element::Se => Some(Element::As),
Element::Br => Some(Element::Se),
Element::Kr => Some(Element::Br),
Element::I => Some(Element::Te),
Element::Xe => Some(Element::I),
Element::Rn => Some(Element::At),
_ => None,
},
2 => match self {
Element::N => Some(Element::B),
Element::O => Some(Element::C),
Element::F => Some(Element::N),
Element::Ne => Some(Element::O),
Element::S => Some(Element::Si),
Element::Cl => Some(Element::P),
Element::Ar => Some(Element::S),
Element::Br => Some(Element::As),
Element::Kr => Some(Element::Se),
Element::Xe => Some(Element::Te),
_ => None,
},
3 => match self {
Element::B => Some(Element::He),
Element::O => Some(Element::B),
Element::F => Some(Element::C),
Element::Ne => Some(Element::N),
Element::Cl => Some(Element::Si),
Element::Ar => Some(Element::P),
Element::Kr => Some(Element::As),
_ => None,
},
4 => match self {
Element::F => Some(Element::B),
Element::Ne => Some(Element::C),
Element::Ar => Some(Element::Si),
_ => None,
},
5 => match self {
Element::C => Some(Element::H),
Element::N => Some(Element::He),
Element::Ne => Some(Element::B),
Element::Si => Some(Element::F),
Element::P => Some(Element::Ne),
_ => None,
},
6 => match self {
Element::N => Some(Element::H),
Element::O => Some(Element::He),
Element::Si => Some(Element::O),
Element::P => Some(Element::F),
Element::S => Some(Element::Ne),
_ => None,
},
7 => match self {
Element::O => Some(Element::H),
Element::F => Some(Element::He),
Element::Si => Some(Element::N),
Element::P => Some(Element::O),
Element::S => Some(Element::F),
Element::Cl => Some(Element::Ne),
_ => None,
},
8 => match self {
Element::F => Some(Element::H),
Element::Si => Some(Element::C),
Element::P => Some(Element::N),
Element::S => Some(Element::O),
Element::Cl => Some(Element::F),
Element::Ar => Some(Element::Ne),
_ => None,
},
9 => match self {
Element::Ne => Some(Element::H),
Element::Si => Some(Element::B),
Element::P => Some(Element::C),
Element::S => Some(Element::N),
Element::Cl => Some(Element::O),
Element::Ar => Some(Element::F),
_ => None,
},
10 => match self {
Element::P => Some(Element::B),
Element::S => Some(Element::C),
Element::Cl => Some(Element::N),
Element::Ar => Some(Element::O),
_ => None,
},
11 => match self {
Element::S => Some(Element::B),
Element::Cl => Some(Element::C),
Element::Ar => Some(Element::N),
_ => None,
},
12 => match self {
Element::Cl => Some(Element::B),
Element::Ar => Some(Element::C),
_ => None,
},
13 => match self {
Element::Si => Some(Element::H),
Element::P => Some(Element::He),
Element::Ar => Some(Element::B),
_ => None,
},
14 => match self {
Element::P => Some(Element::H),
Element::S => Some(Element::He),
_ => None,
},
15 => match self {
Element::S => Some(Element::H),
_ => None,
},
_ => unreachable!(),
}
}
}