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
use crate::HeaderVec;
use alloc::alloc::Layout;
use alloc::borrow::{Borrow, ToOwned};
use core::cmp::Ordering;
use core::fmt::{self, Debug};
use core::ptr;
#[repr(C)]
#[derive(Hash)]
pub struct HeaderSlice<H, T> {
pub head: H,
pub body: [T],
}
impl<H, T> HeaderSlice<H, T> {
fn resize_ptr(this: *mut Self, len: usize) -> *mut Self {
let slice_ptr = ptr::slice_from_raw_parts_mut(this as *mut T, len);
slice_ptr as *mut Self
}
pub fn as_truncated(&self, len: usize) -> &Self {
assert!(len <= self.body.len());
let ptr = Self::resize_ptr(self as *const _ as *mut Self, len);
unsafe { &*ptr }
}
pub fn as_truncated_mut(&mut self, len: usize) -> &mut Self {
assert!(len <= self.body.len());
let ptr = Self::resize_ptr(self as *mut _, len);
unsafe { &mut *ptr }
}
pub unsafe fn resized_unchecked(&mut self, len: usize) -> &mut Self {
let ptr = Self::resize_ptr(self as *mut _, len);
&mut *ptr
}
pub fn len(&self) -> usize {
self.body.len()
}
pub fn layout_for_len(len: usize) -> Layout {
let head_layout = Layout::new::<H>();
let buf_layout = Layout::array::<T>(len).unwrap();
head_layout.extend(buf_layout).unwrap().0.pad_to_align()
}
}
impl<H: Clone, T: Clone> ToOwned for HeaderSlice<H, T> {
type Owned = HeaderVec<H, T>;
fn to_owned(&self) -> Self::Owned {
HeaderVec::from_iter(self.head.clone(), self.body.iter().cloned())
}
}
impl<H: Debug, T: Debug> Debug for HeaderSlice<H, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("[")?;
self.head.fmt(f)?;
if self.body.len() == 0 {
f.write_str(";]")?;
} else {
f.write_str("; ")?;
self.body[0].fmt(f)?;
for item in &self.body[1..] {
f.write_str(", ")?;
item.fmt(f)?;
}
f.write_str("]")?;
}
Ok(())
}
}
impl<H, T, Rhs: ?Sized> PartialEq<Rhs> for HeaderSlice<H, T>
where
H: PartialEq,
T: PartialEq,
Rhs: Borrow<HeaderSlice<H, T>>,
{
fn eq(&self, rhs: &Rhs) -> bool {
let rhs = rhs.borrow();
self.head == rhs.head && self.body == rhs.body
}
}
impl<H: Eq, T: Eq> Eq for HeaderSlice<H, T> {}
impl<H, T, Rhs: ?Sized> PartialOrd<Rhs> for HeaderSlice<H, T>
where
H: PartialOrd,
T: PartialOrd,
Rhs: Borrow<HeaderSlice<H, T>>,
{
fn partial_cmp(&self, rhs: &Rhs) -> Option<Ordering> {
let rhs = rhs.borrow();
partial_ord_chain! {
self.head => rhs.head,
self.body => rhs.body,
}
}
}
impl<H: Ord, T: Ord> Ord for HeaderSlice<H, T> {
fn cmp(&self, rhs: &Self) -> Ordering {
ord_chain! {
self.head => rhs.head,
self.body => rhs.body,
}
}
}