1#![cfg_attr(not(feature = "std"), no_std)]
42
43#[cfg(not(feature = "std"))]
44use core as std;
45
46use log::{Log, Metadata, Record, SetLoggerError};
47
48pub mod target;
49pub mod timing;
50
51pub mod targets;
52
53use target::TargetResults;
54
55pub struct Logger<Targ, Time>
59where
60 Targ: target::Targets + Send + Sync + 'static,
61 Time: timing::Timing + Send + Sync + 'static
62{
63 pub targets: Targ,
64 pub start: Time
65}
66impl<Targ, Time> Logger<Targ, Time>
67where
68 Targ: target::Targets + Send + Sync + 'static,
69 Time: timing::Timing + Send + Sync + 'static
70{
71 pub fn new(targets: Targ, start: Time) -> Self {
75 Logger { targets, start }
76 }
77
78 pub fn start(&self) -> &Time {
80 &self.start
81 }
82
83 pub fn start_mut(&mut self) -> &mut Time {
87 &mut self.start
88 }
89
90 #[cfg(feature = "std")]
91 pub fn init_boxed(self) -> Result<(), SetLoggerError> {
92 let max_level = self.targets.max_level();
93 log::set_max_level(max_level);
94
95 let logger = Box::new(self);
96 log::set_boxed_logger(logger)?;
97 Ok(())
98 }
99
100 pub fn init_static(&'static self) -> Result<(), SetLoggerError> {
102 let max_level = self.targets.max_level();
103 log::set_max_level(max_level);
104
105 log::set_logger(self)?;
106 Ok(())
107 }
108
109 pub unsafe fn init_static_racy(&'static self) -> Result<(), SetLoggerError> {
110 let max_level = self.targets.max_level();
111 log::set_max_level(max_level);
112
113 log::set_logger_racy(self)?;
114 Ok(())
115 }
116
117 #[cfg(feature = "std")]
118 fn on_error(&self, error: &dyn std::fmt::Display) {
119 eprintln!("{}", error);
120 }
121
122 #[cfg(not(feature = "std"))]
123 fn on_error(&self, error: &dyn core::fmt::Display) {
124 }
126}
127impl<Targ, Time> Log for Logger<Targ, Time>
128where
129 Targ: target::Targets + Send + Sync + 'static,
130 Time: timing::Timing + Send + Sync + 'static
131{
132 fn enabled(&self, metadata: &Metadata) -> bool {
133 self.targets.max_level() >= metadata.level()
134 }
135
136 fn log(&self, record: &Record) {
137 let now = Time::now();
138 let duration_since_start = now.duration_since(&self.start);
139
140 let results = self.targets.write(duration_since_start, record);
141 results.log_errors(|err| self.on_error(err));
142 }
143
144 fn flush(&self) {
145 let results = self.targets.flush();
146 results.log_errors(|err| self.on_error(err));
147 }
148}