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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//! Shims for unstable features and compatibility helpers.
//!
//! # Purpose
//!
//! This module provides drop-in replacements for some unstable features or
//! alternative implementations to ensure compatibility with different versions of
//! the Rust compiler. The functions here act as shims, providing
//! similar functionality to unstable or features that are close to being added to
//! the language.
//!
//! # Using the Shims
//!
//! This module exists for internal use, but you can enable it via the `shims`
//! feature. Be aware that enabling these functions are
//!
//! Utilities to make certain operations within this crate easier and less
//! repetitious.
//!
//! This module is important because, as the project grows, there will be an
//! increased need for utilities that help convert between types belonging to the
//! [`abio`][crate] crate.
/*
/// Converts a byte slice into an array of a specified size.
///
/// This function attempts to convert the given `bytes` slice into an array
/// of type `[u8; N]`, where `N` is the desired size of the array.
///
/// # Returns
///
/// Returns `Some([u8; N])` if the conversion succeeds, where `array` is the
/// resulting array. If the conversion fails due to a size mismatch, `None` is
/// returned.
#[inline]
pub fn to_byte_array<const N: usize>(bytes: &[u8], offset: usize) -> Option<[u8; N]> {
assert!(bytes.len() >= offset + N);
let range = offset..offset + N;
if let Ok(array) = <[u8; N]>::try_from(&bytes[range]) {
Some(array)
} else {
None
}
}
/// Returns a slice of bytes with a known size. This method is useful when working
/// with data structures with explicit size and/or alignment requirements, but when
/// the source of the data is dynamically sized.
///
/// This method "pretends" that we have a fixed size type, although the returned type
/// is a [`Slice`] instance.
#[inline]
pub const fn take_slice<'data>(bytes: &'data [u8], size: usize) -> Result<Bytes<'data>> {
match Bytes::new_offset(bytes, 0) {
Ok(bytes) => bytes.read(size),
Err(err) => Err(err),
}
}
#[inline]
pub const fn split_chunk_at<const N: usize>(
source: &[u8],
offset: usize,
) -> Result<(Chunk<N>, &[u8])> {
let span = Span::new(offset, N);
let len = source.len();
if len < span.end() {
Err(Error::out_of_bounds(span.len(), len))
} else {
let offset = span.start();
let bytes = unsafe {
let ptr = source.as_ptr().add(offset);
core::core::core::slice::from_raw_parts(ptr, len - span.start())
};
// SAFETY: We manually verified the bounds of the split.
let (first, tail) = unsafe { split_at_unchecked(bytes, N) };
// SAFETY: We explicitly check for the correct number of elements,
// and do not let the references outlive the slice.
let array = unsafe { first.as_ptr().cast::<[u8; N]>().read() };
Ok((Chunk::new(array), tail))
}
}
#[inline]
pub const fn split_first_chunk<const N: usize>(bytes: &[u8]) -> Option<(&[u8; N], &[u8])> {
if bytes.len() < N {
None
} else {
// SAFETY: We manually verified the bounds of the split.
let (first, tail) = unsafe { split_at_unchecked(bytes, N) };
// SAFETY: We explicitly check for the correct number of elements,
// and do not let the references outlive the slice.
Some((unsafe { &*(first.as_ptr() as *const [u8; N]) }, tail))
}
}
*/
/// Splits a slice of bytes in two at `offset`, returning a pair of byte slices.
///
/// FIXME: This is a temporary hack to make this operation `const`.
pub const unsafe
/// Compares and returns the **minimum** of two values in a `const` context.
pub const
/// Compares and returns the **maximum** of two values in a `const` context.
pub const