diff --git a/src/tests/read_write.rs b/src/tests/read_write.rs index 9060c03..afcfdfc 100644 --- a/src/tests/read_write.rs +++ b/src/tests/read_write.rs @@ -1,6 +1,6 @@ use super::Rb; use crate::{storage::Static, traits::*}; -use std::io; +use std::io::{self, Read}; macro_rules! assert_eq_kind { ($left:expr, $right:expr) => { @@ -107,3 +107,28 @@ fn count() { assert_eq!(cons1.pop_slice(&mut tmp), 4); assert_eq!(tmp[0..4], [3, 4, 5, 6]); } + +#[test] +fn read_from() { + struct Reader; + + impl Read for Reader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + for b in buf.iter_mut() { + // Read buffer before writing to ensure its initialized. + *b = b.wrapping_add(1); + } + buf.fill(2); + Ok(buf.len()) + } + } + + let mut rb = Rb::>::default(); + let (mut prod, mut cons) = rb.split_ref(); + prod.try_push(1).unwrap(); + assert_eq!(cons.try_pop().unwrap(), 1); + + assert_eq!(prod.read_from(&mut Reader, None).unwrap().unwrap(), 3); + + assert!(cons.pop_iter().eq([2; 3])); +} diff --git a/src/traits/producer.rs b/src/traits/producer.rs index 35372e6..8b7f8d0 100644 --- a/src/traits/producer.rs +++ b/src/traits/producer.rs @@ -136,7 +136,12 @@ pub trait Producer: Observer { if count == 0 { return None; } - let left_init = unsafe { slice_assume_init_mut(&mut left[..count]) }; + + let buf = &mut left[..count]; + // Initialize memory before read. It's an overhead but there's no way to read to uninit buffer in stable Rust yet. + // TODO: Use `reader.read_buf` when it stabilized (see https://github.com/rust-lang/rust/issues/78485). + buf.fill(MaybeUninit::new(0)); + let left_init = unsafe { slice_assume_init_mut(buf) }; let read_count = match reader.read(left_init) { Ok(n) => n,