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 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}