avid 0.6.1

A plug-and-play scripting language
Documentation
use std::{
    fmt::Debug,
    ops::{Deref, DerefMut},
};

// A "borrowed-or-owned" struct, mostly for use with Asts.
pub(crate) enum Boo<'a, T> {
    Owned(T),
    Borrowed(&'a mut T),
}

impl<T: Debug> Debug for Boo<'_, T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Owned(arg0) => f.debug_tuple("Owned").field(arg0).finish(),
            Self::Borrowed(arg0) => f.debug_tuple("Borrowed").field(arg0).finish(),
        }
    }
}

impl<'a, T> From<&'a mut T> for Boo<'a, T> {
    fn from(other: &'a mut T) -> Self {
        Self::Borrowed(other)
    }
}

impl<'a, T> From<T> for Boo<'a, T> {
    fn from(other: T) -> Self {
        Self::Owned(other)
    }
}

impl<'a, T> Deref for Boo<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        match self {
            Boo::Owned(o) => o,
            Boo::Borrowed(b) => &**b,
        }
    }
}

impl<'a, T> DerefMut for Boo<'a, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self {
            Boo::Owned(o) => &mut *o,
            Boo::Borrowed(b) => *b,
        }
    }
}

impl<'a, T> AsRef<T> for Boo<'a, T> {
    fn as_ref(&self) -> &T {
        match self {
            Boo::Owned(o) => o,
            Boo::Borrowed(b) => &**b,
        }
    }
}

impl<'a, T> AsMut<T> for Boo<'a, T> {
    fn as_mut(&mut self) -> &mut T {
        match self {
            Boo::Owned(o) => &mut *o,
            Boo::Borrowed(b) => *b,
        }
    }
}

impl<T: PartialEq> PartialEq for Boo<'_, T> {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Self::Owned(l0), Self::Owned(r0)) => l0 == r0,
            (Self::Borrowed(l0), Self::Borrowed(r0)) => l0 == r0,
            (Self::Borrowed(l0), Self::Owned(r0)) => *l0 == r0,
            (Self::Owned(l0), Self::Borrowed(r0)) => l0 == *r0,
        }
    }
}