use std::{ops::Deref, sync::Arc};
#[derive(Clone, Debug, Eq)]
pub enum Ref<'ctx, T> {
Borrowed(&'ctx T),
Arc(Arc<T>),
}
impl<T> std::cmp::PartialEq for Ref<'_, T>
where
T: std::cmp::PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.deref() == other.deref()
}
}
impl<'ctx, T: Clone> Ref<'ctx, T> {
pub fn to_static(&'ctx self) -> Ref<'static, T> {
Ref::Arc(self.to_arc())
}
pub fn to_arc(&'ctx self) -> Arc<T> {
match self {
Ref::Arc(r) => r.clone(),
Ref::Borrowed(b) => Arc::new((*b).clone()),
}
}
}
impl<'ctx, T> From<&'ctx T> for Ref<'ctx, T> {
fn from(val: &'ctx T) -> Self {
Ref::Borrowed(val)
}
}
impl<'ctx, T> From<Arc<T>> for Ref<'ctx, T> {
fn from(val: Arc<T>) -> Self {
Ref::Arc(val)
}
}
impl<'ctx, T> From<T> for Ref<'ctx, T> {
fn from(val: T) -> Self {
Ref::Arc(Arc::new(val))
}
}
impl<'ctx, T> std::ops::Deref for Ref<'ctx, T> {
type Target = T;
fn deref(&self) -> &T {
match self {
Ref::Borrowed(b) => b,
Ref::Arc(rc) => rc,
}
}
}
#[cfg(test)]
mod test {
use crate::reference::Ref;
use proptest::prelude::*;
proptest! {
#[test]
fn test_ref_partialeq(val in any::<u64>()) {
let borrowed = Ref::from(&val);
let owned = Ref::from(val);
assert_eq!(borrowed, owned);
}
}
}