try_drop/drop_strategies/write/
mod.rs1mod thread_unsafe;
2
3use crate::FallibleTryDropStrategy;
4use parking_lot::Mutex;
5use std::io;
6use std::io::Write;
7use std::string::ToString;
8use std::vec::Vec;
9pub use thread_unsafe::*;
10
11#[cfg_attr(feature = "derives", derive(Debug))]
13pub struct WriteDropStrategy<W: Write> {
14 pub writer: Mutex<W>,
16
17 pub new_line: bool,
19
20 pub prelude: Option<Vec<u8>>,
22}
23
24impl<W: Write> WriteDropStrategy<W> {
25 pub fn new(writer: W) -> Self {
27 Self {
28 writer: Mutex::new(writer),
29 new_line: true,
30 prelude: None,
31 }
32 }
33
34 pub fn new_line(&mut self, new_line: bool) -> &mut Self {
36 self.new_line = new_line;
37 self
38 }
39
40 pub fn prelude(&mut self, prelude: impl Into<Vec<u8>>) -> &mut Self {
42 self.prelude = Some(prelude.into());
43 self
44 }
45}
46
47impl WriteDropStrategy<io::Stderr> {
48 pub fn stderr() -> Self {
50 let mut this = Self::new(io::stderr());
51 this.new_line(true);
52 this
53 }
54}
55
56impl WriteDropStrategy<io::Stdout> {
57 pub fn stdout() -> Self {
59 let mut this = Self::new(io::stdout());
60 this.new_line(true);
61 this
62 }
63}
64
65impl<W: Write> FallibleTryDropStrategy for WriteDropStrategy<W> {
66 type Error = io::Error;
67
68 fn try_handle_error(&self, error: anyhow::Error) -> Result<(), Self::Error> {
69 let mut message = Vec::new();
70
71 if let Some(prelude) = &self.prelude {
72 message.extend_from_slice(prelude);
73 }
74
75 message.extend_from_slice(error.to_string().as_bytes());
76
77 if self.new_line {
78 message.push(b'\n')
79 }
80
81 self.writer.lock().write_all(&message)
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88 use crate::drop_strategies::PanicDropStrategy;
89 use crate::test_utils::{ErrorsOnDrop, Fallible};
90 use crate::PureTryDrop;
91 use std::io::Cursor;
92
93 #[test]
94 fn test_write_drop_strategy() {
95 let mut writer = Cursor::new(Vec::new());
96 let mut strategy = WriteDropStrategy::new(&mut writer);
97 strategy.prelude("error: ");
98 let errors =
99 ErrorsOnDrop::<Fallible, _>::given(strategy, PanicDropStrategy::DEFAULT).adapt();
100 drop(errors);
101 assert_eq!(writer.into_inner(), b"error: this will always fail\n",)
102 }
103}