ingot_types/
field.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! `Header` equivalents for header fields accessed by reference.
6
7use super::*;
8
9/// An equivalent to [`Header`] for header fields which are accessed by
10/// shared reference.
11pub enum FieldRef<'a, T: HasView<V>, V> {
12    /// Reference to the owned representation of a field.
13    Repr(&'a T),
14    /// Reference to a field in a borrowed header, which may be owned
15    /// or borrowed depdendent on past modifications.
16    Raw(&'a <T as HasView<V>>::ViewType),
17}
18
19impl<Z, T: HasView<V, ViewType = Q> + AsRef<[Z]>, V, Q: AsRef<[Z]>> AsRef<[Z]>
20    for FieldRef<'_, T, V>
21{
22    #[inline]
23    fn as_ref(&self) -> &[Z] {
24        match self {
25            FieldRef::Repr(t) => t.as_ref(),
26            FieldRef::Raw(a) => a.as_ref(),
27        }
28    }
29}
30
31impl<T: HeaderLen + HasView<V>, V> HeaderLen for FieldRef<'_, T, V>
32where
33    T::ViewType: HeaderLen,
34{
35    const MINIMUM_LENGTH: usize = T::MINIMUM_LENGTH;
36
37    #[inline]
38    fn packet_length(&self) -> usize {
39        match self {
40            FieldRef::Repr(o) => o.packet_length(),
41            FieldRef::Raw(b) => b.packet_length(),
42        }
43    }
44}
45
46impl<B: ByteSlice> FieldRef<'_, Vec<u8>, B> {
47    /// Copy this field out into a list of its raw bytes.
48    pub fn to_owned(&self) -> Vec<u8> {
49        match self {
50            FieldRef::Repr(a) => a.to_vec(),
51            FieldRef::Raw(a) => a.to_vec(),
52        }
53    }
54}
55
56impl<T: HasView<V, ViewType = Q> + NextLayer, V, Q> NextLayer
57    for FieldRef<'_, T, V>
58where
59    <T as HasView<V>>::ViewType: NextLayer<Denom = T::Denom, Hint = T::Hint>,
60{
61    type Denom = T::Denom;
62    type Hint = T::Hint;
63
64    fn next_layer_choice(
65        &self,
66        hint: Option<Self::Hint>,
67    ) -> Option<Self::Denom> {
68        match self {
69            FieldRef::Repr(r) => r.next_layer_choice(hint),
70            FieldRef::Raw(r) => r.next_layer_choice(hint),
71        }
72    }
73}
74
75/// An equivalent to [`Header`] for header fields which are accessed by
76/// mutable reference.
77pub enum FieldMut<'a, T: HasView<V>, V> {
78    /// Mutable reference to the owned representation of a field.
79    Repr(&'a mut T),
80    /// Mutable reference to a field in a borrowed header, which may
81    /// be owned or borrowed depdendent on past modifications.
82    Raw(&'a mut <T as HasView<V>>::ViewType),
83}
84
85impl<T: HasView<V, ViewType = Q> + AsRef<[u8]>, V, Q: AsRef<[u8]>> AsRef<[u8]>
86    for FieldMut<'_, T, V>
87{
88    #[inline]
89    fn as_ref(&self) -> &[u8] {
90        match self {
91            FieldMut::Repr(t) => t.as_ref(),
92            FieldMut::Raw(a) => a.as_ref(),
93        }
94    }
95}
96
97impl<T: HeaderLen + HasView<V>, V> HeaderLen for FieldMut<'_, T, V>
98where
99    T::ViewType: HeaderLen,
100{
101    const MINIMUM_LENGTH: usize = T::MINIMUM_LENGTH;
102
103    #[inline]
104    fn packet_length(&self) -> usize {
105        match self {
106            FieldMut::Repr(o) => o.packet_length(),
107            FieldMut::Raw(b) => b.packet_length(),
108        }
109    }
110}
111
112impl<T: HasView<V, ViewType = Q> + AsMut<[u8]>, V, Q: AsMut<[u8]>> AsMut<[u8]>
113    for FieldMut<'_, T, V>
114{
115    #[inline]
116    fn as_mut(&mut self) -> &mut [u8] {
117        match self {
118            FieldMut::Repr(t) => t.as_mut(),
119            FieldMut::Raw(a) => a.as_mut(),
120        }
121    }
122}
123
124impl<T: HasView<V, ViewType = Q> + NextLayer, V, Q> NextLayer
125    for FieldMut<'_, T, V>
126where
127    <T as HasView<V>>::ViewType: NextLayer<Denom = T::Denom, Hint = T::Hint>,
128{
129    type Denom = T::Denom;
130    type Hint = T::Hint;
131
132    fn next_layer_choice(
133        &self,
134        hint: Option<Self::Hint>,
135    ) -> Option<Self::Denom> {
136        match self {
137            FieldMut::Repr(r) => r.next_layer_choice(hint),
138            FieldMut::Raw(r) => r.next_layer_choice(hint),
139        }
140    }
141}
142
143#[cfg(feature = "alloc")]
144impl<'a, T: HasView<V>, V> From<&'a BoxedHeader<T, <T as HasView<V>>::ViewType>>
145    for FieldRef<'a, T, V>
146{
147    fn from(value: &'a BoxedHeader<T, <T as HasView<V>>::ViewType>) -> Self {
148        match value {
149            BoxedHeader::Raw(r) => Self::Raw(r),
150            BoxedHeader::Repr(r) => Self::Repr(r),
151        }
152    }
153}
154
155impl<'a, T: HasView<V>, V>
156    From<&'a InlineHeader<T, <T as HasView<V>>::ViewType>>
157    for FieldRef<'a, T, V>
158{
159    fn from(value: &'a InlineHeader<T, <T as HasView<V>>::ViewType>) -> Self {
160        match value {
161            InlineHeader::Raw(r) => Self::Raw(r),
162            InlineHeader::Repr(r) => Self::Repr(r),
163        }
164    }
165}
166
167#[cfg(feature = "alloc")]
168impl<'a, T: HasView<V>, V>
169    From<&'a mut BoxedHeader<T, <T as HasView<V>>::ViewType>>
170    for FieldMut<'a, T, V>
171{
172    fn from(
173        value: &'a mut BoxedHeader<T, <T as HasView<V>>::ViewType>,
174    ) -> Self {
175        match value {
176            BoxedHeader::Raw(r) => Self::Raw(r),
177            BoxedHeader::Repr(r) => Self::Repr(r),
178        }
179    }
180}
181
182impl<'a, T: HasView<V>, V>
183    From<&'a mut InlineHeader<T, <T as HasView<V>>::ViewType>>
184    for FieldMut<'a, T, V>
185{
186    fn from(
187        value: &'a mut InlineHeader<T, <T as HasView<V>>::ViewType>,
188    ) -> Self {
189        match value {
190            InlineHeader::Raw(r) => Self::Raw(r),
191            InlineHeader::Repr(r) => Self::Repr(r),
192        }
193    }
194}