twizzler/ptr/resolved/
resolved_slice.rs1use 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}