twizzler/ptr/resolved/
resolved_slice.rs

1use std::{
2    borrow::Borrow,
3    ops::{Deref, Index, RangeBounds},
4};
5
6use twizzler_rt_abi::object::ObjectHandle;
7
8use super::{Ref, RefSliceMut};
9use crate::{
10    ptr::{GlobalPtr, TxRefSlice},
11    util::range_bounds_to_start_and_end,
12};
13
14pub struct RefSlice<'a, T> {
15    ptr: Ref<'a, T>,
16    len: usize,
17}
18
19impl<'a, T> RefSlice<'a, T> {
20    #[inline]
21    pub unsafe fn from_ref(ptr: Ref<'a, T>, len: usize) -> Self {
22        Self { ptr, len }
23    }
24
25    pub fn offset(&self) -> u64 {
26        self.ptr.offset()
27    }
28
29    #[inline]
30    pub fn as_slice(&self) -> &'a [T] {
31        unsafe { core::slice::from_raw_parts(self.ptr.raw(), self.len) }
32    }
33
34    #[inline]
35    pub fn slice(self, range: impl RangeBounds<usize>) -> Self {
36        let (start, end) = range_bounds_to_start_and_end(self.len, range);
37        let len = end - start;
38        if let Some(r) = self.get_ref(start) {
39            unsafe { Self::from_ref(r, len) }
40        } else {
41            unsafe { Self::from_ref(self.ptr, 0) }
42        }
43    }
44
45    #[inline]
46    pub fn get_ref(&self, idx: usize) -> Option<Ref<'a, T>> {
47        let ptr = self.as_slice().get(idx)?;
48        Some(unsafe { Ref::from_ptr(ptr) })
49    }
50
51    #[inline]
52    pub fn get(&self, idx: usize) -> Option<&T> {
53        let ptr = self.as_slice().get(idx)?;
54        Some(ptr)
55    }
56
57    #[inline]
58    pub fn get_into(self, idx: usize) -> Option<Ref<'a, T>> {
59        let ptr = self.as_slice().get(idx)? as *const T;
60        Some(Ref::new(ptr, self.ptr.lazy_handle))
61    }
62
63    #[inline]
64    pub fn len(&self) -> usize {
65        self.len
66    }
67
68    pub fn handle(&self) -> &ObjectHandle {
69        self.ptr.handle()
70    }
71
72    pub fn into_tx(self) -> crate::Result<TxRefSlice<T>> {
73        self.as_tx()
74    }
75
76    pub fn as_tx(&self) -> crate::Result<TxRefSlice<T>> {
77        let len = self.len();
78        Ok(unsafe { TxRefSlice::from_ref(self.ptr.as_tx()?, len) })
79    }
80
81    pub unsafe fn into_mut(self) -> crate::Result<RefSliceMut<'a, T>> {
82        self.as_mut()
83    }
84
85    pub unsafe fn as_mut(&self) -> crate::Result<RefSliceMut<'a, T>> {
86        let len = self.len();
87        Ok(unsafe { RefSliceMut::from_ref(self.ptr.as_mut(), len) })
88    }
89
90    pub fn into_ref(self) -> Ref<'a, T> {
91        self.ptr
92    }
93}
94
95impl<'a, T> From<RefSlice<'a, T>> for GlobalPtr<T> {
96    fn from(value: RefSlice<'a, T>) -> Self {
97        GlobalPtr::new(value.handle().id(), value.offset())
98    }
99}
100
101impl<'a, T> Index<usize> for RefSlice<'a, T> {
102    type Output = T;
103
104    fn index(&self, index: usize) -> &Self::Output {
105        let slice = self.as_slice();
106        &slice[index]
107    }
108}
109
110impl<'a, T> Deref for RefSlice<'a, T> {
111    type Target = [T];
112
113    fn deref(&self) -> &Self::Target {
114        self.as_slice()
115    }
116}
117
118impl<'a, T> AsRef<[T]> for RefSlice<'a, T> {
119    fn as_ref(&self) -> &[T] {
120        &*self
121    }
122}
123
124impl<'a, T> Borrow<[T]> for RefSlice<'a, T> {
125    fn borrow(&self) -> &[T] {
126        &*self
127    }
128}
129
130impl<'a, T> Into<ObjectHandle> for RefSlice<'a, T> {
131    fn into(self) -> ObjectHandle {
132        self.handle().clone()
133    }
134}
135
136impl<'a, T> Into<ObjectHandle> for &RefSlice<'a, T> {
137    fn into(self) -> ObjectHandle {
138        self.handle().clone()
139    }
140}
141
142impl<'a, T> AsRef<ObjectHandle> for RefSlice<'a, T> {
143    fn as_ref(&self) -> &ObjectHandle {
144        self.handle()
145    }
146}