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
//! Convenience types that immutably and mutably deref into an arbitrary type
//! reachable from their owned inner type.
//!
//! These types can be used as a purely-safe alternative to replace some of the
//! typical use cases for self-referential types.
//! They can also be used to limit access to and visibility of an inner type by
//! acting as wrappers that restrict callers to only accessing its `Deref::Target` type,
//! which we call `Ref` in this crate.

#![no_std]
#![feature(const_mut_refs)]

use core::ops::{Deref, DerefMut};

/// A struct that holds an inner value and a function
/// that is used deref the `Inner` value into a `&Ref`.
///
/// As with [`Deref`], the dereffer function must not fail.
/// It typically just accesses an arbitrary field reachable from `Inner`.
///
/// This is also useful to prevent a caller from accessing all of `Inner`,
/// rather only giving them access to `Ref`.
pub struct DerefsTo<Inner, Ref: ?Sized> {
    /// The inner object that is used as the starting point to access
    /// the type `Ref`, and is thus passed into the below `deref_func`
    /// in order to return an `&Ref` in this struct's `Deref` impl.
    inner: Inner,
    /// The function that is called within the `Deref` impl
    /// to actually access and return the `&Ref`.
    deref_func: fn(&Inner) -> &Ref,
}
impl<Inner, Ref: ?Sized> DerefsTo<Inner, Ref> {
    pub const fn new(inner: Inner, deref_func: fn(&Inner) -> &Ref) -> Self {
        Self { inner, deref_func }
    }
}
impl<Inner, Ref> DerefsTo<Inner, Ref> 
where
    Inner: Deref<Target = Ref>,
    Ref: ?Sized,
{
    /// Creates a new wrapper with the default, simple deref function,
    /// [`Deref::deref()`].
    pub const fn new_default(inner: Inner) -> Self {
        Self { inner, deref_func: Deref::deref }
    }
}
impl<Inner, Ref: ?Sized> Deref for DerefsTo<Inner, Ref> {
    type Target = Ref;
    fn deref(&self) -> &Self::Target {
        (self.deref_func)(&self.inner)
    }
}

/// Similar to [`DerefsTo`], but supports mutable dereferencing too.
///
/// Because Ruse doesn't offer a way to abstract over mutability,
/// i.e., accept both `&T` and `&mut T`, this struct must handle the
/// `Deref` and `DerefMut` cases separately with individual functions.
pub struct DerefsToMut<Inner, Ref: ?Sized> {
    inner: DerefsTo<Inner, Ref>,
    deref_mut_func: fn(&mut Inner) -> &mut Ref,
}
impl<Inner, Ref: ?Sized> DerefsToMut<Inner, Ref> {
    /// Creates a new wrapper with custom arbitrary deref functions.
    pub const fn new(
        inner: Inner,
        deref_func: fn(&Inner) -> &Ref,
        deref_mut_func: fn(&mut Inner) -> &mut Ref,
    ) -> Self {
        Self {
            inner: DerefsTo::new(inner, deref_func),
            deref_mut_func,
        }
    }
}
impl<Inner, Ref> DerefsToMut<Inner, Ref> 
where
    Inner: DerefMut<Target = Ref>,
    Ref: ?Sized,
{
    /// Creates a new wrapper with default, simple deref functions,
    /// [`Deref::deref()`] and [`DerefMut::deref_mut()`].
    pub const fn new_default(inner: Inner) -> Self {
        Self {
            inner: DerefsTo::new(inner, Deref::deref),
            deref_mut_func: DerefMut::deref_mut,
        }
    }
}
impl<Inner, Ref: ?Sized> Deref for DerefsToMut<Inner, Ref> {
    type Target = Ref;
    fn deref(&self) -> &Self::Target {
        self.inner.deref()
    }
}

impl<Inner, Ref: ?Sized> DerefMut for DerefsToMut<Inner, Ref> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        (self.deref_mut_func)(&mut self.inner.inner)
    }
}