common_game/components/
energy_cell.rs

1//! `EnergyCell` module
2//!
3//! This module defines the [`EnergyCell`] type, a simple component that can store
4//! energy after being exposed to a [Sunray]. It supports charging, discharging,
5//! and checking whether the cell currently holds energy.
6
7use crate::components::sunray::Sunray;
8use std::fmt::{Debug, Formatter};
9
10/// Represents an energy storage cell that can be charged by receiving a [Sunray].
11#[allow(dead_code)]
12pub struct EnergyCell {
13    /// Indicates whether the cell currently holds energy.
14    charge: bool,
15}
16
17impl Default for EnergyCell {
18    /// Creates a new uncharged `EnergyCell`.
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl Debug for EnergyCell {
25    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26        write!(f, "Energy cell charge: {}", self.charge)
27    }
28}
29
30#[allow(dead_code)]
31impl EnergyCell {
32    /// Constructs a new `EnergyCell` that starts uncharged.
33    #[must_use]
34    pub fn new() -> Self {
35        Self { charge: false }
36    }
37
38    /// Charges the cell using a [Sunray].
39    ///
40    /// If the cell is already charged, the sunray has no additional effect.
41    ///
42    /// # Parameters
43    ///
44    /// - `_sunray`: The sunray that charges the cell.
45    pub fn charge(&mut self, _sunray: Sunray) {
46        if !self.charge {
47            self.charge = true;
48        }
49        // If already charged, nothing happens and the Sunray is wasted.
50    }
51
52    /// Attempts to discharge the cell.
53    ///
54    /// # Returns
55    ///
56    /// - `Ok(())` if the cell was charged and is now discharged.
57    ///
58    /// # Errors
59    ///
60    /// - `Err(String)` if the cell was not charged.
61    pub fn discharge(&mut self) -> Result<(), String> {
62        if self.charge {
63            self.charge = false;
64            Ok(())
65        } else {
66            Err("EnergyCell not charged!".to_string())
67        }
68    }
69
70    /// Returns `true` if the cell currently holds a charge, false otherwise
71    #[must_use]
72    pub fn is_charged(&self) -> bool {
73        self.charge
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    //! Unit tests for the [`EnergyCell`] type.
80    //!
81    //! These tests validate the expected behavior of construction, charging,
82    //! discharging, and error handling.
83
84    use super::*;
85    use crate::components::sunray::Sunray;
86
87    /// Verifies that a newly constructed cell begins uncharged.
88    #[test]
89    fn constructor_creates_uncharged_cell() {
90        let cell = EnergyCell::new();
91        assert!(!cell.is_charged(), "New cells should start uncharged");
92    }
93
94    /// Ensures that calling `charge()` sets the cell to a charged state.
95    #[test]
96    fn charging_sets_state_to_charged() {
97        let mut cell = EnergyCell::new();
98        cell.charge(Sunray::new());
99
100        assert!(
101            cell.is_charged(),
102            "Cell should become charged after calling charge()"
103        );
104    }
105
106    /// Confirms that discharging a charged cell succeeds and clears the charge state.
107    #[test]
108    fn discharge_works_when_charged() {
109        let mut cell = EnergyCell::new();
110        cell.charge(Sunray::new());
111
112        let result = cell.discharge();
113        assert!(
114            result.is_ok(),
115            "Discharging a charged cell should return Ok"
116        );
117        assert!(
118            !cell.is_charged(),
119            "Cell should no longer be charged after discharge()"
120        );
121    }
122
123    /// Ensures discharging an empty cell returns an error.
124    #[test]
125    fn discharge_fails_when_empty() {
126        let mut cell = EnergyCell::new();
127        let result = cell.discharge();
128
129        assert!(
130            result.is_err(),
131            "Discharging an empty cell should return Err"
132        );
133        assert_eq!(result.unwrap_err(), "EnergyCell not charged!");
134    }
135}