chemistru_elements/
lib.rs1#![no_std]
4#![forbid(clippy::pedantic)]
5#![forbid(clippy::unwrap_used)]
6#![forbid(unsafe_code)]
7
8mod atomic;
9mod electron;
10mod misc;
11mod physical;
12mod raw;
13mod table;
14pub mod utils;
15
16extern crate alloc;
17
18use alloc::vec::Vec;
19use core::fmt::Display;
20
21use lazy_static::lazy_static;
22
23use crate::{
24 atomic::AtomicData, electron::ElectronData, misc::MiscData, physical::PhysicalData,
25 raw::RawElement, table::TableData,
26};
27
28lazy_static! {
31 pub static ref ELEMENTS: Vec<Element> = {
32 let raw_elements: Vec<RawElement> =
33 serde_json::from_str(include_str!("../db.json")).expect("Failed to load json data");
34 raw_elements.iter().map(|e| e.clone().sanitise()).collect()
35 };
36}
37
38#[derive(Clone, Debug, PartialEq, PartialOrd)]
39pub struct Element {
40 pub(crate) name: &'static str,
41 pub(crate) symbol: &'static str,
42 pub(crate) atomic_data: AtomicData,
43 pub(crate) electron_data: ElectronData,
44 pub(crate) physical_data: PhysicalData,
45 pub(crate) table_data: TableData,
46 pub(crate) misc_data: MiscData,
47}
48
49impl Element {
50 #[must_use]
51 pub fn name(&self) -> &'static str {
52 self.name
53 }
54
55 #[must_use]
56 pub fn symbol(&self) -> &'static str {
57 self.symbol
58 }
59
60 #[must_use]
61 pub fn atomic_data(&self) -> &AtomicData {
62 &self.atomic_data
63 }
64
65 #[must_use]
66 pub fn electron_data(&self) -> &ElectronData {
67 &self.electron_data
68 }
69
70 #[must_use]
71 pub fn physical_data(&self) -> &PhysicalData {
72 &self.physical_data
73 }
74
75 #[must_use]
76 pub fn table_data(&self) -> &TableData {
77 &self.table_data
78 }
79
80 #[must_use]
81 pub fn misc_data(&self) -> &MiscData {
82 &self.misc_data
83 }
84}
85
86impl Display for Element {
87 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88 f.write_fmt(format_args!(
89 "{}-{}",
90 self.name, self.atomic_data.atomic_number
91 ))
92 }
93}
94
95pub mod prelude {
96 pub use super::ELEMENTS;
97 pub use super::Element;
98 pub use super::utils::element_from_atomic_number;
99 pub use super::utils::element_from_name;
100 pub use super::utils::preload_elements;
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn test_getting_elements_by_atomic_number() {
109 utils::preload_elements();
110
111 let hydrogen = utils::element_from_atomic_number(1);
112 let helium = utils::element_from_atomic_number(2);
113
114 assert_eq!(
115 hydrogen.expect("We know this exists").name().to_lowercase(),
116 "hydrogen"
117 );
118 assert_eq!(
119 helium.expect("We know this exists").name().to_lowercase(),
120 "helium"
121 );
122 }
123
124 #[test]
125 fn test_getting_elements_by_name() {
126 utils::preload_elements();
127
128 let hydrogen = utils::element_from_name("hydrogen");
129 let helium = utils::element_from_name("helium");
130
131 assert_eq!(
132 hydrogen
133 .expect("We know this exists")
134 .atomic_data
135 .atomic_number,
136 1
137 );
138 assert_eq!(
139 helium
140 .expect("We know this exists")
141 .atomic_data
142 .atomic_number,
143 2
144 );
145 }
146}