Skip to main content

design/place/subplace/
transmuted.rs

1use std::{
2    marker::PhantomInvariant,
3    ptr::Pointee,
4};
5
6use crate::{
7    place::{
8        Field,
9        Subplace,
10    },
11    ptr::Metadata,
12};
13
14pub struct TransmutedSubplace<Sub, Source: ?Sized, Target: ?Sized> {
15    subplace: Sub,
16    _source: PhantomInvariant<Source>,
17    _target: PhantomInvariant<Target>,
18}
19
20impl<Sub: Default, Source: ?Sized, Target: ?Sized> Default
21    for TransmutedSubplace<Sub, Source, Target>
22{
23    fn default() -> Self {
24        Self {
25            subplace: Default::default(),
26            _source: Default::default(),
27            _target: Default::default(),
28        }
29    }
30}
31
32unsafe impl<Sub, Source, Target> Subplace
33    for TransmutedSubplace<Sub, Source, Target>
34where
35    Sub: Subplace,
36    Source: ?Sized + Pointee<Metadata = Metadata<Sub::Source>>,
37    Target: ?Sized + Pointee<Metadata = Metadata<Sub::Target>>,
38{
39    type Source = Source;
40
41    type Target = Target;
42
43    fn offset(
44        self,
45        metadata: Metadata<Self::Source>,
46    ) -> (usize, Metadata<Self::Target>) {
47        self.subplace.offset(metadata)
48    }
49}
50
51impl<Sub, Source, Target> TransmutedSubplace<Sub, Source, Target>
52where
53    Sub: Subplace,
54    Source: ?Sized,
55    Target: ?Sized,
56{
57    pub unsafe fn new_unchecked(p: Sub) -> Self {
58        Self {
59            subplace: p,
60            _source: PhantomInvariant::new(),
61            _target: PhantomInvariant::new(),
62        }
63    }
64}
65
66pub struct TransmutedField<F, Source: ?Sized, Target: ?Sized>(
67    TransmutedSubplace<F, Source, Target>,
68);
69
70impl<F: Default, Source: ?Sized, Target: ?Sized> Default
71    for TransmutedField<F, Source, Target>
72{
73    fn default() -> Self {
74        Self(Default::default())
75    }
76}
77
78unsafe impl<F, Source, Target> Subplace for TransmutedField<F, Source, Target>
79where
80    F: Field,
81    Source: ?Sized + Pointee<Metadata = Metadata<F::Source>>,
82    Target: ?Sized + Pointee<Metadata = Metadata<F::Target>>,
83{
84    type Source = Source;
85    type Target = Target;
86
87    fn offset(
88        self,
89        metadata: Metadata<Self::Source>,
90    ) -> (usize, Metadata<Self::Target>) {
91        self.0.subplace.offset(metadata)
92    }
93}
94
95unsafe impl<F, Source, Target> Field for TransmutedField<F, Source, Target>
96where
97    F: Field,
98    Source: ?Sized + Pointee<Metadata = Metadata<F::Source>>,
99    Target: ?Sized + Pointee<Metadata = Metadata<F::Target>>,
100{
101    const NAME: &'static str = F::NAME;
102}