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
// Copyright © 2018–2022 Trevor Spiteri
// This library is free software: you can redistribute it and/or
// modify it under the terms of either
//
// * the Apache License, Version 2.0 or
// * the MIT License
//
// at your option.
//
// You should have recieved copies of the Apache License and the MIT
// License along with the library. If not, see
// <https://www.apache.org/licenses/LICENSE-2.0> and
// <https://opensource.org/licenses/MIT>.
use core::{marker::PhantomData, slice};
#[derive(Clone, Copy, Debug)]
pub struct Bytes<'a> {
ptr: *const u8,
len: usize,
phantom: PhantomData<&'a [u8]>,
}
impl<'a> Bytes<'a> {
#[inline]
pub const fn new(bytes: &'a [u8]) -> Bytes<'a> {
Bytes {
ptr: bytes.as_ptr(),
len: bytes.len(),
phantom: PhantomData,
}
}
#[inline]
#[allow(dead_code)]
pub fn slice(self) -> &'a [u8] {
// SAFETY: points to a valid slice
unsafe { slice::from_raw_parts(self.ptr, self.len) }
}
#[inline]
pub const fn len(self) -> usize {
self.len
}
#[inline]
pub const fn is_empty(self) -> bool {
self.len == 0
}
#[inline]
pub const fn get(self, i: usize) -> u8 {
assert!(i < self.len, "index out of bounds");
let ptr = self.ptr.wrapping_add(i);
// SAFETY: points to a valid slice, and bounds already checked
unsafe { *ptr }
}
#[inline]
pub const fn split(self, i: usize) -> (Bytes<'a>, Bytes<'a>) {
let end_len = match self.len().checked_sub(i) {
Some(s) => s,
None => panic!("index out of bounds"),
};
(
Bytes {
ptr: self.ptr,
len: i,
phantom: PhantomData,
},
Bytes {
ptr: self.ptr.wrapping_add(i),
len: end_len,
phantom: PhantomData,
},
)
}
}