bytesbuf_io/testing/
fake_write.rs1use std::convert::Infallible;
5
6use bytesbuf::mem::testing::TransparentMemory;
7use bytesbuf::mem::{HasMemory, Memory, MemoryShared, OpaqueMemory};
8use bytesbuf::{BytesBuf, BytesView};
9
10use crate::Write;
11
12#[derive(Debug)]
16pub struct FakeWrite {
17 contents: BytesBuf,
18
19 memory: OpaqueMemory,
20}
21
22impl FakeWrite {
23 #[must_use]
25 pub fn builder() -> FakeWriteBuilder {
26 FakeWriteBuilder {
27 memory: OpaqueMemory::new(TransparentMemory::new()),
28 }
29 }
30
31 #[must_use]
33 pub fn new() -> Self {
34 Self::builder().build()
35 }
36
37 #[must_use]
39 pub fn into_contents(mut self) -> BytesView {
40 self.contents.consume_all()
41 }
42
43 #[must_use]
47 pub fn contents(&self) -> &BytesBuf {
48 &self.contents
49 }
50
51 #[expect(clippy::unused_async, reason = "API compatibility between trait and inherent fn")]
57 pub async fn write(&mut self, data: BytesView) -> Result<(), Infallible> {
58 self.contents.put_bytes(data);
59 Ok(())
60 }
61
62 #[must_use]
64 pub fn memory(&self) -> impl MemoryShared {
65 self.memory.clone()
66 }
67
68 #[must_use]
86 pub fn reserve(&self, min_bytes: usize) -> BytesBuf {
87 self.memory.reserve(min_bytes)
88 }
89}
90
91impl Default for FakeWrite {
92 fn default() -> Self {
93 Self::new()
94 }
95}
96
97#[cfg_attr(coverage_nightly, coverage(off))] impl Write for FakeWrite {
99 type Error = Infallible;
100
101 #[cfg_attr(test, mutants::skip)] async fn write(&mut self, data: BytesView) -> Result<(), Infallible> {
103 self.write(data).await
104 }
105}
106
107#[cfg_attr(coverage_nightly, coverage(off))] impl Memory for FakeWrite {
109 #[cfg_attr(test, mutants::skip)] fn reserve(&self, min_bytes: usize) -> BytesBuf {
111 self.reserve(min_bytes)
112 }
113}
114
115#[cfg_attr(coverage_nightly, coverage(off))] impl HasMemory for FakeWrite {
117 #[cfg_attr(test, mutants::skip)] fn memory(&self) -> impl MemoryShared {
119 self.memory()
120 }
121}
122
123#[derive(Debug)]
127pub struct FakeWriteBuilder {
128 memory: OpaqueMemory,
129}
130
131impl FakeWriteBuilder {
132 #[must_use]
136 pub fn memory(mut self, memory: OpaqueMemory) -> Self {
137 self.memory = memory;
138 self
139 }
140
141 #[must_use]
143 pub fn build(self) -> FakeWrite {
144 FakeWrite {
145 contents: BytesBuf::new(),
146 memory: self.memory,
147 }
148 }
149}
150
151#[cfg(test)]
152#[cfg_attr(coverage_nightly, coverage(off))]
153mod tests {
154 use std::sync::Arc;
155 use std::sync::atomic::{AtomicBool, Ordering};
156
157 use bytesbuf::mem::CallbackMemory;
158 use testing_aids::async_test;
159
160 use super::*;
161 use crate::WriteExt;
162
163 #[test]
164 fn smoke_test() {
165 async_test(async || {
166 let mut write_stream = FakeWrite::new();
167
168 write_stream
169 .prepare_and_write(1234, |mut buf| {
170 buf.put_byte(1);
171 buf.put_byte(2);
172 buf.put_byte(3);
173 Ok::<BytesView, Infallible>(buf.consume_all())
174 })
175 .await
176 .unwrap();
177
178 assert_eq!(write_stream.contents().len(), 3);
179
180 let mut contents = write_stream.into_contents();
181 assert_eq!(contents.len(), 3);
182
183 assert_eq!(contents.get_byte(), 1);
184 assert_eq!(contents.get_byte(), 2);
185 assert_eq!(contents.get_byte(), 3);
186 assert_eq!(contents.len(), 0);
187 });
188 }
189
190 #[test]
191 fn default_returns_working_instance() {
192 async_test(async || {
193 let mut write_stream = FakeWrite::default();
194
195 write_stream
196 .prepare_and_write(10, |mut buf| {
197 buf.put_byte(42);
198 Ok::<BytesView, Infallible>(buf.consume_all())
199 })
200 .await
201 .unwrap();
202
203 assert_eq!(write_stream.contents().len(), 1);
204
205 let mut contents = write_stream.into_contents();
206 assert_eq!(contents.get_byte(), 42);
207 });
208 }
209
210 #[test]
211 fn memory_returns_configured_provider() {
212 let callback_called = Arc::new(AtomicBool::new(false));
213
214 let custom_memory = OpaqueMemory::new(CallbackMemory::new({
215 let callback_called = Arc::clone(&callback_called);
216 move |min_bytes| {
217 callback_called.store(true, Ordering::SeqCst);
218 TransparentMemory::new().reserve(min_bytes)
219 }
220 }));
221
222 let write_stream = FakeWrite::builder().memory(custom_memory).build();
223
224 let stream_memory = write_stream.memory();
226 let _buf = stream_memory.reserve(10);
227
228 assert!(
229 callback_called.load(Ordering::SeqCst),
230 "Custom memory callback should have been called"
231 );
232 }
233}