amplify/traits/
wrapper.rs

1// Rust language amplification library providing multiple generic trait
2// implementations, type wrappers, derive macros and other language enhancements
3//
4// Written in 2019-2022 by
5//     Dr. Maxim Orlovsky <orlovsky@ubideco.org>
6//     Martin Habovstiak <martin.habovstiak@gmail.com>
7//
8// To the extent possible under law, the author(s) have dedicated all
9// copyright and related and neighboring rights to this software to
10// the public domain worldwide. This software is distributed without
11// any warranty.
12//
13// You should have received a copy of the MIT License
14// along with this software.
15// If not, see <https://opensource.org/licenses/MIT>.
16
17/// Trait defining wrapped types ("newtypes" in rust terminology). Wrapped
18/// types are used for allowing implemeting foreign traits to foreign types:
19/// <https://doc.rust-lang.org/stable/rust-by-example/generics/new_types.html>
20///
21/// Trait defines convenient methods for accessing inner data, construct
22/// and deconstruct newtype. It also serves as a marker trait for newtypes.
23///
24/// The trait works well with `#[derive(Wrapper)]` from `amplify_derive` crate
25pub trait Wrapper {
26    /// Inner type wrapped by the current newtype
27    type Inner;
28
29    /// Instantiates wrapper type with the inner data
30    fn from_inner(inner: Self::Inner) -> Self;
31
32    /// Returns reference to the inner representation for the wrapper type
33    fn as_inner(&self) -> &Self::Inner;
34
35    /// Clones inner data of the wrapped type and return them
36    #[inline]
37    fn to_inner(&self) -> Self::Inner
38    where
39        Self::Inner: Clone,
40    {
41        self.as_inner().clone()
42    }
43
44    /// Unwraps the wrapper returning the inner type
45    fn into_inner(self) -> Self::Inner;
46
47    /// Copies the wrapped type
48    fn copy(&self) -> Self
49    where
50        Self: Sized,
51        Self::Inner: Copy,
52    {
53        Self::from_inner(*self.as_inner())
54    }
55}
56
57/// Trait allowing mutable reference borrowing for the wrapped inner type.
58pub trait WrapperMut: Wrapper {
59    /// Returns a mutable reference to the inner representation for the wrapper
60    /// type
61    fn as_inner_mut(&mut self) -> &mut Self::Inner;
62}
63
64#[cfg(test)]
65mod test {
66    use super::*;
67
68    #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
69    struct TestWrapper(pub(super) u8);
70
71    impl Wrapper for TestWrapper {
72        type Inner = u8;
73
74        fn from_inner(inner: Self::Inner) -> Self {
75            Self(inner)
76        }
77
78        fn as_inner(&self) -> &Self::Inner {
79            &self.0
80        }
81
82        fn into_inner(self) -> Self::Inner {
83            self.0
84        }
85    }
86
87    impl WrapperMut for TestWrapper {
88        fn as_inner_mut(&mut self) -> &mut Self::Inner {
89            &mut self.0
90        }
91    }
92
93    #[test]
94    fn test_copy() {
95        let item = TestWrapper::from_inner(5);
96        let copy = item.copy();
97        assert_eq!(item, copy);
98        assert_eq!(copy.into_inner(), 5)
99    }
100}