1use core::{
2 mem,
3 ops::{Deref, DerefMut},
4 slice,
5};
6
7pub trait IoSlice<'a>: Sized + Deref<Target = [u8]> {
8 fn advance(&mut self, n: usize);
9
10 fn advance_slices(bufs: &mut &mut [Self], n: usize) {
11 let mut remove = 0;
13 let mut accumulated_len = 0;
15 for buf in bufs.iter() {
16 if accumulated_len + buf.len() > n {
17 break;
18 } else {
19 accumulated_len += buf.len();
20 remove += 1;
21 }
22 }
23
24 *bufs = &mut mem::take(bufs)[remove..];
25 if bufs.is_empty() {
26 assert!(
27 n == accumulated_len,
28 "advancing io slices beyond their length"
29 );
30 } else {
31 bufs[0].advance(n - accumulated_len)
32 }
33 }
34}
35
36pub trait IoSliceMut<'a>: Sized + DerefMut<Target = [u8]> {
37 fn advance(&mut self, n: usize);
38
39 fn advance_slices(bufs: &mut &mut [Self], n: usize) {
40 let mut remove = 0;
42 let mut accumulated_len = 0;
44 for buf in bufs.iter() {
45 if accumulated_len + buf.len() > n {
46 break;
47 } else {
48 accumulated_len += buf.len();
49 remove += 1;
50 }
51 }
52
53 *bufs = &mut mem::take(bufs)[remove..];
54 if bufs.is_empty() {
55 assert!(
56 n == accumulated_len,
57 "advancing io slices beyond their length"
58 );
59 } else {
60 bufs[0].advance(n - accumulated_len)
61 }
62 }
63}
64
65#[derive(Copy, PartialEq, Eq, Clone, Debug)]
66pub enum SeekFrom {
67 Start(usize),
68 Current(isize),
69 End(isize),
70}
71
72impl<'a> IoSlice<'a> for &'a [u8] {
73 fn advance(&mut self, n: usize) {
74 *self = &self[n..];
75 }
76}
77
78impl<'a> IoSliceMut<'a> for &'a mut [u8] {
79 fn advance(&mut self, n: usize) {
80 *self = unsafe {
81 let (ptr, len) = (*self as *mut [u8]).to_raw_parts();
82 let ptr = ptr.cast::<u8>().add(n);
83 slice::from_raw_parts_mut(ptr, len - n)
84 };
85 }
86}
87
88#[cfg(feature = "std")]
89impl<'a> IoSlice<'a> for std::io::IoSlice<'a> {
90 fn advance(&mut self, n: usize) {
91 self.advance(n)
92 }
93
94 fn advance_slices(bufs: &mut &mut [Self], n: usize) {
95 std::io::IoSlice::advance_slices(bufs, n)
96 }
97}
98
99#[cfg(feature = "std")]
100impl<'a> IoSliceMut<'a> for std::io::IoSliceMut<'a> {
101 fn advance(&mut self, n: usize) {
102 self.advance(n)
103 }
104
105 fn advance_slices(bufs: &mut &mut [Self], n: usize) {
106 std::io::IoSliceMut::advance_slices(bufs, n)
107 }
108}
109
110#[cfg(feature = "std")]
111impl From<SeekFrom> for std::io::SeekFrom {
112 fn from(this: SeekFrom) -> Self {
113 match this {
114 SeekFrom::Start(pos) => std::io::SeekFrom::Start(pos as u64),
115 SeekFrom::Current(pos) => std::io::SeekFrom::Current(pos as i64),
116 SeekFrom::End(pos) => std::io::SeekFrom::End(pos as i64),
117 }
118 }
119}
120
121#[cfg(feature = "std")]
122impl From<std::io::SeekFrom> for SeekFrom {
123 fn from(this: std::io::SeekFrom) -> Self {
124 match this {
125 std::io::SeekFrom::Start(pos) => SeekFrom::Start(pos as usize),
126 std::io::SeekFrom::Current(pos) => SeekFrom::Current(pos as isize),
127 std::io::SeekFrom::End(pos) => SeekFrom::End(pos as isize),
128 }
129 }
130}