abi_stable/std_types/slices.rs
1//! Contains the ffi-safe equivalent of `&'a [T]`.
2
3use std::{
4 borrow::Borrow,
5 io::{self, BufRead, Read},
6 marker::PhantomData,
7 ops::{Deref, Index},
8 slice::SliceIndex,
9};
10
11#[allow(unused_imports)]
12use core_extensions::SelfOps;
13
14use serde::{Deserialize, Deserializer, Serialize, Serializer};
15
16use crate::std_types::RVec;
17
18mod private {
19 use super::*;
20
21 /// Ffi-safe equivalent of `&'a [T]`
22 ///
23 /// As of the writing this documentation the abi stability of `&[T]` is
24 /// not yet guaranteed.
25 ///
26 /// # Lifetime problems
27 ///
28 /// Because `RSlice` dereferences into a slice, you can call slice methods on it.
29 ///
30 /// If you call a slice method that returns a borrow into the slice,
31 /// it will have the lifetime of the `let slice: RSlice<'a, [T]>` variable instead of the `'a`
32 /// lifetime that it's parameterized over.
33 ///
34 /// To get a slice with the same lifetime as an `RSlice`,
35 /// one must use the `RSlice::as_slice` method.
36 ///
37 ///
38 /// Example of what would not work:
39 ///
40 /// ```compile_fail
41 /// use abi_stable::std_types::RSlice;
42 ///
43 /// fn into_slice<'a, T>(slic: RSlice<'a, T>) -> &'a [T] {
44 /// &*slic
45 /// }
46 /// ```
47 ///
48 /// Example of what would work:
49 ///
50 /// ```
51 /// use abi_stable::std_types::RSlice;
52 ///
53 /// fn into_slice<'a, T>(slic: RSlice<'a, T>) -> &'a [T] {
54 /// slic.as_slice()
55 /// }
56 /// ```
57 ///
58 ///
59 ///
60 /// # Example
61 ///
62 /// Defining an extern fn that returns a reference to
63 /// the first element that compares equal to a parameter.
64 ///
65 /// ```
66 /// use abi_stable::{sabi_extern_fn, std_types::RSlice};
67 ///
68 /// #[sabi_extern_fn]
69 /// pub fn find_first_mut<'a, T>(slice_: RSlice<'a, T>, element: &T) -> Option<&'a T>
70 /// where
71 /// T: std::cmp::PartialEq,
72 /// {
73 /// slice_
74 /// .iter()
75 /// .position(|x| x == element)
76 /// .map(|i| &slice_.as_slice()[i])
77 /// }
78 ///
79 /// ```
80 #[repr(C)]
81 #[derive(StableAbi)]
82 #[sabi(bound(T: 'a))]
83 //#[sabi(debug_print)]
84 pub struct RSlice<'a, T> {
85 data: *const T,
86 length: usize,
87 _marker: PhantomData<&'a T>,
88 }
89
90 impl_from_rust_repr! {
91 impl['a, T] From<&'a [T]> for RSlice<'a, T> {
92 fn(this){
93 Self::from_slice(this)
94 }
95 }
96 }
97
98 impl<'a, T: 'a> RSlice<'a, T> {
99 const _EMPTY_SLICE: &'a [T] = &[];
100
101 /// An empty slice.
102 pub const EMPTY: Self = RSlice {
103 data: {
104 let v: &[T] = Self::_EMPTY_SLICE;
105 v.as_ptr()
106 },
107 length: 0,
108 _marker: PhantomData,
109 };
110
111 /// Constructs an `RSlice<'a, T>` from a pointer to the first element,
112 /// and a length.
113 ///
114 /// # Safety
115 ///
116 /// Callers must ensure that:
117 ///
118 /// - `ptr_` points to valid memory,
119 ///
120 /// - `ptr_ .. ptr+len` range is accessible memory.
121 ///
122 /// - `ptr_` is aligned to `T`.
123 ///
124 /// - The data `ptr_` points to must be valid for the `'a` lifetime.
125 ///
126 /// # Examples
127 ///
128 /// This function unsafely converts a `&[T]` to an `RSlice<T>`,
129 /// equivalent to doing `RSlice::from_slice`.
130 ///
131 /// ```
132 /// use abi_stable::std_types::RSlice;
133 ///
134 /// fn convert<T>(slice_: &[T]) -> RSlice<'_, T> {
135 /// unsafe { RSlice::from_raw_parts(slice_.as_ptr(), slice_.len()) }
136 /// }
137 ///
138 /// ```
139 pub const unsafe fn from_raw_parts(ptr_: *const T, len: usize) -> Self {
140 Self {
141 data: ptr_,
142 length: len,
143 _marker: PhantomData,
144 }
145 }
146
147 #[doc(hidden)]
148 pub const unsafe fn from_raw_parts_with_lifetime(slice: &'a [T], len: usize) -> Self {
149 Self {
150 data: slice.as_ptr(),
151 length: len,
152 _marker: PhantomData,
153 }
154 }
155 }
156
157 impl<'a, T> RSlice<'a, T> {
158 conditionally_const! {
159 feature = "rust_1_64"
160 /// Creates an `&'a [T]` with access to all the elements of this slice.
161 ///
162 ;
163 ///
164 /// # Example
165 ///
166 /// ```
167 /// use abi_stable::std_types::RSlice;
168 ///
169 /// assert_eq!(RSlice::from_slice(&[0, 1, 2, 3]).as_slice(), &[0, 1, 2, 3]);
170 ///
171 /// ```
172 pub fn as_slice(&self) -> &'a [T] {
173 unsafe { ::std::slice::from_raw_parts(self.data, self.length) }
174 }
175 }
176
177 /// Gets a raw pointer to the start of the slice.
178 pub const fn as_ptr(&self) -> *const T {
179 self.data
180 }
181
182 /// The length (in elements) of this slice.
183 ///
184 /// # Example
185 ///
186 /// ```
187 /// use abi_stable::std_types::RSlice;
188 ///
189 /// assert_eq!(RSlice::<u8>::from_slice(&[]).len(), 0);
190 /// assert_eq!(RSlice::from_slice(&[0]).len(), 1);
191 /// assert_eq!(RSlice::from_slice(&[0, 1]).len(), 2);
192 ///
193 /// ```
194 #[inline]
195 pub const fn len(&self) -> usize {
196 self.length
197 }
198
199 /// Whether this slice is empty.
200 ///
201 /// # Example
202 ///
203 /// ```
204 /// use abi_stable::std_types::RSlice;
205 ///
206 /// assert_eq!(RSlice::<u8>::from_slice(&[]).is_empty(), true);
207 /// assert_eq!(RSlice::from_slice(&[0]).is_empty(), false);
208 /// assert_eq!(RSlice::from_slice(&[0, 1]).is_empty(), false);
209 ///
210 /// ```
211 #[inline]
212 pub const fn is_empty(&self) -> bool {
213 self.length == 0
214 }
215 }
216}
217
218pub use self::private::RSlice;
219
220impl<'a, T> RSlice<'a, T> {
221 /// Creates an empty slice
222 pub const fn empty() -> Self {
223 Self::EMPTY
224 }
225
226 /// Converts a reference to `T` to a single element `RSlice<'a, T>`.
227 ///
228 /// Note: this function does not copy anything.
229 ///
230 /// # Example
231 ///
232 /// ```
233 /// use abi_stable::std_types::RSlice;
234 ///
235 /// assert_eq!(RSlice::from_ref(&0), RSlice::from_slice(&[0]));
236 /// assert_eq!(RSlice::from_ref(&1), RSlice::from_slice(&[1]));
237 /// assert_eq!(RSlice::from_ref(&2), RSlice::from_slice(&[2]));
238 ///
239 /// ```
240 pub const fn from_ref(ref_: &'a T) -> Self {
241 unsafe { Self::from_raw_parts(ref_, 1) }
242 }
243
244 /// Converts a `&[T]` to an `RSlice<'_, T>`.
245 ///
246 /// # Example
247 ///
248 /// ```
249 /// use abi_stable::std_types::RSlice;
250 ///
251 /// let empty: &[u8] = &[];
252 ///
253 /// assert_eq!(RSlice::<u8>::from_slice(&[]).as_slice(), empty);
254 /// assert_eq!(RSlice::from_slice(&[0]).as_slice(), &[0][..]);
255 /// assert_eq!(RSlice::from_slice(&[0, 1]).as_slice(), &[0, 1][..]);
256 ///
257 /// ```
258 #[inline]
259 pub const fn from_slice(slic: &'a [T]) -> Self {
260 unsafe { RSlice::from_raw_parts(slic.as_ptr(), slic.len()) }
261 }
262
263 /// Creates an `RSlice<'a, T>` with access to the `range` range of elements.
264 ///
265 /// This is an inherent method instead of an implementation of the
266 /// `std::ops::Index` trait because it does not return a reference.
267 ///
268 /// # Example
269 ///
270 /// ```
271 /// use abi_stable::std_types::RSlice;
272 ///
273 /// let slic = RSlice::from_slice(&[0, 1, 2, 3]);
274 ///
275 /// assert_eq!(slic.slice(..), RSlice::from_slice(&[0, 1, 2, 3]));
276 /// assert_eq!(slic.slice(..2), RSlice::from_slice(&[0, 1]));
277 /// assert_eq!(slic.slice(2..), RSlice::from_slice(&[2, 3]));
278 /// assert_eq!(slic.slice(1..3), RSlice::from_slice(&[1, 2]));
279 ///
280 /// ```
281 pub fn slice<I>(&self, i: I) -> RSlice<'a, T>
282 where
283 [T]: Index<I, Output = [T]>,
284 {
285 self.as_slice().index(i).into()
286 }
287
288 /// Creates a new `RVec<T>` and clones all the elements of this slice into it.
289 ///
290 /// # Example
291 ///
292 /// ```
293 /// use abi_stable::std_types::{RSlice, RVec};
294 ///
295 /// let slic = RSlice::from_slice(&[0, 1, 2, 3]);
296 ///
297 /// assert_eq!(slic.slice(..).to_rvec(), RVec::from_slice(&[0, 1, 2, 3]));
298 /// assert_eq!(slic.slice(..2).to_rvec(), RVec::from_slice(&[0, 1]));
299 /// assert_eq!(slic.slice(2..).to_rvec(), RVec::from_slice(&[2, 3]));
300 /// assert_eq!(slic.slice(1..3).to_rvec(), RVec::from_slice(&[1, 2]));
301 ///
302 /// ```
303 pub fn to_rvec(&self) -> RVec<T>
304 where
305 T: Clone,
306 {
307 self.to_vec().into()
308 }
309
310 /// Transmutes n `RSlice<'a, T>` to a `RSlice<'a, U>`
311 ///
312 /// # Safety
313 ///
314 /// This has the same safety requirements as calling [`std::mem::transmute`] to
315 /// transmute a `&'a [T]` to a `&'a [U]`.
316 ///
317 /// [`std::mem::transmute`]: https://doc.rust-lang.org/std/mem/fn.transmute.html
318 pub const unsafe fn transmute<U>(self) -> RSlice<'a, U>
319 where
320 U: 'a,
321 {
322 let len = self.len();
323 unsafe { RSlice::from_raw_parts(self.as_ptr() as *const T as *const U, len) }
324 }
325}
326
327unsafe impl<'a, T> Send for RSlice<'a, T> where &'a [T]: Send {}
328unsafe impl<'a, T> Sync for RSlice<'a, T> where &'a [T]: Sync {}
329
330impl<'a, T> Copy for RSlice<'a, T> {}
331
332impl<'a, T> Clone for RSlice<'a, T> {
333 fn clone(&self) -> Self {
334 *self
335 }
336}
337
338impl<'a, T> Default for RSlice<'a, T> {
339 fn default() -> Self {
340 (&[][..]).into()
341 }
342}
343
344impl<'a, T> IntoIterator for RSlice<'a, T> {
345 type Item = &'a T;
346
347 type IntoIter = ::std::slice::Iter<'a, T>;
348
349 fn into_iter(self) -> ::std::slice::Iter<'a, T> {
350 self.as_slice().iter()
351 }
352}
353
354impl<'a, T, I: SliceIndex<[T]>> Index<I> for RSlice<'a, T> {
355 type Output = I::Output;
356
357 #[inline]
358 fn index(&self, index: I) -> &Self::Output {
359 self.get(index).expect("Index out of bounds")
360 }
361}
362
363slice_like_impl_cmp_traits! {
364 impl[] RSlice<'_, T>,
365 where[];
366 Vec<U>,
367 [U],
368 &[U],
369}
370
371slice_like_impl_cmp_traits! {
372 impl[const N: usize] RSlice<'_, T>,
373 where[];
374 [U; N],
375}
376
377slice_like_impl_cmp_traits! {
378 impl[] RSlice<'_, T>,
379 where[T: Clone, U: Clone];
380 std::borrow::Cow<'_, [U]>,
381 crate::std_types::RCowSlice<'_, U>,
382}
383
384impl<'a, T: 'a> Deref for RSlice<'a, T> {
385 type Target = [T];
386
387 fn deref(&self) -> &Self::Target {
388 self.as_slice()
389 }
390}
391
392impl_into_rust_repr! {
393 impl['a, T] Into<&'a [T]> for RSlice<'a, T> {
394 fn(this){
395 this.as_slice()
396 }
397 }
398}
399
400////////////////////
401
402impl<'a, T: 'a> Borrow<[T]> for RSlice<'a, T> {
403 fn borrow(&self) -> &[T] {
404 self
405 }
406}
407
408impl<'a, T: 'a> AsRef<[T]> for RSlice<'a, T> {
409 fn as_ref(&self) -> &[T] {
410 self
411 }
412}
413
414///////////////////
415
416impl<'de, T> Deserialize<'de> for RSlice<'de, T>
417where
418 &'de [T]: Deserialize<'de>,
419{
420 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
421 where
422 D: Deserializer<'de>,
423 {
424 <&'de [T] as Deserialize<'de>>::deserialize(deserializer).map(Self::from)
425 }
426}
427
428impl<'a, T> Serialize for RSlice<'a, T>
429where
430 T: Serialize,
431{
432 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
433 where
434 S: Serializer,
435 {
436 self.as_slice().serialize(serializer)
437 }
438}
439
440///////////////////////////////////////////////////////////////////////////////
441
442impl<'a> Read for RSlice<'a, u8> {
443 #[inline]
444 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
445 let mut this = self.as_slice();
446 let ret = this.read(buf);
447 *self = this.into();
448 ret
449 }
450
451 #[inline]
452 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
453 let mut this = self.as_slice();
454 let ret = this.read_exact(buf);
455 *self = this.into();
456 ret
457 }
458
459 #[inline]
460 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
461 let mut this = self.as_slice();
462 let ret = this.read_to_end(buf);
463 *self = this.into();
464 ret
465 }
466}
467
468impl<'a> BufRead for RSlice<'a, u8> {
469 #[inline]
470 fn fill_buf(&mut self) -> io::Result<&[u8]> {
471 Ok(&**self)
472 }
473
474 #[inline]
475 fn consume(&mut self, amt: usize) {
476 *self = self.slice(amt..);
477 }
478}
479
480///////////////////////////////////////////////////////////////////////////////
481
482#[allow(dead_code)]
483type Slice<'a, T> = &'a [T];
484
485shared_impls! {
486 mod = slice_impls
487 new_type = RSlice['a][T],
488 original_type = Slice,
489}
490
491////////////////////////////////////////////////////////////////////////////////
492
493//#[cfg(test)]
494#[cfg(all(test, not(feature = "only_new_tests")))]
495mod test {
496 use super::*;
497
498 #[test]
499 fn from_to_slice() {
500 let a = "what the hell".as_bytes();
501 let b = RSlice::from(a);
502
503 assert_eq!(a, &*b);
504 assert_eq!(a.len(), b.len());
505 }
506
507 #[cfg(feature = "rust_1_64")]
508 #[test]
509 fn const_as_slice_test() {
510 const RS: RSlice<'_, u8> = RSlice::from_slice(&[3, 5, 8]);
511 const SLICE: &[u8] = RS.as_slice();
512
513 assert_eq!(SLICE, [3, 5, 8]);
514 }
515
516 #[test]
517 fn test_index() {
518 let s = rslice![1, 2, 3, 4, 5];
519
520 assert_eq!(s.index(0), &1);
521 assert_eq!(s.index(4), &5);
522 assert_eq!(s.index(..2), rslice![1, 2]);
523 assert_eq!(s.index(1..2), rslice![2]);
524 assert_eq!(s.index(3..), rslice![4, 5]);
525 }
526}