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}