1use crate::HeaderVec;
2use alloc::alloc::Layout;
3use alloc::borrow::{Borrow, ToOwned};
4use core::cmp::Ordering;
5use core::fmt::{self, Debug};
6use core::ptr;
7
8#[repr(C)]
9#[derive(Hash)]
10pub struct HeaderSlice<H, T> {
11 pub head: H,
12 pub body: [T],
13}
14
15impl<H, T> HeaderSlice<H, T> {
16 fn resize_ptr(this: *mut Self, len: usize) -> *mut Self {
17 let slice_ptr = ptr::slice_from_raw_parts_mut(this as *mut T, len);
18 slice_ptr as *mut Self
19 }
20
21 pub fn as_truncated(&self, len: usize) -> &Self {
22 assert!(len <= self.body.len());
23 let ptr = Self::resize_ptr(self as *const _ as *mut Self, len);
24 unsafe { &*ptr }
25 }
26
27 pub fn as_truncated_mut(&mut self, len: usize) -> &mut Self {
28 assert!(len <= self.body.len());
29 let ptr = Self::resize_ptr(self as *mut _, len);
30 unsafe { &mut *ptr }
31 }
32
33 pub unsafe fn resized_unchecked(&mut self, len: usize) -> &mut Self {
34 let ptr = Self::resize_ptr(self as *mut _, len);
35 &mut *ptr
36 }
37
38 pub fn len(&self) -> usize {
39 self.body.len()
40 }
41
42 pub fn layout_for_len(len: usize) -> Layout {
44 let head_layout = Layout::new::<H>();
45 let buf_layout = Layout::array::<T>(len).unwrap();
46 head_layout.extend(buf_layout).unwrap().0.pad_to_align()
47 }
48}
49
50impl<H: Clone, T: Clone> ToOwned for HeaderSlice<H, T> {
51 type Owned = HeaderVec<H, T>;
52 fn to_owned(&self) -> Self::Owned {
53 HeaderVec::from_iter(self.head.clone(), self.body.iter().cloned())
54 }
55}
56
57impl<H: Debug, T: Debug> Debug for HeaderSlice<H, T> {
58 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59 f.write_str("[")?;
60 self.head.fmt(f)?;
61 if self.body.len() == 0 {
62 f.write_str(";]")?;
63 } else {
64 f.write_str("; ")?;
65 self.body[0].fmt(f)?;
66 for item in &self.body[1..] {
67 f.write_str(", ")?;
68 item.fmt(f)?;
69 }
70 f.write_str("]")?;
71 }
72 Ok(())
73 }
74}
75
76impl<H, T, Rhs: ?Sized> PartialEq<Rhs> for HeaderSlice<H, T>
77where
78 H: PartialEq,
79 T: PartialEq,
80 Rhs: Borrow<HeaderSlice<H, T>>,
81{
82 fn eq(&self, rhs: &Rhs) -> bool {
83 let rhs = rhs.borrow();
84 self.head == rhs.head && self.body == rhs.body
85 }
86}
87
88impl<H: Eq, T: Eq> Eq for HeaderSlice<H, T> {}
89
90impl<H, T, Rhs: ?Sized> PartialOrd<Rhs> for HeaderSlice<H, T>
91where
92 H: PartialOrd,
93 T: PartialOrd,
94 Rhs: Borrow<HeaderSlice<H, T>>,
95{
96 fn partial_cmp(&self, rhs: &Rhs) -> Option<Ordering> {
97 let rhs = rhs.borrow();
98 partial_ord_chain! {
99 self.head => rhs.head,
100 self.body => rhs.body,
101 }
102 }
103}
104
105impl<H: Ord, T: Ord> Ord for HeaderSlice<H, T> {
106 fn cmp(&self, rhs: &Self) -> Ordering {
107 ord_chain! {
108 self.head => rhs.head,
109 self.body => rhs.body,
110 }
111 }
112}