use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BiosConfig {
pub source: Option<BiosConfigSource>,
pub attributes: HashMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BiosConfigSource {
pub host: Option<String>,
pub system_id: Option<String>,
pub model: Option<String>,
pub bios_version: Option<String>,
pub exported_at: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BiosConfigDiff {
pub changed: HashMap<String, (Value, Value)>,
pub only_in_source: HashMap<String, Value>,
pub only_in_target: HashMap<String, Value>,
}
impl BiosConfig {
pub fn diff(&self, other: &BiosConfig) -> BiosConfigDiff {
let mut changed = HashMap::new();
let mut only_in_source = HashMap::new();
let mut only_in_target = HashMap::new();
for (key, val) in &self.attributes {
match other.attributes.get(key) {
Some(other_val) if val != other_val => {
changed.insert(key.clone(), (val.clone(), other_val.clone()));
}
None => {
only_in_source.insert(key.clone(), val.clone());
}
_ => {}
}
}
for (key, val) in &other.attributes {
if !self.attributes.contains_key(key) {
only_in_target.insert(key.clone(), val.clone());
}
}
BiosConfigDiff { changed, only_in_source, only_in_target }
}
pub fn to_json(&self) -> Result<String, serde_json::Error> {
serde_json::to_string_pretty(self)
}
pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
serde_json::from_str(json)
}
pub fn filter(&self, keys: &[&str]) -> Self {
let attributes = self.attributes
.iter()
.filter(|(k, _)| keys.contains(&k.as_str()))
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
Self { source: self.source.clone(), attributes }
}
}