avr-oxide 0.4.1

An extremely simple Rusty operating system for AVR microcontrollers
/* util.rs
 *
 * Developed by Tim Walls <tim.walls@snowgoons.com>
 * Copyright (c) All Rights Reserved, Tim Walls
 */
//! General utility types/functions.

pub mod persist;
pub mod datatypes;
pub mod debug;

// Imports ===================================================================
use core::ops::{Deref, DerefMut};
use avr_oxide::alloc::boxed::Box;

// Declarations ==============================================================
pub enum OwnOrBorrow<'a, T: 'a + ?Sized> {
  Own(Box<T>),
  Borrow(&'a T)
}
pub enum OwnOrBorrowMut<'a, T: 'a + ?Sized> {
  Own(Box<T>),
  Borrow(&'a mut T)
}


// Code ======================================================================

macro_rules! common_impl {
  ($name:ident) => {
    impl<T> $name<'_,T>
    where
      T: Clone + ?Sized
    {
      pub fn into_owned(self) -> T {
        match self {
          Self::Own(v) => *v,
          Self::Borrow(r) => r.clone()
        }
      }
    }

    impl<T> $name<'_,T> {
      pub fn is_owned(&self) -> bool {
        match self {
          Self::Own(_) => true,
          Self::Borrow(_) => false
        }
      }
    }


    impl<T> Deref for $name<'_,T>
    where
      T: ?Sized
    {
      type Target = T;

      fn deref(&self) -> &Self::Target {
        match self {
          Self::Own(v) => v,
          Self::Borrow(r) => *r
        }
      }
    }

    impl<T> From<T> for $name<'_,T>
    {
      fn from(v: T) -> Self {
        Self::Own(Box::new(v))
      }
    }
  }
}

common_impl!(OwnOrBorrow);
common_impl!(OwnOrBorrowMut);

impl<T> Clone for OwnOrBorrow<'_,T>
where
  T: Clone
{
  fn clone(&self) -> Self {
    match self {
      OwnOrBorrow::Own(v) => Self::Own(v.clone()),
      OwnOrBorrow::Borrow(r) => Self::Borrow(r)
    }
  }
}

impl<'a, T> From<&'a T> for OwnOrBorrow<'a,T>
where
  T: ?Sized
{
  fn from(r: &'a T) -> Self {
    Self::Borrow(r)
  }
}

impl<'a, T> From<&'a mut T> for OwnOrBorrowMut<'a,T>
where
  T: ?Sized
{
  fn from(r: &'a mut T) -> Self {
    Self::Borrow(r)
  }
}

impl<T> DerefMut for OwnOrBorrowMut<'_,T>
where
  T: ?Sized
{
  fn deref_mut(&mut self) -> &mut Self::Target {
    match self {
      Self::Own(v) => v,
      Self::Borrow(r) => r
    }
  }
}

/*impl<T> DerefMut for OwnOrBorrowMut<'_,[T]>
where
  T: ?Sized
{
  fn deref_mut(&mut self) -> &mut Self::Target {
    match self {
      Self::Own(v) => v,
      Self::Borrow(r) => r
    }
  }
}*/