use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct UserProfile {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tz: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub locale: Option<String>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub extra: BTreeMap<String, serde_json::Value>,
}
impl UserProfile {
pub fn summary_line(&self) -> String {
let mut parts = Vec::new();
if let Some(n) = &self.name {
parts.push(format!("name={n}"));
}
parts.push(match &self.tz {
Some(z) => format!("tz={z}"),
None => "tz=(system clock)".into(),
});
if let Some(l) = &self.locale {
parts.push(format!("locale={l}"));
}
parts.join(", ")
}
pub fn extra<T: serde::de::DeserializeOwned>(&self, key: &str) -> Option<T> {
self.extra.get(key).cloned().and_then(|v| serde_json::from_value(v).ok())
}
pub fn set_extra<T: Serialize>(&mut self, key: impl Into<String>, value: T) {
if let Ok(v) = serde_json::to_value(value) {
self.extra.insert(key.into(), v);
}
}
}