use std::{
fmt::{self, Debug, Formatter},
hash::Hash,
};
use crate::{storage::Storage, Entity, Value, ID};
#[derive(Clone)]
pub enum EntityResult<'connection, S: Storage> {
NotFound,
Value(Value),
Ref(Entity<'connection, S>),
Repeated(Vec<Self>),
}
impl<'connection, S: Storage> Debug for EntityResult<'connection, S> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::NotFound => write!(f, "NotFound")?,
Self::Value(v) => {
write!(f, "Value(")?;
v.fmt(f)?;
write!(f, ")")?;
}
Self::Ref(e) => {
write!(f, "Ref(")?;
e.id().fmt(f)?;
write!(f, ")")?;
}
Self::Repeated(xs) => {
write!(f, "Repeated(")?;
for x in xs {
x.fmt(f)?;
write!(f, ", ")?;
}
write!(f, ")")?;
}
}
Ok(())
}
}
impl<'connection, S: Storage> EntityResult<'connection, S> {
pub fn is_ref_to(&self, id: &ID) -> bool {
if let Self::Ref(e) = self {
e.id() == id
} else {
false
}
}
}
impl<'connection, S: Storage> PartialEq<Self> for EntityResult<'connection, S> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Value(l0), Self::Value(r0)) => l0 == r0,
(Self::Ref(l0), Self::Ref(r0)) => l0 == r0,
(Self::Repeated(l0), Self::Repeated(r0)) => l0 == r0,
_ => core::mem::discriminant(self) == core::mem::discriminant(other),
}
}
}
impl<'connection, S: Storage> Eq for EntityResult<'connection, S> {}
impl<'connection, S: Storage> Hash for EntityResult<'connection, S> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
core::mem::discriminant(self).hash(state);
}
}
impl<'connection, S: Storage> PartialEq<Value> for EntityResult<'connection, S> {
fn eq(&self, other: &Value) -> bool {
match self {
Self::Value(s) => s == other,
_ => false,
}
}
}
impl<'connection, S: Storage + PartialEq> PartialEq<Entity<'connection, S>>
for EntityResult<'connection, S>
{
fn eq(&self, other: &Entity<'connection, S>) -> bool {
match self {
Self::Ref(s) => s == other,
_ => false,
}
}
}
impl<'connection, S: Storage> PartialEq<ID> for EntityResult<'connection, S> {
fn eq(&self, other: &ID) -> bool {
self.is_ref_to(other)
}
}
impl<'connection, S: Storage + PartialEq> PartialEq<Vec<Self>> for EntityResult<'connection, S> {
fn eq(&self, other: &Vec<Self>) -> bool {
match self {
Self::Repeated(s) => s == other,
_ => false,
}
}
}
impl<'connection, S: Storage> From<Value> for EntityResult<'connection, S> {
fn from(v: Value) -> Self {
Self::Value(v)
}
}
impl<'connection, S: Storage> From<Entity<'connection, S>> for EntityResult<'connection, S> {
fn from(e: Entity<'connection, S>) -> Self {
Self::Ref(e)
}
}