1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* 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
    }
  }
}*/