use std::collections::BTreeMap;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value as JsonValue;
use super::{ProfileFieldName, ProfileFieldValue, StaticProfileField};
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum UserProfileUpdate {
Updated(UserProfileChanges),
Dropped,
}
impl<'d> Deserialize<'d> for UserProfileUpdate {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'d>,
{
Option::<UserProfileChanges>::deserialize(deserializer).map(|value| match value {
Some(changes) => Self::Updated(changes),
None => Self::Dropped,
})
}
}
impl Serialize for UserProfileUpdate {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::Updated(changes) => serializer.serialize_some(changes),
Self::Dropped => serializer.serialize_none(),
}
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[non_exhaustive]
pub struct UserProfileChanges {
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub updated: BTreeMap<ProfileFieldName, JsonValue>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub removed: Vec<ProfileFieldName>,
}
impl UserProfileChanges {
pub fn new() -> Self {
Self::default()
}
pub fn get_updated_static<F: StaticProfileField>(
&self,
) -> Result<Option<F::Value>, serde_json::Error> {
self.updated
.get(&ProfileFieldName::from(F::NAME))
.map(|value| serde_json::from_value(value.clone()))
.transpose()
}
pub fn insert_updated_value(&mut self, value: ProfileFieldValue) {
self.updated.insert(value.field_name(), value.value().into_owned());
}
}