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
102
103
104
105
106
107
use log;
use log::Record;
use std::io::{self, Write};
use crate::logger::Duplicate;
use crate::writers::FileLogWriter;
use crate::writers::LogWriter;
use crate::FormatFunction;
#[allow(clippy::large_enum_variant)]
pub enum PrimaryWriter {
StdErrWriter(StdErrWriter),
ExtendedFileWriter(ExtendedFileWriter),
}
impl PrimaryWriter {
pub fn file(duplicate: Duplicate, file_log_writer: FileLogWriter) -> PrimaryWriter {
PrimaryWriter::ExtendedFileWriter(ExtendedFileWriter {
duplicate,
file_log_writer,
})
}
pub fn stderr(format: FormatFunction) -> PrimaryWriter {
PrimaryWriter::StdErrWriter(StdErrWriter { format })
}
pub fn write(&self, record: &Record) -> io::Result<()> {
match *self {
PrimaryWriter::StdErrWriter(ref w) => w.write(record),
PrimaryWriter::ExtendedFileWriter(ref w) => w.write(record),
}
}
pub fn flush(&self) -> io::Result<()> {
match *self {
PrimaryWriter::StdErrWriter(ref w) => w.flush(),
PrimaryWriter::ExtendedFileWriter(ref w) => w.flush(),
}
}
pub(crate) fn validate_logs(
&self,
expected: &[(&'static str, &'static str, &'static str)],
) -> bool {
match *self {
PrimaryWriter::StdErrWriter(_) => false,
PrimaryWriter::ExtendedFileWriter(ref w) => w.validate_logs(expected),
}
}
}
pub struct StdErrWriter {
format: FormatFunction,
}
impl StdErrWriter {
#[inline]
fn write(&self, record: &Record) -> io::Result<()> {
write_to_stderr(self.format, record)
}
#[inline]
fn flush(&self) -> io::Result<()> {
io::stderr().flush()
}
}
pub struct ExtendedFileWriter {
duplicate: Duplicate,
file_log_writer: FileLogWriter,
}
impl ExtendedFileWriter {
#[doc(hidden)]
pub fn validate_logs(&self, expected: &[(&'static str, &'static str, &'static str)]) -> bool {
self.file_log_writer.validate_logs(expected)
}
fn write(&self, record: &Record) -> io::Result<()> {
if match self.duplicate {
Duplicate::Error => record.level() == log::Level::Error,
Duplicate::Warn => record.level() <= log::Level::Warn,
Duplicate::Info => record.level() <= log::Level::Info,
Duplicate::Debug => record.level() <= log::Level::Debug,
Duplicate::Trace | Duplicate::All => true,
Duplicate::None => false,
} {
write_to_stderr(self.file_log_writer.format(), record)?;
}
self.file_log_writer.write(record)
}
fn flush(&self) -> io::Result<()> {
self.file_log_writer.flush()?;
io::stderr().flush()
}
}
#[inline]
fn write_to_stderr(f: FormatFunction, record: &Record) -> io::Result<()> {
(f)(&mut io::stderr(), record)?;
io::stderr().write_all(b"\n")
}