use serde::{Deserialize, Serialize};
use crate::{object::Meta, query::IndexMeta};
#[doc(hidden)]
pub trait ObjectInternal {
fn __serialize_internal(&self) -> Vec<u8>;
}
pub trait Unique {
const HAS_UNIQUE_FIELDS: bool;
fn derive_unique_hashes(&self) -> Vec<(String, &'static str)>;
}
pub trait Object:
ObjectInternal + Unique + Serialize + for<'de> Deserialize<'de> + Sized + Send + Sync + 'static
{
const TYPE: &'static str;
fn type_name(&self) -> &'static str {
Self::TYPE
}
fn meta(&self) -> &Meta;
fn meta_mut(&mut self) -> &mut Meta;
fn index_meta(&self) -> IndexMeta;
}
pub trait ObjectMeta {
fn id(&self) -> uuid::Uuid;
fn owner(&self) -> uuid::Uuid;
fn created_at(&self) -> chrono::DateTime<chrono::Utc>;
fn updated_at(&self) -> chrono::DateTime<chrono::Utc>;
}
impl<T> ObjectMeta for T
where
T: Object,
{
fn id(&self) -> uuid::Uuid {
self.meta().id()
}
fn owner(&self) -> uuid::Uuid {
self.meta().owner()
}
fn created_at(&self) -> chrono::DateTime<chrono::Utc> {
self.meta().created_at()
}
fn updated_at(&self) -> chrono::DateTime<chrono::Utc> {
self.meta().updated_at()
}
}
pub trait ObjectType {
fn type_name(&self) -> &'static str;
}
impl<T: Object> ObjectType for T
where
T: Object,
{
fn type_name(&self) -> &'static str {
T::TYPE
}
}
pub trait ObjectOwnership {
fn is_system_owned(&self) -> bool;
fn is_owned_by<O: Object>(&self, owner: &O) -> bool;
fn set_owner(&mut self, owner: uuid::Uuid);
}
impl<T: Object> ObjectOwnership for T {
fn is_system_owned(&self) -> bool {
self.meta().owner() == super::SYSTEM_OWNER
}
fn is_owned_by<O: Object>(&self, object: &O) -> bool {
self.meta().owner() == object.meta().id()
}
fn set_owner(&mut self, owner: uuid::Uuid) {
self.meta_mut().owner = owner;
}
}
pub enum Union<A: Object, B: Object> {
First(A),
Second(B),
}
impl<A: Object, B: Object> Union<A, B> {
pub fn is_first(&self) -> bool {
match self {
Self::First(_) => true,
Self::Second(_) => false,
}
}
pub fn is_second(&self) -> bool {
match self {
Self::First(_) => false,
Self::Second(_) => true,
}
}
pub fn as_first(self) -> Option<A> {
match self {
Self::First(a) => Some(a),
Self::Second(_) => None,
}
}
pub fn as_second(self) -> Option<B> {
match self {
Self::First(_) => None,
Self::Second(b) => Some(b),
}
}
}