@@ -27,9 +27,9 @@ pub const DEFAULT_WRITE_STYLE_ENV: &str = "RUST_LOG_STYLE";
2727/// let mut builder = Builder::from_default_env();
2828///
2929/// builder
30- /// .format(|buf, record| writeln!(buf, "{} - {}", record.level(), record.args()))
3130/// .filter(None, LevelFilter::Info)
32- /// .init();
31+ /// .build_with_format_fn(|buf, record| writeln!(buf, "{} - {}", record.level(), record.args()))
32+ /// .try_init().unwrap();
3333///
3434/// error!("error message");
3535/// info!("info message");
@@ -38,7 +38,7 @@ pub const DEFAULT_WRITE_STYLE_ENV: &str = "RUST_LOG_STYLE";
3838pub struct Builder {
3939 filter : env_filter:: Builder ,
4040 writer : writer:: Builder ,
41- format : fmt:: Builder ,
41+ format : fmt:: ConfigurableFormat ,
4242 built : bool ,
4343}
4444
@@ -211,68 +211,23 @@ impl Builder {
211211 self . parse_env ( Env :: default ( ) )
212212 }
213213
214- /// Sets the format function for formatting the log output.
215- ///
216- /// This function is called on each record logged and should format the
217- /// log record and output it to the given [`Formatter`].
218- ///
219- /// The format function is expected to output the string directly to the
220- /// `Formatter` so that implementations can use the [`std::fmt`] macros
221- /// to format and output without intermediate heap allocations. The default
222- /// `env_logger` formatter takes advantage of this.
223- ///
224- /// When the `color` feature is enabled, styling via ANSI escape codes is supported and the
225- /// output will automatically respect [`Builder::write_style`].
226- ///
227- /// # Examples
228- ///
229- /// Use a custom format to write only the log message:
230- ///
231- /// ```
232- /// use std::io::Write;
233- /// use env_logger::Builder;
234- ///
235- /// let mut builder = Builder::new();
236- ///
237- /// builder.format(|buf, record| writeln!(buf, "{}", record.args()));
238- /// ```
239- ///
240- /// [`Formatter`]: fmt/struct.Formatter.html
241- /// [`String`]: https://doc.rust-lang.org/stable/std/string/struct.String.html
242- /// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html
243- pub fn format < F > ( & mut self , format : F ) -> & mut Self
244- where
245- F : Fn ( & mut Formatter , & Record < ' _ > ) -> io:: Result < ( ) > + Sync + Send + ' static ,
246- {
247- self . format . custom_format = Some ( Box :: new ( format) ) ;
248- self
249- }
250-
251- /// Use the default format.
252- ///
253- /// This method will clear any custom format set on the builder.
254- pub fn default_format ( & mut self ) -> & mut Self {
255- self . format = Default :: default ( ) ;
256- self
257- }
258-
259214 /// Whether or not to write the level in the default format.
260215 pub fn format_level ( & mut self , write : bool ) -> & mut Self {
261- self . format . default_format . level ( write) ;
216+ self . format . level ( write) ;
262217 self
263218 }
264219
265220 /// Whether or not to write the source file path in the default format.
266221 pub fn format_file ( & mut self , write : bool ) -> & mut Self {
267- self . format . default_format . file ( write) ;
222+ self . format . file ( write) ;
268223 self
269224 }
270225
271226 /// Whether or not to write the source line number path in the default format.
272227 ///
273228 /// Only has effect if `format_file` is also enabled
274229 pub fn format_line_number ( & mut self , write : bool ) -> & mut Self {
275- self . format . default_format . line_number ( write) ;
230+ self . format . line_number ( write) ;
276231 self
277232 }
278233
@@ -287,26 +242,26 @@ impl Builder {
287242
288243 /// Whether or not to write the module path in the default format.
289244 pub fn format_module_path ( & mut self , write : bool ) -> & mut Self {
290- self . format . default_format . module_path ( write) ;
245+ self . format . module_path ( write) ;
291246 self
292247 }
293248
294249 /// Whether or not to write the target in the default format.
295250 pub fn format_target ( & mut self , write : bool ) -> & mut Self {
296- self . format . default_format . target ( write) ;
251+ self . format . target ( write) ;
297252 self
298253 }
299254
300255 /// Configures the amount of spaces to use to indent multiline log records.
301256 /// A value of `None` disables any kind of indentation.
302257 pub fn format_indent ( & mut self , indent : Option < usize > ) -> & mut Self {
303- self . format . default_format . indent ( indent) ;
258+ self . format . indent ( indent) ;
304259 self
305260 }
306261
307262 /// Configures if timestamp should be included and in what precision.
308263 pub fn format_timestamp ( & mut self , timestamp : Option < fmt:: TimestampPrecision > ) -> & mut Self {
309- self . format . default_format . timestamp ( timestamp) ;
264+ self . format . timestamp ( timestamp) ;
310265 self
311266 }
312267
@@ -332,7 +287,7 @@ impl Builder {
332287
333288 /// Configures the end of line suffix.
334289 pub fn format_suffix ( & mut self , suffix : & ' static str ) -> & mut Self {
335- self . format . default_format . suffix ( suffix) ;
290+ self . format . suffix ( suffix) ;
336291 self
337292 }
338293
@@ -351,7 +306,7 @@ impl Builder {
351306 where
352307 F : Fn ( & mut Formatter , & dyn log:: kv:: Source ) -> io:: Result < ( ) > + Sync + Send + ' static ,
353308 {
354- self . format . default_format . key_values ( format) ;
309+ self . format . key_values ( format) ;
355310 self
356311 }
357312
@@ -497,15 +452,7 @@ impl Builder {
497452 /// library has already initialized a global logger.
498453 pub fn try_init ( & mut self ) -> Result < ( ) , SetLoggerError > {
499454 let logger = self . build ( ) ;
500-
501- let max_level = logger. filter ( ) ;
502- let r = log:: set_boxed_logger ( Box :: new ( logger) ) ;
503-
504- if r. is_ok ( ) {
505- log:: set_max_level ( max_level) ;
506- }
507-
508- r
455+ logger. try_init ( )
509456 }
510457
511458 /// Initializes the global logger with the built env logger.
@@ -533,7 +480,51 @@ impl Builder {
533480 Logger {
534481 writer : self . writer . build ( ) ,
535482 filter : self . filter . build ( ) ,
536- format : self . format . build ( ) ,
483+ format : Box :: new ( std:: mem:: take ( & mut self . format ) ) ,
484+ }
485+ }
486+
487+ /// Sets the format function for formatting the log output,
488+ /// and builds the Logger.
489+ ///
490+ /// This function is called on each record logged and should format the
491+ /// log record and output it to the given [`Formatter`].
492+ ///
493+ /// The format function is expected to output the string directly to the
494+ /// `Formatter` so that implementations can use the [`std::fmt`] macros
495+ /// to format and output without intermediate heap allocations. The default
496+ /// `env_logger` formatter takes advantage of this.
497+ ///
498+ /// When the `color` feature is enabled, styling via ANSI escape codes is supported and the
499+ /// output will automatically respect [`Builder::write_style`].
500+ ///
501+ /// # Examples
502+ ///
503+ /// Use a custom format to write only the log message:
504+ ///
505+ /// ```
506+ /// use std::io::Write;
507+ /// use env_logger::Builder;
508+ ///
509+ /// let mut builder = Builder::new();
510+ ///
511+ /// builder.build_with_format_fn(|buf, record| writeln!(buf, "{}", record.args()));
512+ /// ```
513+ ///
514+ /// [`Formatter`]: fmt/struct.Formatter.html
515+ /// [`String`]: https://doc.rust-lang.org/stable/std/string/struct.String.html
516+ /// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html
517+ pub fn build_with_format_fn < F > ( & mut self , format : F ) -> Logger
518+ where
519+ F : Fn ( & mut Formatter , & Record < ' _ > ) -> io:: Result < ( ) > + Sync + Send + ' static ,
520+ {
521+ assert ! ( !self . built, "attempt to re-use consumed builder" ) ;
522+ self . built = true ;
523+
524+ Logger {
525+ writer : self . writer . build ( ) ,
526+ filter : self . filter . build ( ) ,
527+ format : Box :: new ( format) ,
537528 }
538529 }
539530}
@@ -641,6 +632,17 @@ impl Logger {
641632 pub fn matches ( & self , record : & Record < ' _ > ) -> bool {
642633 self . filter . matches ( record)
643634 }
635+
636+ pub fn try_init ( self ) -> Result < ( ) , SetLoggerError > {
637+ let max_level = self . filter ( ) ;
638+ let r = log:: set_boxed_logger ( Box :: new ( self ) ) ;
639+
640+ if r. is_ok ( ) {
641+ log:: set_max_level ( max_level) ;
642+ }
643+
644+ r
645+ }
644646}
645647
646648impl Log for Logger {
0 commit comments