1use std::fmt;
2use std::io;
3
4use codeq::OffsetSize;
5
6use crate::ChunkId;
7use crate::Types;
8use crate::WALRecord;
9use crate::num::format_pad9_u64;
10use crate::types::Segment;
11
12struct DebugAsDisplay<'a, T: fmt::Debug>(&'a T);
13
14impl<T: fmt::Debug> fmt::Display for DebugAsDisplay<'_, T> {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 fmt::Debug::fmt(self.0, f)
17 }
18}
19
20pub fn write_record_debug<T: Types, W: io::Write>(
21 w: &mut W,
22 chunk_id: ChunkId,
23 in_chunk_record_index: u64,
24 res: Result<(Segment, WALRecord<T>), io::Error>,
25) -> Result<(), io::Error> {
26 match res {
27 Ok((seg, rec)) => write_ok(
28 w,
29 chunk_id,
30 in_chunk_record_index,
31 &seg,
32 &DebugAsDisplay(&rec),
33 ),
34 Err(e) => writeln!(w, "Error: {}", e),
35 }
36}
37
38pub fn write_record_display<T: Types, W: io::Write>(
41 w: &mut W,
42 chunk_id: ChunkId,
43 in_chunk_record_index: u64,
44 res: Result<(Segment, WALRecord<T>), io::Error>,
45) -> Result<(), io::Error>
46where
47 WALRecord<T>: fmt::Display,
48{
49 match res {
50 Ok((seg, rec)) => {
51 write_ok(w, chunk_id, in_chunk_record_index, &seg, &rec)
52 }
53 Err(e) => writeln!(w, "Error: {}", e),
54 }
55}
56
57fn write_ok<W: io::Write>(
58 w: &mut W,
59 chunk_id: ChunkId,
60 in_chunk_record_index: u64,
61 seg: &Segment,
62 rec: &dyn fmt::Display,
63) -> Result<(), io::Error> {
64 if seg.offset().0 == 0 {
65 writeln!(w, "{}", chunk_id)?;
66 }
67 writeln!(
68 w,
69 " R-{in_chunk_record_index:05}: [{}, {}) {}: {}",
70 format_pad9_u64(*seg.offset()),
71 format_pad9_u64(*seg.end()),
72 seg.size(),
73 rec
74 )
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use crate::testing::TestDisplayTypes;
81
82 fn make_input() -> Result<(Segment, WALRecord<TestDisplayTypes>), io::Error>
83 {
84 Ok((
85 Segment::new(0, 10),
86 WALRecord::Append(3, "hello".to_string()),
87 ))
88 }
89
90 #[test]
91 fn test_write_record_debug_vs_display() {
92 let mut debug_buf = Vec::new();
93 write_record_debug(&mut debug_buf, ChunkId(0), 0, make_input())
94 .unwrap();
95 let debug_out = String::from_utf8(debug_buf).unwrap();
96
97 let mut display_buf = Vec::new();
98 write_record_display(&mut display_buf, ChunkId(0), 0, make_input())
99 .unwrap();
100 let display_out = String::from_utf8(display_buf).unwrap();
101
102 assert!(
104 debug_out.contains(r#"Append(3, "hello")"#),
105 "got: {debug_out}"
106 );
107 assert!(
109 display_out.contains("Append(log_id: 3, payload: hello)"),
110 "got: {display_out}"
111 );
112 }
113}