Skip to content

Commit fdec431

Browse files
committed
support writing to uninit slices
1 parent 3f83185 commit fdec431

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

embedded-io-async/src/impls/slice_mut.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::mem;
1+
use core::mem::{self, MaybeUninit};
22
use embedded_io::SliceWriteError;
33

44
use crate::Write;
@@ -25,3 +25,28 @@ impl Write for &mut [u8] {
2525
Ok(amt)
2626
}
2727
}
28+
29+
/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting
30+
/// its data.
31+
///
32+
/// Note that writing updates the slice to point to the yet unwritten part.
33+
/// The slice will be empty when it has been completely overwritten.
34+
///
35+
/// If the number of bytes to be written exceeds the size of the slice, write operations will
36+
/// return short writes: ultimately, `Ok(0)`; in this situation, `write_all` returns an error of
37+
/// kind `ErrorKind::WriteZero`.
38+
impl Write for &mut [MaybeUninit<u8>] {
39+
#[inline]
40+
async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
41+
let amt = core::cmp::min(buf.len(), self.len());
42+
if !buf.is_empty() && amt == 0 {
43+
return Err(SliceWriteError::Full);
44+
}
45+
let (a, b) = mem::take(self).split_at_mut(amt);
46+
buf.split_at(amt).0.iter().enumerate().for_each(|(index,byte)| {
47+
a[index].write(*byte);
48+
});
49+
*self = b;
50+
Ok(amt)
51+
}
52+
}

embedded-io/src/impls/slice_mut.rs

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{Error, ErrorKind, ErrorType, SliceWriteError, Write, WriteReady};
2-
use core::mem;
2+
use core::mem::{self, MaybeUninit};
33

44
impl Error for SliceWriteError {
55
fn kind(&self) -> ErrorKind {
@@ -9,10 +9,6 @@ impl Error for SliceWriteError {
99
}
1010
}
1111

12-
impl ErrorType for &mut [u8] {
13-
type Error = SliceWriteError;
14-
}
15-
1612
impl core::fmt::Display for SliceWriteError {
1713
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1814
write!(f, "{self:?}")
@@ -21,6 +17,10 @@ impl core::fmt::Display for SliceWriteError {
2117

2218
impl core::error::Error for SliceWriteError {}
2319

20+
impl ErrorType for &mut [u8] {
21+
type Error = SliceWriteError;
22+
}
23+
2424
/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting
2525
/// its data.
2626
///
@@ -54,3 +54,43 @@ impl WriteReady for &mut [u8] {
5454
Ok(true)
5555
}
5656
}
57+
58+
impl ErrorType for &mut [MaybeUninit<u8>] {
59+
type Error = SliceWriteError;
60+
}
61+
62+
/// Write is implemented for `&mut [MaybeUninit<u8>]` by copying into the slice, overwriting
63+
/// its data.
64+
///
65+
/// Note that writing updates the slice to point to the yet unwritten part.
66+
/// The slice will be empty when it has been completely overwritten.
67+
///
68+
/// If the number of bytes to be written exceeds the size of the slice, write operations will
69+
/// return short writes: ultimately, a `SliceWriteError::Full`.
70+
impl Write for &mut [MaybeUninit<u8>] {
71+
#[inline]
72+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
73+
let amt = core::cmp::min(buf.len(), self.len());
74+
if !buf.is_empty() && amt == 0 {
75+
return Err(SliceWriteError::Full);
76+
}
77+
let (a, b) = mem::take(self).split_at_mut(amt);
78+
buf.split_at(amt).0.iter().enumerate().for_each(|(index,byte)| {
79+
a[index].write(*byte);
80+
});
81+
*self = b;
82+
Ok(amt)
83+
}
84+
85+
#[inline]
86+
fn flush(&mut self) -> Result<(), Self::Error> {
87+
Ok(())
88+
}
89+
}
90+
91+
impl WriteReady for &mut [MaybeUninit<u8>] {
92+
#[inline]
93+
fn write_ready(&mut self) -> Result<bool, Self::Error> {
94+
Ok(true)
95+
}
96+
}

0 commit comments

Comments
 (0)