#[derive(Debug, Eq)]
pub enum OwnedOrRef<'a, T> {
Borrowed(&'a T),
Owned(T),
}
impl<'a, 'b, A, B> PartialEq<OwnedOrRef<'a, A>> for OwnedOrRef<'b, B>
where
B: PartialEq<A>,
{
#[inline]
fn eq(&self, other: &OwnedOrRef<'a, A>) -> bool {
PartialEq::eq(self.as_ref(), other.as_ref())
}
}
impl<T> From<T> for OwnedOrRef<'_, T> {
fn from(value: T) -> Self {
Self::Owned(value)
}
}
impl<'a, T> From<&'a T> for OwnedOrRef<'a, T> {
fn from(value: &'a T) -> Self {
Self::Borrowed(value)
}
}
impl<T> AsRef<T> for OwnedOrRef<'_, T> {
fn as_ref(&self) -> &T {
match self {
Self::Borrowed(b) => b,
Self::Owned(o) => o,
}
}
}
impl<T> OwnedOrRef<'_, T> {
pub fn into_owned(self) -> T {
match self {
Self::Borrowed(_) => panic!("Borrowed data does not allow call into_owned"),
Self::Owned(o) => o,
}
}
}
use rkyv::{
Archive, Deserialize, Serialize,
bytecheck::{CheckBytes, TupleStructCheckContext, rancor},
rancor::Fallible,
};
pub struct ArchivedOwnedOrRef<T: Archive>(T::Archived);
unsafe impl<T, C> CheckBytes<C> for ArchivedOwnedOrRef<T>
where
T: Archive,
C: Fallible + ?Sized,
<C as Fallible>::Error: rancor::Trace,
<T as Archive>::Archived: CheckBytes<C>,
{
unsafe fn check_bytes(value: *const Self, context: &mut C) -> Result<(), <C as Fallible>::Error> {
unsafe {
<<T as Archive>::Archived as CheckBytes<C>>::check_bytes(&raw const (*value).0, context)
.map_err(|e| {
<<C as Fallible>::Error as rancor::Trace>::trace(
e,
TupleStructCheckContext {
tuple_struct_name: "ArchivedOwnedOrRef",
field_index: 0usize,
},
)
})?;
}
Ok(())
}
}
pub struct OwnedOrRefResolver<T: Archive>(<T as Archive>::Resolver);
impl<'a, F> Archive for OwnedOrRef<'a, F>
where
F: Archive,
{
type Archived = ArchivedOwnedOrRef<F>;
type Resolver = OwnedOrRefResolver<F>;
fn resolve(&self, resolver: Self::Resolver, out: rkyv::Place<Self::Archived>) {
let field_ptr = unsafe { &raw mut (*out.ptr()).0 };
let field_out = unsafe { rkyv::Place::from_field_unchecked(out, field_ptr) };
<F as Archive>::resolve(self.as_ref(), resolver.0, field_out);
}
}
unsafe impl<F> rkyv::traits::Portable for ArchivedOwnedOrRef<F>
where
F: Archive,
<F as Archive>::Archived: rkyv::traits::Portable,
{
}
impl<'a, F, D: Fallible + ?Sized> Deserialize<OwnedOrRef<'a, F>, D>
for rkyv::Archived<OwnedOrRef<'a, F>>
where
F: Archive,
<F as Archive>::Archived: Deserialize<F, D>,
{
fn deserialize(&self, deserializer: &mut D) -> Result<OwnedOrRef<'a, F>, <D as Fallible>::Error> {
Ok(OwnedOrRef::Owned(
<<F as Archive>::Archived as Deserialize<F, D>>::deserialize(&self.0, deserializer)?,
))
}
}
impl<'a, F, S: Fallible + ?Sized> Serialize<S> for OwnedOrRef<'a, F>
where
F: Serialize<S>,
{
fn serialize(
&self,
serializer: &mut S,
) -> Result<<Self as Archive>::Resolver, <S as Fallible>::Error> {
Ok(OwnedOrRefResolver(<F as Serialize<S>>::serialize(
self.as_ref(),
serializer,
)?))
}
}