carbond_lib/metrics/cpu/
cpu_cycle_intensity.rs

1// SPDX-FileCopyrightText: 2024 Andreas Schmidt <andreas.schmidt@cs.uni-saarland.de>
2//
3// SPDX-License-Identifier: Apache-2.0 OR MIT
4
5use std::{fmt::Display, num::ParseFloatError, str::FromStr};
6use uom::si::{f64::Mass, mass::picogram};
7
8use crate::metrics::round;
9
10use crate::metrics::Metric;
11
12/// Used to store a CarbonIntensity in the appropriate unit gram per kWh on the filesystem.
13#[derive(PartialEq, Debug)]
14pub struct CpuCycleIntensity {
15    mass: Mass,
16}
17
18impl Display for CpuCycleIntensity {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        let rounded_intensity = round(self.get_value().get::<picogram>());
21        write!(f, "{rounded_intensity} pg/cycle")
22    }
23}
24
25impl FromStr for CpuCycleIntensity {
26    type Err = ParseFloatError;
27
28    fn from_str(s: &str) -> Result<Self, Self::Err> {
29        let intensity = s.split_at(s.len() - 9).0;
30        let mass: Mass = Mass::new::<picogram>(intensity.parse()?);
31        Ok(CpuCycleIntensity { mass })
32    }
33}
34
35impl Metric for CpuCycleIntensity {
36    const NAME: &'static str = "cpu cycle emission";
37
38    type Unit = Mass;
39
40    fn neutral() -> Self {
41        CpuCycleIntensity {
42            mass: Mass::new::<picogram>(0.0),
43        }
44    }
45
46    fn from_value(value: Self::Unit) -> Self {
47        CpuCycleIntensity { mass: value }
48    }
49
50    fn get_value(&self) -> Self::Unit {
51        self.mass
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_to_string() {
61        let string_representation: String =
62            CpuCycleIntensity::from_value(Mass::new::<picogram>(300.5)).to_string();
63
64        assert_eq!("300.5 pg/cycle", string_representation);
65    }
66
67    #[test]
68    fn test_from_string() {
69        let string = CpuCycleIntensity::from_str("300.54 pg/cycle");
70
71        assert_eq!(
72            string.unwrap(),
73            CpuCycleIntensity::from_value(Mass::new::<picogram>(300.54))
74        );
75    }
76}