header_slice/
slice.rs

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    /// Returns the memory layout for an instance with the given length
43    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}