use std::fmt::Display;
use serde::{Deserialize, Serialize};
use crate::{
ntds::Error,
value::{FromValue, StringOrStringSet, ToStringOrStringSet},
CDatabase,
};
#[derive(Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
pub struct ClassId(u32);
impl FromValue for ClassId {
fn from_value_opt(value: &crate::cache::Value) -> crate::ntds::Result<Option<Self>>
where
Self: Sized,
{
match value {
crate::cache::Value::Null(_) => Ok(None),
crate::cache::Value::U8(n) => Ok(Some(Self((*n).into()))),
crate::cache::Value::I16(n) => {
Ok(Some(Self((*n).try_into().map_err(|_| {
Error::InvalidValueDetected(value.to_string(), "u32")
})?)))
}
crate::cache::Value::I32(n) => {
Ok(Some(Self((*n).try_into().map_err(|_| {
Error::InvalidValueDetected(value.to_string(), "u32")
})?)))
}
crate::cache::Value::Currency(n) => {
Ok(Some(Self((*n).try_into().map_err(|_| {
Error::InvalidValueDetected(value.to_string(), "u32")
})?)))
}
crate::cache::Value::U32(n) => Ok(Some(Self(*n))),
crate::cache::Value::I64(n) => {
Ok(Some(Self((*n).try_into().map_err(|_| {
Error::InvalidValueDetected(value.to_string(), "u32")
})?)))
}
crate::cache::Value::U16(n) => Ok(Some(Self((*n).into()))),
_ => Err(Error::InvalidValueDetected(value.to_string(), "i32")),
}
}
}
impl Display for ClassId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl ToStringOrStringSet for ClassId {
fn to_string_or_stringset(&self, database: &CDatabase<'_, '_>) -> StringOrStringSet {
if let Some(ptr) = database
.data_table()
.data_table()
.metadata()
.object_classes()
.get(self)
{
if let Some(cn) = database
.record(ptr.ds_record_id())
.and_then(|entry| entry.cn().as_ref())
{
return StringOrStringSet::String(cn.to_string());
}
}
StringOrStringSet::String(self.0.to_string())
}
}