Skip to main content

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}