spdlog/sink/
win_debug_sink.rs1use std::{ffi::OsStr, iter::once};
2
3use crate::{
4 formatter::{Formatter, FormatterContext},
5 sink::{GetSinkProp, Sink, SinkProp},
6 sync::*,
7 ErrorHandler, LevelFilter, Record, Result, StringBuf,
8};
9
10pub struct WinDebugSink {
12 prop: SinkProp,
13}
14
15impl WinDebugSink {
16 #[must_use]
29 pub fn builder() -> WinDebugSinkBuilder {
30 WinDebugSinkBuilder {
31 prop: SinkProp::default(),
32 }
33 }
34
35 #[allow(clippy::new_without_default)]
37 #[deprecated(
38 since = "0.3.0",
39 note = "it may be removed in the future, use `WinDebugSink::builder()` instead"
40 )]
41 #[must_use]
42 pub fn new() -> WinDebugSink {
43 WinDebugSink::builder().build().unwrap()
44 }
45}
46
47impl GetSinkProp for WinDebugSink {
48 fn prop(&self) -> &SinkProp {
49 &self.prop
50 }
51}
52
53impl Sink for WinDebugSink {
54 fn log(&self, record: &Record) -> Result<()> {
55 #[cfg(windows)] use std::os::windows::ffi::OsStrExt;
57
58 let mut string_buf = StringBuf::new();
59 let mut ctx = FormatterContext::new();
60 self.prop
61 .formatter()
62 .format(record, &mut string_buf, &mut ctx)?;
63
64 let wide: Vec<u16> = OsStr::new(&string_buf)
65 .encode_wide()
66 .chain(once(0))
67 .collect();
68 let wide = wide.as_ptr();
69
70 unsafe { winapi::um::debugapi::OutputDebugStringW(wide) }
71
72 Ok(())
73 }
74
75 fn flush(&self) -> Result<()> {
76 Ok(())
77 }
78}
79
80#[allow(missing_docs)]
81pub struct WinDebugSinkBuilder {
82 prop: SinkProp,
83}
84
85impl WinDebugSinkBuilder {
86 #[must_use]
93 pub fn level_filter(self, level_filter: LevelFilter) -> Self {
94 self.prop.set_level_filter(level_filter);
95 self
96 }
97
98 #[must_use]
104 pub fn formatter<F>(self, formatter: F) -> Self
105 where
106 F: Formatter + 'static,
107 {
108 self.prop.set_formatter(formatter);
109 self
110 }
111
112 #[must_use]
117 pub fn error_handler<F: Into<ErrorHandler>>(self, handler: F) -> Self {
118 self.prop.set_error_handler(handler);
119 self
120 }
121
122 pub fn build(self) -> Result<WinDebugSink> {
126 let sink = WinDebugSink { prop: self.prop };
127 Ok(sink)
128 }
129
130 pub fn build_arc(self) -> Result<Arc<WinDebugSink>> {
134 self.build().map(Arc::new)
135 }
136}