cloud_scanner_cli/
impact_provider.rs1use crate::model::{CloudResource, EstimatedInventory, Inventory};
3use anyhow::Result;
4use async_trait::async_trait;
5use rocket_okapi::okapi::schemars;
6use rocket_okapi::okapi::schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8
9#[async_trait]
11pub trait ImpactProvider {
12 async fn get_impacts(
15 &self,
16 inventory: Inventory,
17 usage_duration_hours: &f32,
18 verbose: bool,
19 ) -> Result<EstimatedInventory>;
20}
21
22#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
23pub struct CloudResourceWithImpacts {
24 pub cloud_resource: CloudResource,
25 pub impacts_values: Option<ImpactsValues>,
27 pub impacts_duration_hours: f32,
29}
30
31#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
34pub struct ImpactsValues {
35 pub adp_manufacture_kgsbeq: f64,
36 pub adp_use_kgsbeq: f64,
37 pub pe_manufacture_megajoules: f64,
38 pub pe_use_megajoules: f64,
39 pub gwp_manufacture_kgco2eq: f64,
40 pub gwp_use_kgco2eq: f64,
41 pub raw_data: Option<serde_json::Value>,
42}
43
44#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
46pub struct ImpactsSummary {
47 pub number_of_resources_total: usize,
48 pub number_of_resources_assessed: usize,
49 pub number_of_resources_not_assessed: usize,
50 pub duration_of_use_hours: f64,
51 pub adp_manufacture_kgsbeq: f64,
52 pub adp_use_kgsbeq: f64,
53 pub pe_manufacture_megajoules: f64,
54 pub pe_use_megajoules: f64,
55 pub gwp_manufacture_kgco2eq: f64,
56 pub gwp_use_kgco2eq: f64,
57 pub aws_region: String,
58 pub country: String,
59}
60
61impl ImpactsSummary {
62 pub fn new(
64 aws_region: String,
65 country: String,
66 resources_with_impacts: &EstimatedInventory,
67 duration_of_use_hours: f64,
68 ) -> Self {
69 let resources = resources_with_impacts.impacting_resources.clone();
70
71 let mut summary = ImpactsSummary {
72 number_of_resources_total: resources.len(),
73 number_of_resources_assessed: 0,
74 number_of_resources_not_assessed: 0,
75 aws_region,
76 country,
77 duration_of_use_hours,
78 adp_manufacture_kgsbeq: 0.0,
79 adp_use_kgsbeq: 0.0,
80 pe_manufacture_megajoules: 0.0,
81 pe_use_megajoules: 0.0,
82 gwp_manufacture_kgco2eq: 0.0,
83 gwp_use_kgco2eq: 0.0,
84 };
85
86 for resource in resources {
87 if let Some(impacts) = resource.impacts_values {
89 summary.number_of_resources_assessed += 1;
90 summary.adp_manufacture_kgsbeq += impacts.adp_manufacture_kgsbeq;
91 summary.adp_use_kgsbeq += impacts.adp_use_kgsbeq;
92 summary.pe_manufacture_megajoules += impacts.pe_manufacture_megajoules;
93 summary.pe_use_megajoules += impacts.pe_use_megajoules;
94 summary.gwp_manufacture_kgco2eq += impacts.gwp_manufacture_kgco2eq;
95 summary.gwp_use_kgco2eq += impacts.gwp_use_kgco2eq;
96 } else {
97 debug!("Skipped counting resource: {:#?} while building summary because it has no impact data", resource);
99 summary.number_of_resources_not_assessed += 1;
100 }
101 }
102 summary
103 }
104}