dreid_forge/model/atom.rs
1//! Atomic representation for molecular systems.
2//!
3//! Provides the [`Atom`] struct that stores the chemical identity
4//! and Cartesian coordinates of an atom within a molecular structure.
5
6use super::types::Element;
7
8/// A single atom with element type and 3D position.
9///
10/// Represents the minimal information needed to define an atom
11/// in a molecular system: its chemical element and Cartesian
12/// coordinates in Ångströms.
13///
14/// # Examples
15///
16/// ```
17/// use dreid_forge::{Atom, Element};
18///
19/// // Create a carbon atom at the origin
20/// let carbon = Atom::new(Element::C, [0.0, 0.0, 0.0]);
21///
22/// assert_eq!(carbon.element, Element::C);
23/// assert_eq!(carbon.position, [0.0, 0.0, 0.0]);
24/// ```
25#[derive(Debug, Clone, PartialEq)]
26pub struct Atom {
27 /// Chemical element of this atom.
28 pub element: Element,
29 /// Cartesian coordinates [x, y, z] in Ångströms.
30 pub position: [f64; 3],
31}
32
33impl Atom {
34 /// Creates a new atom with the specified element and position.
35 ///
36 /// # Arguments
37 ///
38 /// * `element` — Chemical element of the atom
39 /// * `position` — Cartesian coordinates [x, y, z] in Ångströms
40 ///
41 /// # Returns
42 ///
43 /// A new [`Atom`] instance with the given properties.
44 pub fn new(element: Element, position: [f64; 3]) -> Self {
45 Self { element, position }
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52 use crate::model::types::Element;
53
54 #[test]
55 fn atom_new_and_fields() {
56 let pos = [0.0_f64, 1.5, -2.25];
57 let a = Atom::new(Element::C, pos);
58 assert_eq!(a.element, Element::C);
59 assert_eq!(a.position, pos);
60 }
61
62 #[test]
63 fn atom_clone_and_eq() {
64 let a = Atom::new(Element::O, [1.0, 2.0, 3.0]);
65 let b = a.clone();
66 assert_eq!(a, b);
67 let mut c = b.clone();
68 c.position[0] = 9.0;
69 assert_ne!(a, c);
70 }
71
72 #[test]
73 fn atom_debug_contains_fields() {
74 let a = Atom::new(Element::Na, [0.0, 0.0, 0.0]);
75 let dbg = format!("{:?}", a);
76 assert!(dbg.contains("Atom"));
77 assert!(dbg.contains("Na"));
78 assert!(dbg.contains("position"));
79 }
80
81 #[test]
82 fn atom_position_precision_preserved() {
83 let pos = [1e-12_f64, -1e6, std::f64::consts::PI];
84 let a = Atom::new(Element::H, pos);
85 assert_eq!(a.position[0], pos[0]);
86 assert_eq!(a.position[1], pos[1]);
87 assert_eq!(a.position[2], pos[2]);
88 }
89}