wuffs/
slice.rs

1use std::{marker::PhantomData, ops::Deref};
2
3use wuffs_sys::wuffs_base__slice_u8;
4
5#[derive(Clone)]
6pub enum WuffsSlice<'a, T: WuffsSliceImpl> {
7  Owned(WuffsSliceOwned<T>),
8  Borrowed(WuffsSliceBorrowed<'a, T>),
9}
10
11impl<T: WuffsSliceImpl> WuffsSlice<'_, T> {
12  pub fn from_inner(inner: T::Native) -> Self {
13    Self::Borrowed(WuffsSliceBorrowed::from(inner))
14  }
15
16  pub fn into_inner(self) -> T::Native {
17    match self {
18      Self::Owned(owned) => owned.into_inner(),
19      Self::Borrowed(borrowed) => borrowed.into_inner(),
20    }
21  }
22
23  /// Convert read-only slice reference into a `T::Native`
24  ///
25  /// # Safety
26  /// Potential cast to `*mut` ptr underlying with the hope the underlying data isn't
27  /// modified.
28  pub unsafe fn from_readonly(slice: &[T]) -> T::Native {
29    T::from_ptr(slice.as_ptr() as *mut _, slice.len())
30  }
31}
32
33impl<T: WuffsSliceImpl> AsRef<[T]> for WuffsSlice<'_, T> {
34  fn as_ref(&self) -> &[T] {
35    self.data()
36  }
37}
38
39impl<'a, T: WuffsSliceImpl> From<&'a mut [T]> for WuffsSlice<'a, T> {
40  fn from(slice: &'a mut [T]) -> Self {
41    Self::Borrowed(WuffsSliceBorrowed::new(slice))
42  }
43}
44
45impl<'a, T: WuffsSliceImpl> From<Vec<T>> for WuffsSlice<'a, T> {
46  fn from(vec: Vec<T>) -> Self {
47    Self::Owned(WuffsSliceOwned::new(vec))
48  }
49}
50
51impl<T: WuffsSliceImpl> Deref for WuffsSlice<'_, T> {
52  type Target = T::Native;
53
54  fn deref(&self) -> &Self::Target {
55    match self {
56      Self::Owned(owned) => owned,
57      Self::Borrowed(borrowed) => borrowed,
58    }
59  }
60}
61
62#[derive(Clone)]
63pub struct WuffsSliceOwned<T: WuffsSliceImpl> {
64  data: Vec<T>,
65  inner: T::Native,
66}
67
68impl<T: WuffsSliceImpl> WuffsSliceOwned<T> {
69  pub fn new(mut data: Vec<T>) -> Self {
70    let inner = T::from_ptr(data.as_mut_ptr(), data.len());
71
72    Self { data, inner }
73  }
74
75  pub fn into_data(self) -> Vec<T> {
76    self.data
77  }
78
79  pub fn into_inner(self) -> T::Native {
80    self.inner
81  }
82}
83
84impl<T: WuffsSliceImpl> Deref for WuffsSliceOwned<T> {
85  type Target = T::Native;
86
87  fn deref(&self) -> &Self::Target {
88    &self.inner
89  }
90}
91
92#[derive(Clone)]
93pub struct WuffsSliceBorrowed<'a, T: WuffsSliceImpl> {
94  inner: T::Native,
95  phantom: PhantomData<&'a u8>,
96}
97
98impl<'a, T: WuffsSliceImpl> WuffsSliceBorrowed<'a, T> {
99  pub fn new(slice: &'a mut [T]) -> Self {
100    Self {
101      inner: T::from_ptr(slice.as_mut_ptr(), slice.len()),
102      phantom: Default::default(),
103    }
104  }
105
106  pub fn from(inner: T::Native) -> Self {
107    Self {
108      inner,
109      phantom: Default::default(),
110    }
111  }
112
113  pub fn into_inner(self) -> T::Native {
114    self.inner
115  }
116}
117
118impl<T: WuffsSliceImpl> Deref for WuffsSliceBorrowed<'_, T> {
119  type Target = T::Native;
120
121  fn deref(&self) -> &Self::Target {
122    &self.inner
123  }
124}
125
126pub trait WuffsSliceImpl: Sized + Clone {
127  type Native: WuffsSliceNative<Self> + Clone;
128
129  fn from_ptr(ptr: *mut Self, len: usize) -> Self::Native;
130}
131
132pub trait WuffsSliceNative<T> {
133  fn data(&self) -> &[T];
134}
135
136impl WuffsSliceImpl for u8 {
137  type Native = wuffs_base__slice_u8;
138
139  fn from_ptr(ptr: *mut Self, len: usize) -> Self::Native {
140    wuffs_base__slice_u8 { ptr, len: len as _ }
141  }
142}
143
144impl WuffsSliceNative<u8> for wuffs_base__slice_u8 {
145  fn data(&self) -> &[u8] {
146    unsafe { std::slice::from_raw_parts(self.ptr, self.len as _) }
147  }
148}