spdlog/sink/
win_debug_sink.rs1use std::{ffi::OsStr, iter::once};
2
3use crate::{
4 formatter::FormatterContext,
5 sink::{helper, Sink},
6 Record, Result, StringBuf,
7};
8
9pub struct WinDebugSink {
11 common_impl: helper::CommonImpl,
12}
13
14impl WinDebugSink {
15 #[must_use]
28 pub fn builder() -> WinDebugSinkBuilder {
29 WinDebugSinkBuilder {
30 common_builder_impl: helper::CommonBuilderImpl::new(),
31 }
32 }
33
34 #[allow(clippy::new_without_default)]
36 #[deprecated(
37 since = "0.3.0",
38 note = "it may be removed in the future, use `WinDebugSink::builder()` instead"
39 )]
40 #[must_use]
41 pub fn new() -> WinDebugSink {
42 WinDebugSink::builder().build().unwrap()
43 }
44}
45
46impl Sink for WinDebugSink {
47 fn log(&self, record: &Record) -> Result<()> {
48 #[cfg(windows)] use std::os::windows::ffi::OsStrExt;
50
51 let mut string_buf = StringBuf::new();
52 let mut ctx = FormatterContext::new();
53 self.common_impl
54 .formatter
55 .read()
56 .format(record, &mut string_buf, &mut ctx)?;
57
58 let wide: Vec<u16> = OsStr::new(&string_buf)
59 .encode_wide()
60 .chain(once(0))
61 .collect();
62 let wide = wide.as_ptr();
63
64 unsafe { winapi::um::debugapi::OutputDebugStringW(wide) }
65
66 Ok(())
67 }
68
69 fn flush(&self) -> Result<()> {
70 Ok(())
71 }
72
73 helper::common_impl!(@Sink: common_impl);
74}
75
76#[allow(missing_docs)]
77pub struct WinDebugSinkBuilder {
78 common_builder_impl: helper::CommonBuilderImpl,
79}
80
81impl WinDebugSinkBuilder {
82 helper::common_impl!(@SinkBuilder: common_builder_impl);
83
84 pub fn build(self) -> Result<WinDebugSink> {
86 let sink = WinDebugSink {
87 common_impl: helper::CommonImpl::from_builder(self.common_builder_impl),
88 };
89 Ok(sink)
90 }
91}