use crate::{DeltaError, DeltaResult, Deltoid};
use crate::convert::{FromDelta, IntoDelta};
use serde::{Deserialize, Serialize};
use std::borrow::{Borrow, Cow, ToOwned};
use std::marker::PhantomData;
impl<'a, B> Deltoid for Cow<'a, B>
where B: Clone + std::fmt::Debug + PartialEq + Deltoid + ToOwned
+ Serialize
+ for<'de> Deserialize<'de>,
<B as ToOwned>::Owned: std::fmt::Debug
{
type Delta = CowDelta<'a, B>;
fn apply_delta(&self, delta: &Self::Delta) -> DeltaResult<Self> {
let lhs: &B = self.borrow();
if let Some(delta) = delta.inner.as_ref() {
lhs.apply_delta(delta)
.map(|new| new.to_owned())
.map(Cow::Owned)
} else {
Ok(self.clone())
}
}
fn delta(&self, other: &Self) -> DeltaResult<Self::Delta> {
let (lhs, rhs): (&B, &B) = (self.borrow(), other.borrow());
Ok(CowDelta {
inner: Some(lhs.delta(rhs)?),
_phantom: PhantomData,
})
}
}
impl<'a, B> IntoDelta for Cow<'a, B>
where B: IntoDelta + Serialize + for<'de> Deserialize<'de> {
fn into_delta(self) -> DeltaResult<<Self as Deltoid>::Delta> {
Ok(CowDelta {
inner: Some((self.borrow() as &B).clone().into_delta()?),
_phantom: PhantomData,
})
}
}
impl<'a, B> FromDelta for Cow<'a, B>
where B: FromDelta + Serialize + for<'de> Deserialize<'de> {
fn from_delta(delta: <Self as Deltoid>::Delta) -> DeltaResult<Self> {
let delta: <B as Deltoid>::Delta = delta.inner
.ok_or(DeltaError::ExpectedValue)?;
B::from_delta(delta)
.map(|b: B| b.to_owned())
.map(Cow::Owned)
}
}
#[derive(Clone, Debug, PartialEq)]
#[derive(serde_derive::Deserialize, serde_derive::Serialize)]
pub struct CowDelta<'a, B: Deltoid + Clone> {
inner: Option<<B as Deltoid>::Delta>,
_phantom: PhantomData<&'a B>
}