use serde::{Deserialize, Serialize};
use simd_json::{derived::ValueTryIntoObject, owned};
use url::Url;
use self::identity_operation_type::IdentityOperationType;
use crate::replica::entity::operation::operation_data::OperationData;
pub mod identity_operation_type;
mod op;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IdentityOperationData {
Create {
name: String,
},
SetName {
name: String,
},
SetEmail {
email: String,
},
SetLoginName {
login_name: String,
},
SetAvatarUrl {
url: Url,
},
SetMetadata {
metadata: Vec<(String, String)>,
},
}
impl OperationData for IdentityOperationData {
type DecodeError = decode::Error;
fn is_root(&self) -> bool {
matches!(self, Self::Create { .. })
}
fn from_value(raw: owned::Value, predicted_type: u64) -> Result<Self, Self::DecodeError>
where
Self: Sized,
{
let r#type = IdentityOperationType::try_from(predicted_type)?;
let object = raw
.try_into_object()
.map_err(|err| decode::Error::ObjectExpected { err })?;
match r#type {
IdentityOperationType::Create => op::create(object),
IdentityOperationType::SetName => op::set_name(object),
IdentityOperationType::SetEmail => op::set_email(object),
IdentityOperationType::SetLoginName => op::set_login_name(object),
IdentityOperationType::SetAvatarUrl => op::set_avatar_url(object),
IdentityOperationType::SetMetadata => op::set_metadata(object),
}
}
fn as_value(&self) -> simd_json::borrowed::Object<'_> {
match self {
IdentityOperationData::Create { name } => op::create_value(name),
IdentityOperationData::SetName { name } => op::set_name_value(name),
IdentityOperationData::SetEmail { email } => op::set_email_value(email),
IdentityOperationData::SetLoginName { login_name } => {
op::set_login_name_value(login_name)
}
IdentityOperationData::SetAvatarUrl { url } => op::set_avatar_url_value(url),
IdentityOperationData::SetMetadata { metadata } => op::set_metadata_value(metadata),
}
}
fn to_json_type(&self) -> u64 {
IdentityOperationType::from(self).into()
}
}
#[allow(missing_docs)]
pub mod decode {
use super::identity_operation_type;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
InvalidType(#[from] identity_operation_type::decode::Error),
#[error("The json value did not contain the expected field '{field}'.")]
MissingJsonField { field: &'static str },
#[error("Expected to parse the '{field}' field in the json data: {err}")]
WrongJsonType {
err: simd_json::TryTypeError,
field: &'static str,
},
#[error("Failed to parse an url value: {0}")]
UrlParse(#[from] url::ParseError),
#[error("Expected this operation json data to be a object, but was not: {err}")]
ObjectExpected { err: simd_json::TryTypeError },
}
}