-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathwriter.rs
More file actions
101 lines (92 loc) · 2.69 KB
/
Copy pathwriter.rs
File metadata and controls
101 lines (92 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! In-memory writer for testing
//!
//! Provides a thread-safe in-memory buffer that implements Write for use in
//! tests and fuzzing.
use std::io::Write;
use std::sync::{Arc, Mutex};
/// In-memory writer for testing
///
/// This writer accumulates all written data in an in-memory buffer that can be
/// retrieved for assertions. Thread-safe through Arc<Mutex>.
#[derive(Clone, Debug)]
pub struct InMemoryWriter {
buffer: Arc<Mutex<Vec<u8>>>,
}
impl InMemoryWriter {
/// Create a new in-memory writer
#[must_use]
pub fn new() -> Self {
Self {
buffer: Arc::new(Mutex::new(Vec::new())),
}
}
/// Get the raw bytes written to the buffer
///
/// # Panics
///
/// Panics if the mutex is poisoned
#[must_use]
#[expect(
clippy::expect_used,
reason = "mutex poisoning in this test/fuzz helper is the documented contract above"
)]
pub fn get_bytes(&self) -> Vec<u8> {
self.buffer.lock().expect("mutex poisoned").clone()
}
/// Get the buffer contents as a UTF-8 string
///
/// # Panics
///
/// Panics if the buffer contains invalid UTF-8
#[must_use]
#[expect(
clippy::expect_used,
reason = "invalid UTF-8 in this test/fuzz helper is the documented contract above"
)]
pub fn get_string(&self) -> String {
String::from_utf8(self.get_bytes()).expect("buffer contains invalid UTF-8")
}
/// Parse the buffer contents as JSON lines
///
/// # Errors
///
/// Returns an error if any line cannot be parsed as JSON
///
/// # Panics
///
/// Panics if the mutex is poisoned
#[expect(
clippy::expect_used,
reason = "mutex poisoning in this test/fuzz helper is the documented contract above"
)]
pub fn parse_lines(&self) -> Result<Vec<crate::line::Line>, serde_json::Error> {
let buffer = self.buffer.lock().expect("mutex poisoned");
let content_str = String::from_utf8_lossy(&buffer);
content_str
.lines()
.filter(|line| !line.is_empty())
.map(serde_json::from_str)
.collect()
}
}
impl Default for InMemoryWriter {
fn default() -> Self {
Self::new()
}
}
impl Write for InMemoryWriter {
#[expect(
clippy::expect_used,
reason = "mutex poisoning in this test/fuzz helper is treated as a fatal error per the type's documented contract"
)]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.buffer
.lock()
.expect("mutex poisoned")
.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}