ingot_types/
primitives.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//! Primitive types -- integers of known endianness,
6//! and base buffer types.
7
8// The type aliases here are *fairly* self-describing.
9#![allow(non_camel_case_types)]
10#![allow(missing_docs)]
11
12use super::*;
13
14pub type u1 = u8;
15pub type u2 = u8;
16pub type u3 = u8;
17pub type u4 = u8;
18pub type u5 = u8;
19pub type u6 = u8;
20pub type u7 = u8;
21
22pub type i1 = i8;
23pub type i2 = i8;
24pub type i3 = i8;
25pub type i4 = i8;
26pub type i5 = i8;
27pub type i6 = i8;
28pub type i7 = i8;
29ingot_macros::define_primitive_types!();
30
31impl NetworkRepr<u1> for bool {
32    fn to_network(self) -> u1 {
33        self as u1
34    }
35
36    fn from_network(val: u1) -> Self {
37        val != 0
38    }
39}
40
41#[cfg(feature = "alloc")]
42/// Buffer type which can be owned or a view.
43pub type VarBytes<V> = Header<Vec<u8>, V>;
44#[cfg(not(feature = "alloc"))]
45/// Buffer type which can be owned or a view.
46pub type VarBytes<V> = Header<Vec<u8, 256>, V>;
47
48impl<B: ByteSlice> HasView<B> for Vec<u8> {
49    type ViewType = RawBytes<B>;
50}
51
52impl<B: zerocopy::ByteSlice, T> HasView<ObjectSlice<B, T>> for Vec<T> {
53    type ViewType = ObjectSlice<B, T>;
54}
55
56impl<V: ByteSlice> From<&VarBytes<V>> for Vec<u8> {
57    fn from(value: &VarBytes<V>) -> Self {
58        match value {
59            Header::Repr(v) => *v.clone(),
60            Header::Raw(v) => v.to_vec(),
61        }
62    }
63}
64
65/// Newtype-wrapped buffers for use in Header view-types.
66pub struct RawBytes<B: ByteSlice>(B);
67
68impl<B: ByteSlice> From<B> for RawBytes<B> {
69    #[inline]
70    fn from(value: B) -> Self {
71        Self(value)
72    }
73}
74
75impl<B: ByteSlice> Deref for RawBytes<B> {
76    type Target = B;
77
78    #[inline]
79    fn deref(&self) -> &Self::Target {
80        &self.0
81    }
82}
83
84impl<B: ByteSlice> DerefMut for RawBytes<B> {
85    #[inline]
86    fn deref_mut(&mut self) -> &mut Self::Target {
87        &mut self.0
88    }
89}
90
91impl<B: ByteSlice> AsRef<[u8]> for RawBytes<B> {
92    #[inline]
93    fn as_ref(&self) -> &[u8] {
94        &self[..]
95    }
96}
97
98impl<B: ByteSliceMut> AsMut<[u8]> for RawBytes<B> {
99    #[inline]
100    fn as_mut(&mut self) -> &mut [u8] {
101        &mut self[..]
102    }
103}
104
105impl<B: ByteSlice> From<RawBytes<B>> for Vec<u8> {
106    fn from(val: RawBytes<B>) -> Self {
107        val.to_vec()
108    }
109}
110
111impl<B: ByteSlice> HeaderLen for RawBytes<B> {
112    const MINIMUM_LENGTH: usize = 0;
113
114    #[inline]
115    fn packet_length(&self) -> usize {
116        self.len()
117    }
118}
119
120impl<V: ByteSlice> AsRef<[u8]> for VarBytes<V> {
121    #[inline]
122    fn as_ref(&self) -> &[u8] {
123        match self {
124            Header::Repr(o) => o.as_ref(),
125            Header::Raw(b) => b.as_ref(),
126        }
127    }
128}
129
130impl<V: ByteSliceMut> AsMut<[u8]> for VarBytes<V> {
131    #[inline]
132    fn as_mut(&mut self) -> &mut [u8] {
133        match self {
134            Header::Repr(o) => o.as_mut(),
135            Header::Raw(b) => b.as_mut(),
136        }
137    }
138}
139
140impl<B: ByteSlice> Emit for RawBytes<B> {
141    #[inline]
142    fn emit_raw<V: ByteSliceMut>(&self, mut buf: V) -> usize {
143        buf.copy_from_slice(self);
144
145        self.len()
146    }
147
148    #[inline]
149    fn needs_emit(&self) -> bool {
150        false
151    }
152}
153
154// Safety: We know this holds true for all our derived emits, by design.
155unsafe impl<B: ByteSlice> EmitDoesNotRelyOnBufContents for RawBytes<B> {}
156
157/// Newtype-wrapped zerocopy object buffers for use in Header view-types.
158///
159/// The byteslice must be an even multiple of object size (checked at
160/// construction time).
161pub struct ObjectSlice<B: ByteSlice, V>(B, core::marker::PhantomData<V>);
162
163impl<B: ByteSlice, V> HeaderLen for ObjectSlice<B, V> {
164    const MINIMUM_LENGTH: usize = 0;
165    #[inline]
166    fn packet_length(&self) -> usize {
167        self.0.len()
168    }
169}
170
171impl<B: ByteSlice, V> Emit for ObjectSlice<B, V> {
172    #[inline]
173    fn emit_raw<O: ByteSliceMut>(&self, mut buf: O) -> usize {
174        buf.copy_from_slice(self.0.deref());
175
176        self.0.len()
177    }
178
179    #[inline]
180    fn needs_emit(&self) -> bool {
181        false
182    }
183}
184
185#[cfg(feature = "alloc")]
186impl<B: ByteSlice, T> From<&BoxedHeader<Vec<T>, ObjectSlice<B, T>>> for Vec<T>
187where
188    T: FromBytes + IntoBytes + KnownLayout + Immutable + Clone,
189{
190    fn from(value: &Header<Vec<T>, ObjectSlice<B, T>>) -> Self {
191        match value {
192            Header::Repr(v) => v.deref().clone(),
193            Header::Raw(v) => {
194                <[T]>::ref_from_bytes(v.0.as_ref()).unwrap().to_vec()
195            }
196        }
197    }
198}
199
200impl<B: ByteSlice, V: FromBytes> From<B> for ObjectSlice<B, V> {
201    fn from(b: B) -> Self {
202        assert_eq!(
203            b.len() % core::mem::size_of::<V>(),
204            0,
205            "invalid slice size"
206        );
207        Self(b, core::marker::PhantomData)
208    }
209}
210
211impl<B: ByteSlice, V: FromBytes + Immutable> Deref for ObjectSlice<B, V> {
212    type Target = [V];
213    fn deref(&self) -> &[V] {
214        // Size is checked at construction, so this should be infallible
215        <[V]>::ref_from_bytes(self.0.as_ref()).unwrap()
216    }
217}
218
219impl<B: ByteSliceMut, V: FromBytes + Immutable + IntoBytes> DerefMut
220    for ObjectSlice<B, V>
221{
222    fn deref_mut(&mut self) -> &mut [V] {
223        // Size is checked at construction, so this should be infallible
224        <[V]>::mut_from_bytes(self.0.as_mut()).unwrap()
225    }
226}