7 个版本
0.0.7 | 2021 年 4 月 27 日 |
---|---|
0.0.6 | 2021 年 4 月 11 日 |
2619 在 Rust 模式
每月 21 下载
125KB
2K SLoC
示例
一个类似于 Read
的特质实现,以更好地支持未初始化内存。
use std::mem::MaybeUninit;
use uninit_tools::buffer::{Buffer, BufferRef};
use uninit_tools::traits::Initialize;
pub trait MyRead {
// NOTE: The function does not return any count, since the buffer keeps track of that.
//
// Rather than using `&mut Buffer<T>` directly, we use `BufferRef<'_, T>` to prevent the
// caller from replacing the buffer that is being filled with something different. It also
// gives the `Read` implementor a reduced subset of the functionality, to that it cannot
// for example read the bytes that are already written into the buffer.
fn read<'buffer, T>(&mut self, buffer: BufferRef<'buffer, T>) -> io::Result<()>
where
T: Initialize<Item = u8>,
;
}
impl MyRead for &[u8] {
fn read<'buffer, T>(&mut self, mut buffer: BufferRef<'buffer, T>) -> io::Result<()>
where
T: Initialize<Item = u8>,
{
// Get the minimum number of bytes to copy. Note that it will panic if the source slice
// were to overflow, as with the regular `copy_from_slice` function for regular slices.
let min = std::cmp::min(self.len(), buffer.remaining());
// Advance the buffer by simply copying the source slice.
buffer.append(&self[..min]);
Ok(())
}
}
// NOTE: The `Initialize` trait is implemented for arrays of all sizes, thanks to const
// generics.
let array = [MaybeUninit::uninit(); 32];
let len = array.len();
let mut buf = Buffer::uninit(array);
let original_stupid_text: &[u8] = b"copying is expensive!";
let mut stupid_text = original_stupid_text;
// Read as many bytes as possible.
stupid_text.read(buf.by_ref())?;
// Note that while we cannot do anything useful with the rest of the buffer, we can still use
// it as the destination of even more I/O, or simply check its length like we do here.
assert_eq!(buf.remaining(), len - original_stupid_text.len());
请注意,这可能不是 Read
特质的最佳实现,但它确实表明未初始化内存的处理可以完全在安全代码中完成,且相对方便。
(如果将其纳入 std::io::Read
,可能会有一个更简单的 unsafe 函数,默认使用更安全的包装器。)