retina_common/
transparent_wrapper.rs

1// Copyright (C) 2023 Tristan Gerritsen <tristan@thewoosh.org>
2// All Rights Reserved.
3
4use core::fmt::Debug;
5use std::{borrow::{Borrow, BorrowMut}, ops::{Deref, DerefMut}};
6
7/// The transparent wrapper wraps a generic object transparently in a
8/// single-field tuple. This can be useful for having generics of either
9/// `Option<T>` or `TransparentWrapper<T>`.
10#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
11#[repr(transparent)]
12pub struct TransparentWrapper<Inner>(Inner);
13
14impl<Inner> Debug for TransparentWrapper<Inner>
15        where Inner: Debug {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        self.0.fmt(f)
18    }
19}
20
21impl<Inner> TransparentWrapper<Inner> {
22    pub const fn new(value: Inner) -> Self {
23        Self(value)
24    }
25}
26
27impl<Inner> AsRef<Inner> for TransparentWrapper<Inner> {
28    fn as_ref(&self) -> &Inner {
29        &self.0
30    }
31}
32
33impl<Inner> AsMut<Inner> for TransparentWrapper<Inner> {
34    fn as_mut(&mut self) -> &mut Inner {
35        &mut self.0
36    }
37}
38
39impl<Inner> Borrow<Inner> for TransparentWrapper<Inner> {
40    fn borrow(&self) -> &Inner {
41        &self.0
42    }
43}
44
45impl<Inner> BorrowMut<Inner> for TransparentWrapper<Inner> {
46    fn borrow_mut(&mut self) -> &mut Inner {
47        &mut self.0
48    }
49}
50
51impl<Inner> Deref for TransparentWrapper<Inner> {
52    type Target = Inner;
53
54    fn deref(&self) -> &Self::Target {
55        &self.0
56    }
57}
58
59impl<Inner> DerefMut for TransparentWrapper<Inner> {
60    fn deref_mut(&mut self) -> &mut Self::Target {
61        &mut self.0
62    }
63}
64
65impl<Inner> From<Inner> for TransparentWrapper<Inner> {
66    fn from(value: Inner) -> Self {
67        Self(value)
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use crate::TransparentWrapper;
74
75    #[test]
76    fn debug() {
77        let value = 5;
78        let _obj = TransparentWrapper::new(value);
79        assert_eq!(format!("{_obj:#?}"), format!("{value:#?}"));
80    }
81
82    #[test]
83    fn as_ref() {
84        let value = "hello";
85        let obj = TransparentWrapper::new(value);
86        assert!(obj.as_ref().eq_ignore_ascii_case("HelLO"));
87    }
88
89    #[test]
90    fn deref() {
91        let value = "hello";
92        let obj = TransparentWrapper::new(value);
93        assert!(obj.eq_ignore_ascii_case("HELLO"));
94    }
95}