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
#![no_std]

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

pub struct DerefMap<V: Deref, T: ?Sized, F: Fn(&<V as Deref>::Target) -> &T> {
    value: V,
    map_fn: F,
}

impl<V, T: ?Sized, F> DerefMap<V, T, F> where
    V: Deref,
    F: Fn(&<V as Deref>::Target) -> &T,
{
    pub fn new(v: V, f: F) -> Self {
        DerefMap {
            value: v,
            map_fn: f,
        }
    }
}

impl<V, T: ?Sized, F> Deref for DerefMap<V, T, F> where
    V: Deref,
    F: Fn(&<V as Deref>::Target) -> &T,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        (self.map_fn)(self.value.deref())
    }
}

pub trait DerefMapExt: Deref + Sized {
    #[inline]
    fn map<MapFn, NewValue: ?Sized>(self, f: MapFn) -> DerefMap<Self, NewValue, MapFn> where
        MapFn: Fn(&<Self as Deref>::Target) -> &NewValue,
    {
        DerefMap::new(self, f)
    }
}

impl<T> DerefMapExt for T where
    T: Deref,
{
}