1#![doc(
349 html_logo_url = "https://prev.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
350 html_favicon_url = "https://prev.rust-lang.org/favicon.ico",
351 html_root_url = "https://docs.rs/log/0.4.29"
352)]
353#![warn(missing_docs)]
354#![deny(missing_debug_implementations, unconditional_recursion)]
355#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
356
357#[cfg(any(
358 all(feature = "max_level_off", feature = "max_level_error"),
359 all(feature = "max_level_off", feature = "max_level_warn"),
360 all(feature = "max_level_off", feature = "max_level_info"),
361 all(feature = "max_level_off", feature = "max_level_debug"),
362 all(feature = "max_level_off", feature = "max_level_trace"),
363 all(feature = "max_level_error", feature = "max_level_warn"),
364 all(feature = "max_level_error", feature = "max_level_info"),
365 all(feature = "max_level_error", feature = "max_level_debug"),
366 all(feature = "max_level_error", feature = "max_level_trace"),
367 all(feature = "max_level_warn", feature = "max_level_info"),
368 all(feature = "max_level_warn", feature = "max_level_debug"),
369 all(feature = "max_level_warn", feature = "max_level_trace"),
370 all(feature = "max_level_info", feature = "max_level_debug"),
371 all(feature = "max_level_info", feature = "max_level_trace"),
372 all(feature = "max_level_debug", feature = "max_level_trace"),
373))]
374compile_error!("multiple max_level_* features set");
375
376#[rustfmt::skip]
377#[cfg(any(
378 all(feature = "release_max_level_off", feature = "release_max_level_error"),
379 all(feature = "release_max_level_off", feature = "release_max_level_warn"),
380 all(feature = "release_max_level_off", feature = "release_max_level_info"),
381 all(feature = "release_max_level_off", feature = "release_max_level_debug"),
382 all(feature = "release_max_level_off", feature = "release_max_level_trace"),
383 all(feature = "release_max_level_error", feature = "release_max_level_warn"),
384 all(feature = "release_max_level_error", feature = "release_max_level_info"),
385 all(feature = "release_max_level_error", feature = "release_max_level_debug"),
386 all(feature = "release_max_level_error", feature = "release_max_level_trace"),
387 all(feature = "release_max_level_warn", feature = "release_max_level_info"),
388 all(feature = "release_max_level_warn", feature = "release_max_level_debug"),
389 all(feature = "release_max_level_warn", feature = "release_max_level_trace"),
390 all(feature = "release_max_level_info", feature = "release_max_level_debug"),
391 all(feature = "release_max_level_info", feature = "release_max_level_trace"),
392 all(feature = "release_max_level_debug", feature = "release_max_level_trace"),
393))]
394compile_error!("multiple release_max_level_* features set");
395
396#[cfg(all(not(feature = "std"), not(test)))]
397extern crate core as std;
398
399use std::cfg;
400#[cfg(feature = "std")]
401use std::error;
402use std::str::FromStr;
403use std::{cmp, fmt, mem};
404
405#[macro_use]
406mod macros;
407mod serde;
408
409#[cfg(feature = "kv")]
410pub mod kv;
411
412#[cfg(target_has_atomic = "ptr")]
413use std::sync::atomic::{AtomicUsize, Ordering};
414
415#[cfg(not(target_has_atomic = "ptr"))]
416use std::cell::Cell;
417#[cfg(not(target_has_atomic = "ptr"))]
418use std::sync::atomic::Ordering;
419
420#[cfg(not(target_has_atomic = "ptr"))]
421struct AtomicUsize {
422 v: Cell<usize>,
423}
424
425#[cfg(not(target_has_atomic = "ptr"))]
426impl AtomicUsize {
427 const fn new(v: usize) -> AtomicUsize {
428 AtomicUsize { v: Cell::new(v) }
429 }
430
431 fn load(&self, _order: Ordering) -> usize {
432 self.v.get()
433 }
434
435 fn store(&self, val: usize, _order: Ordering) {
436 self.v.set(val)
437 }
438}
439
440#[cfg(not(target_has_atomic = "ptr"))]
443unsafe impl Sync for AtomicUsize {}
444
445static mut LOGGER: &dyn Log = &NopLogger;
448
449static STATE: AtomicUsize = AtomicUsize::new(0);
450
451const UNINITIALIZED: usize = 0;
455const INITIALIZING: usize = 1;
456const INITIALIZED: usize = 2;
457
458static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0);
459
460static LOG_LEVEL_NAMES: [&str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
461
462static SET_LOGGER_ERROR: &str = "attempted to set a logger after the logging system \
463 was already initialized";
464static LEVEL_PARSE_ERROR: &str =
465 "attempted to convert a string that doesn't match an existing log level";
466
467#[repr(usize)]
474#[derive(#[automatically_derived]
impl ::core::clone::Clone for Level {
#[inline]
fn clone(&self) -> Level { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Level { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Level {
#[inline]
fn eq(&self, other: &Level) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Level {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Level {
#[inline]
fn partial_cmp(&self, other: &Level)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Level {
#[inline]
fn cmp(&self, other: &Level) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::fmt::Debug for Level {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Level::Error => "Error",
Level::Warn => "Warn",
Level::Info => "Info",
Level::Debug => "Debug",
Level::Trace => "Trace",
})
}
}Debug, #[automatically_derived]
impl ::core::hash::Hash for Level {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash)]
475pub enum Level {
476 Error = 1,
483 Warn,
487 Info,
491 Debug,
495 Trace,
499}
500
501impl PartialEq<LevelFilter> for Level {
502 #[inline]
503 fn eq(&self, other: &LevelFilter) -> bool {
504 *self as usize == *other as usize
505 }
506}
507
508impl PartialOrd<LevelFilter> for Level {
509 #[inline]
510 fn partial_cmp(&self, other: &LevelFilter) -> Option<cmp::Ordering> {
511 Some((*self as usize).cmp(&(*other as usize)))
512 }
513}
514
515impl FromStr for Level {
516 type Err = ParseLevelError;
517 fn from_str(level: &str) -> Result<Level, Self::Err> {
518 for idx in 1..LOG_LEVEL_NAMES.len() {
520 if LOG_LEVEL_NAMES[idx].eq_ignore_ascii_case(level) {
521 return Ok(Level::from_usize(idx).unwrap());
522 }
523 }
524 Err(ParseLevelError(()))
525 }
526}
527
528impl fmt::Display for Level {
529 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
530 fmt.pad(self.as_str())
531 }
532}
533
534impl Level {
535 fn from_usize(u: usize) -> Option<Level> {
536 match u {
537 1 => Some(Level::Error),
538 2 => Some(Level::Warn),
539 3 => Some(Level::Info),
540 4 => Some(Level::Debug),
541 5 => Some(Level::Trace),
542 _ => None,
543 }
544 }
545
546 #[inline]
548 pub fn max() -> Level {
549 Level::Trace
550 }
551
552 #[inline]
554 pub fn to_level_filter(&self) -> LevelFilter {
555 LevelFilter::from_usize(*self as usize).unwrap()
556 }
557
558 pub fn as_str(&self) -> &'static str {
562 LOG_LEVEL_NAMES[*self as usize]
563 }
564
565 pub fn iter() -> impl Iterator<Item = Self> {
580 (1..6).map(|i| Self::from_usize(i).unwrap())
581 }
582
583 pub fn increment_severity(&self) -> Self {
600 let current = *self as usize;
601 Self::from_usize(current + 1).unwrap_or(*self)
602 }
603
604 pub fn decrement_severity(&self) -> Self {
621 let current = *self as usize;
622 Self::from_usize(current.saturating_sub(1)).unwrap_or(*self)
623 }
624}
625
626#[repr(usize)]
635#[derive(#[automatically_derived]
impl ::core::clone::Clone for LevelFilter {
#[inline]
fn clone(&self) -> LevelFilter { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LevelFilter { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for LevelFilter {
#[inline]
fn eq(&self, other: &LevelFilter) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for LevelFilter {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for LevelFilter {
#[inline]
fn partial_cmp(&self, other: &LevelFilter)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for LevelFilter {
#[inline]
fn cmp(&self, other: &LevelFilter) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::fmt::Debug for LevelFilter {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
LevelFilter::Off => "Off",
LevelFilter::Error => "Error",
LevelFilter::Warn => "Warn",
LevelFilter::Info => "Info",
LevelFilter::Debug => "Debug",
LevelFilter::Trace => "Trace",
})
}
}Debug, #[automatically_derived]
impl ::core::hash::Hash for LevelFilter {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash)]
636pub enum LevelFilter {
637 Off,
639 Error,
641 Warn,
643 Info,
645 Debug,
647 Trace,
649}
650
651impl PartialEq<Level> for LevelFilter {
652 #[inline]
653 fn eq(&self, other: &Level) -> bool {
654 other.eq(self)
655 }
656}
657
658impl PartialOrd<Level> for LevelFilter {
659 #[inline]
660 fn partial_cmp(&self, other: &Level) -> Option<cmp::Ordering> {
661 Some((*self as usize).cmp(&(*other as usize)))
662 }
663}
664
665impl FromStr for LevelFilter {
666 type Err = ParseLevelError;
667 fn from_str(level: &str) -> Result<LevelFilter, Self::Err> {
668 for idx in 0..LOG_LEVEL_NAMES.len() {
670 if LOG_LEVEL_NAMES[idx].eq_ignore_ascii_case(level) {
671 return Ok(LevelFilter::from_usize(idx).unwrap());
672 }
673 }
674 Err(ParseLevelError(()))
675 }
676}
677
678impl fmt::Display for LevelFilter {
679 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
680 fmt.pad(self.as_str())
681 }
682}
683
684impl LevelFilter {
685 fn from_usize(u: usize) -> Option<LevelFilter> {
686 match u {
687 0 => Some(LevelFilter::Off),
688 1 => Some(LevelFilter::Error),
689 2 => Some(LevelFilter::Warn),
690 3 => Some(LevelFilter::Info),
691 4 => Some(LevelFilter::Debug),
692 5 => Some(LevelFilter::Trace),
693 _ => None,
694 }
695 }
696
697 #[inline]
699 pub fn max() -> LevelFilter {
700 LevelFilter::Trace
701 }
702
703 #[inline]
707 pub fn to_level(&self) -> Option<Level> {
708 Level::from_usize(*self as usize)
709 }
710
711 pub fn as_str(&self) -> &'static str {
715 LOG_LEVEL_NAMES[*self as usize]
716 }
717
718 pub fn iter() -> impl Iterator<Item = Self> {
733 (0..6).map(|i| Self::from_usize(i).unwrap())
734 }
735
736 pub fn increment_severity(&self) -> Self {
753 let current = *self as usize;
754 Self::from_usize(current + 1).unwrap_or(*self)
755 }
756
757 pub fn decrement_severity(&self) -> Self {
775 let current = *self as usize;
776 Self::from_usize(current.saturating_sub(1)).unwrap_or(*self)
777 }
778}
779
780#[derive(#[automatically_derived]
impl<'a> ::core::marker::Copy for MaybeStaticStr<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::clone::Clone for MaybeStaticStr<'a> {
#[inline]
fn clone(&self) -> MaybeStaticStr<'a> {
let _: ::core::clone::AssertParamIsClone<&'static str>;
let _: ::core::clone::AssertParamIsClone<&'a str>;
*self
}
}Clone, #[automatically_derived]
impl<'a> ::core::cmp::Eq for MaybeStaticStr<'a> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<&'static str>;
let _: ::core::cmp::AssertParamIsEq<&'a str>;
}
}Eq, #[automatically_derived]
impl<'a> ::core::cmp::PartialEq for MaybeStaticStr<'a> {
#[inline]
fn eq(&self, other: &MaybeStaticStr<'a>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(MaybeStaticStr::Static(__self_0),
MaybeStaticStr::Static(__arg1_0)) => __self_0 == __arg1_0,
(MaybeStaticStr::Borrowed(__self_0),
MaybeStaticStr::Borrowed(__arg1_0)) => __self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl<'a> ::core::cmp::Ord for MaybeStaticStr<'a> {
#[inline]
fn cmp(&self, other: &MaybeStaticStr<'a>) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
::core::cmp::Ordering::Equal =>
match (self, other) {
(MaybeStaticStr::Static(__self_0),
MaybeStaticStr::Static(__arg1_0)) =>
::core::cmp::Ord::cmp(__self_0, __arg1_0),
(MaybeStaticStr::Borrowed(__self_0),
MaybeStaticStr::Borrowed(__arg1_0)) =>
::core::cmp::Ord::cmp(__self_0, __arg1_0),
_ => unsafe { ::core::intrinsics::unreachable() }
},
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl<'a> ::core::cmp::PartialOrd for MaybeStaticStr<'a> {
#[inline]
fn partial_cmp(&self, other: &MaybeStaticStr<'a>)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
match (self, other) {
(MaybeStaticStr::Static(__self_0),
MaybeStaticStr::Static(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
(MaybeStaticStr::Borrowed(__self_0),
MaybeStaticStr::Borrowed(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
_ =>
::core::cmp::PartialOrd::partial_cmp(&__self_discr,
&__arg1_discr),
}
}
}PartialOrd, #[automatically_derived]
impl<'a> ::core::hash::Hash for MaybeStaticStr<'a> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
MaybeStaticStr::Static(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
MaybeStaticStr::Borrowed(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash, #[automatically_derived]
impl<'a> ::core::fmt::Debug for MaybeStaticStr<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
MaybeStaticStr::Static(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Static",
&__self_0),
MaybeStaticStr::Borrowed(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Borrowed", &__self_0),
}
}
}Debug)]
781enum MaybeStaticStr<'a> {
782 Static(&'static str),
783 Borrowed(&'a str),
784}
785
786impl<'a> MaybeStaticStr<'a> {
787 #[inline]
788 fn get(&self) -> &'a str {
789 match *self {
790 MaybeStaticStr::Static(s) => s,
791 MaybeStaticStr::Borrowed(s) => s,
792 }
793 }
794}
795
796#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for Record<'a> {
#[inline]
fn clone(&self) -> Record<'a> {
Record {
metadata: ::core::clone::Clone::clone(&self.metadata),
args: ::core::clone::Clone::clone(&self.args),
module_path: ::core::clone::Clone::clone(&self.module_path),
file: ::core::clone::Clone::clone(&self.file),
line: ::core::clone::Clone::clone(&self.line),
}
}
}Clone, #[automatically_derived]
impl<'a> ::core::fmt::Debug for Record<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field5_finish(f, "Record",
"metadata", &self.metadata, "args", &self.args, "module_path",
&self.module_path, "file", &self.file, "line", &&self.line)
}
}Debug)]
842pub struct Record<'a> {
843 metadata: Metadata<'a>,
844 args: fmt::Arguments<'a>,
845 module_path: Option<MaybeStaticStr<'a>>,
846 file: Option<MaybeStaticStr<'a>>,
847 line: Option<u32>,
848 #[cfg(feature = "kv")]
849 key_values: KeyValues<'a>,
850}
851
852#[cfg(feature = "kv")]
857#[derive(Clone)]
858struct KeyValues<'a>(&'a dyn kv::Source);
859
860#[cfg(feature = "kv")]
861impl<'a> fmt::Debug for KeyValues<'a> {
862 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
863 let mut visitor = f.debug_map();
864 self.0.visit(&mut visitor).map_err(|_| fmt::Error)?;
865 visitor.finish()
866 }
867}
868
869impl<'a> Record<'a> {
870 #[inline]
872 pub fn builder() -> RecordBuilder<'a> {
873 RecordBuilder::new()
874 }
875
876 #[inline]
878 pub fn args(&self) -> &fmt::Arguments<'a> {
879 &self.args
880 }
881
882 #[inline]
884 pub fn metadata(&self) -> &Metadata<'a> {
885 &self.metadata
886 }
887
888 #[inline]
890 pub fn level(&self) -> Level {
891 self.metadata.level()
892 }
893
894 #[inline]
896 pub fn target(&self) -> &'a str {
897 self.metadata.target()
898 }
899
900 #[inline]
902 pub fn module_path(&self) -> Option<&'a str> {
903 self.module_path.map(|s| s.get())
904 }
905
906 #[inline]
908 pub fn module_path_static(&self) -> Option<&'static str> {
909 match self.module_path {
910 Some(MaybeStaticStr::Static(s)) => Some(s),
911 _ => None,
912 }
913 }
914
915 #[inline]
917 pub fn file(&self) -> Option<&'a str> {
918 self.file.map(|s| s.get())
919 }
920
921 #[inline]
923 pub fn file_static(&self) -> Option<&'static str> {
924 match self.file {
925 Some(MaybeStaticStr::Static(s)) => Some(s),
926 _ => None,
927 }
928 }
929
930 #[inline]
932 pub fn line(&self) -> Option<u32> {
933 self.line
934 }
935
936 #[cfg(feature = "kv")]
938 #[inline]
939 pub fn key_values(&self) -> &dyn kv::Source {
940 self.key_values.0
941 }
942
943 #[cfg(feature = "kv")]
945 #[inline]
946 pub fn to_builder(&self) -> RecordBuilder<'_> {
947 RecordBuilder {
948 record: Record {
949 metadata: Metadata {
950 level: self.metadata.level,
951 target: self.metadata.target,
952 },
953 args: self.args,
954 module_path: self.module_path,
955 file: self.file,
956 line: self.line,
957 key_values: self.key_values.clone(),
958 },
959 }
960 }
961}
962
963#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for RecordBuilder<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "RecordBuilder",
"record", &&self.record)
}
}Debug)]
1003pub struct RecordBuilder<'a> {
1004 record: Record<'a>,
1005}
1006
1007impl<'a> RecordBuilder<'a> {
1008 #[inline]
1021 pub fn new() -> RecordBuilder<'a> {
1022 RecordBuilder {
1023 record: Record {
1024 args: format_args!("")format_args!(""),
1025 metadata: Metadata::builder().build(),
1026 module_path: None,
1027 file: None,
1028 line: None,
1029 #[cfg(feature = "kv")]
1030 key_values: KeyValues(&None::<(kv::Key, kv::Value)>),
1031 },
1032 }
1033 }
1034
1035 #[inline]
1037 pub fn args(&mut self, args: fmt::Arguments<'a>) -> &mut RecordBuilder<'a> {
1038 self.record.args = args;
1039 self
1040 }
1041
1042 #[inline]
1044 pub fn metadata(&mut self, metadata: Metadata<'a>) -> &mut RecordBuilder<'a> {
1045 self.record.metadata = metadata;
1046 self
1047 }
1048
1049 #[inline]
1051 pub fn level(&mut self, level: Level) -> &mut RecordBuilder<'a> {
1052 self.record.metadata.level = level;
1053 self
1054 }
1055
1056 #[inline]
1058 pub fn target(&mut self, target: &'a str) -> &mut RecordBuilder<'a> {
1059 self.record.metadata.target = target;
1060 self
1061 }
1062
1063 #[inline]
1065 pub fn module_path(&mut self, path: Option<&'a str>) -> &mut RecordBuilder<'a> {
1066 self.record.module_path = path.map(MaybeStaticStr::Borrowed);
1067 self
1068 }
1069
1070 #[inline]
1072 pub fn module_path_static(&mut self, path: Option<&'static str>) -> &mut RecordBuilder<'a> {
1073 self.record.module_path = path.map(MaybeStaticStr::Static);
1074 self
1075 }
1076
1077 #[inline]
1079 pub fn file(&mut self, file: Option<&'a str>) -> &mut RecordBuilder<'a> {
1080 self.record.file = file.map(MaybeStaticStr::Borrowed);
1081 self
1082 }
1083
1084 #[inline]
1086 pub fn file_static(&mut self, file: Option<&'static str>) -> &mut RecordBuilder<'a> {
1087 self.record.file = file.map(MaybeStaticStr::Static);
1088 self
1089 }
1090
1091 #[inline]
1093 pub fn line(&mut self, line: Option<u32>) -> &mut RecordBuilder<'a> {
1094 self.record.line = line;
1095 self
1096 }
1097
1098 #[cfg(feature = "kv")]
1100 #[inline]
1101 pub fn key_values(&mut self, kvs: &'a dyn kv::Source) -> &mut RecordBuilder<'a> {
1102 self.record.key_values = KeyValues(kvs);
1103 self
1104 }
1105
1106 #[inline]
1108 pub fn build(&self) -> Record<'a> {
1109 self.record.clone()
1110 }
1111}
1112
1113impl Default for RecordBuilder<'_> {
1114 fn default() -> Self {
1115 Self::new()
1116 }
1117}
1118
1119#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for Metadata<'a> {
#[inline]
fn clone(&self) -> Metadata<'a> {
Metadata {
level: ::core::clone::Clone::clone(&self.level),
target: ::core::clone::Clone::clone(&self.target),
}
}
}Clone, #[automatically_derived]
impl<'a> ::core::cmp::Eq for Metadata<'a> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<Level>;
let _: ::core::cmp::AssertParamIsEq<&'a str>;
}
}Eq, #[automatically_derived]
impl<'a> ::core::cmp::PartialEq for Metadata<'a> {
#[inline]
fn eq(&self, other: &Metadata<'a>) -> bool {
self.level == other.level && self.target == other.target
}
}PartialEq, #[automatically_derived]
impl<'a> ::core::cmp::Ord for Metadata<'a> {
#[inline]
fn cmp(&self, other: &Metadata<'a>) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.level, &other.level) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.target, &other.target),
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl<'a> ::core::cmp::PartialOrd for Metadata<'a> {
#[inline]
fn partial_cmp(&self, other: &Metadata<'a>)
-> ::core::option::Option<::core::cmp::Ordering> {
match ::core::cmp::PartialOrd::partial_cmp(&self.level, &other.level)
{
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
::core::cmp::PartialOrd::partial_cmp(&self.target,
&other.target),
cmp => cmp,
}
}
}PartialOrd, #[automatically_derived]
impl<'a> ::core::hash::Hash for Metadata<'a> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.level, state);
::core::hash::Hash::hash(&self.target, state)
}
}Hash, #[automatically_derived]
impl<'a> ::core::fmt::Debug for Metadata<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Metadata",
"level", &self.level, "target", &&self.target)
}
}Debug)]
1158pub struct Metadata<'a> {
1159 level: Level,
1160 target: &'a str,
1161}
1162
1163impl<'a> Metadata<'a> {
1164 #[inline]
1166 pub fn builder() -> MetadataBuilder<'a> {
1167 MetadataBuilder::new()
1168 }
1169
1170 #[inline]
1172 pub fn level(&self) -> Level {
1173 self.level
1174 }
1175
1176 #[inline]
1178 pub fn target(&self) -> &'a str {
1179 self.target
1180 }
1181}
1182
1183#[derive(#[automatically_derived]
impl<'a> ::core::cmp::Eq for MetadataBuilder<'a> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<Metadata<'a>>;
}
}Eq, #[automatically_derived]
impl<'a> ::core::cmp::PartialEq for MetadataBuilder<'a> {
#[inline]
fn eq(&self, other: &MetadataBuilder<'a>) -> bool {
self.metadata == other.metadata
}
}PartialEq, #[automatically_derived]
impl<'a> ::core::cmp::Ord for MetadataBuilder<'a> {
#[inline]
fn cmp(&self, other: &MetadataBuilder<'a>) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.metadata, &other.metadata)
}
}Ord, #[automatically_derived]
impl<'a> ::core::cmp::PartialOrd for MetadataBuilder<'a> {
#[inline]
fn partial_cmp(&self, other: &MetadataBuilder<'a>)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.metadata, &other.metadata)
}
}PartialOrd, #[automatically_derived]
impl<'a> ::core::hash::Hash for MetadataBuilder<'a> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.metadata, state)
}
}Hash, #[automatically_derived]
impl<'a> ::core::fmt::Debug for MetadataBuilder<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"MetadataBuilder", "metadata", &&self.metadata)
}
}Debug)]
1200pub struct MetadataBuilder<'a> {
1201 metadata: Metadata<'a>,
1202}
1203
1204impl<'a> MetadataBuilder<'a> {
1205 #[inline]
1212 pub fn new() -> MetadataBuilder<'a> {
1213 MetadataBuilder {
1214 metadata: Metadata {
1215 level: Level::Info,
1216 target: "",
1217 },
1218 }
1219 }
1220
1221 #[inline]
1223 pub fn level(&mut self, arg: Level) -> &mut MetadataBuilder<'a> {
1224 self.metadata.level = arg;
1225 self
1226 }
1227
1228 #[inline]
1230 pub fn target(&mut self, target: &'a str) -> &mut MetadataBuilder<'a> {
1231 self.metadata.target = target;
1232 self
1233 }
1234
1235 #[inline]
1237 pub fn build(&self) -> Metadata<'a> {
1238 self.metadata.clone()
1239 }
1240}
1241
1242impl Default for MetadataBuilder<'_> {
1243 fn default() -> Self {
1244 Self::new()
1245 }
1246}
1247
1248pub trait Log: Sync + Send {
1250 fn enabled(&self, metadata: &Metadata) -> bool;
1263
1264 fn log(&self, record: &Record);
1272
1273 fn flush(&self);
1280}
1281
1282struct NopLogger;
1284
1285impl Log for NopLogger {
1286 fn enabled(&self, _: &Metadata) -> bool {
1287 false
1288 }
1289
1290 fn log(&self, _: &Record) {}
1291 fn flush(&self) {}
1292}
1293
1294impl<T> Log for &'_ T
1295where
1296 T: ?Sized + Log,
1297{
1298 fn enabled(&self, metadata: &Metadata) -> bool {
1299 (**self).enabled(metadata)
1300 }
1301
1302 fn log(&self, record: &Record) {
1303 (**self).log(record);
1304 }
1305 fn flush(&self) {
1306 (**self).flush();
1307 }
1308}
1309
1310#[cfg(feature = "std")]
1311impl<T> Log for std::boxed::Box<T>
1312where
1313 T: ?Sized + Log,
1314{
1315 fn enabled(&self, metadata: &Metadata) -> bool {
1316 self.as_ref().enabled(metadata)
1317 }
1318
1319 fn log(&self, record: &Record) {
1320 self.as_ref().log(record);
1321 }
1322 fn flush(&self) {
1323 self.as_ref().flush();
1324 }
1325}
1326
1327#[cfg(feature = "std")]
1328impl<T> Log for std::sync::Arc<T>
1329where
1330 T: ?Sized + Log,
1331{
1332 fn enabled(&self, metadata: &Metadata) -> bool {
1333 self.as_ref().enabled(metadata)
1334 }
1335
1336 fn log(&self, record: &Record) {
1337 self.as_ref().log(record);
1338 }
1339 fn flush(&self) {
1340 self.as_ref().flush();
1341 }
1342}
1343
1344#[inline]
1350#[cfg(target_has_atomic = "ptr")]
1351pub fn set_max_level(level: LevelFilter) {
1352 MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed);
1353}
1354
1355#[inline]
1375pub unsafe fn set_max_level_racy(level: LevelFilter) {
1376 MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed);
1380}
1381
1382#[inline(always)]
1396pub fn max_level() -> LevelFilter {
1397 unsafe { mem::transmute(MAX_LOG_LEVEL_FILTER.load(Ordering::Relaxed)) }
1404}
1405
1406#[cfg(all(feature = "std", target_has_atomic = "ptr"))]
1420pub fn set_boxed_logger(logger: Box<dyn Log>) -> Result<(), SetLoggerError> {
1421 set_logger_inner(|| Box::leak(logger))
1422}
1423
1424#[cfg(target_has_atomic = "ptr")]
1478pub fn set_logger(logger: &'static dyn Log) -> Result<(), SetLoggerError> {
1479 set_logger_inner(|| logger)
1480}
1481
1482#[cfg(target_has_atomic = "ptr")]
1483fn set_logger_inner<F>(make_logger: F) -> Result<(), SetLoggerError>
1484where
1485 F: FnOnce() -> &'static dyn Log,
1486{
1487 match STATE.compare_exchange(
1488 UNINITIALIZED,
1489 INITIALIZING,
1490 Ordering::Acquire,
1491 Ordering::Relaxed,
1492 ) {
1493 Ok(UNINITIALIZED) => {
1494 unsafe {
1495 LOGGER = make_logger();
1496 }
1497 STATE.store(INITIALIZED, Ordering::Release);
1498 Ok(())
1499 }
1500 Err(INITIALIZING) => {
1501 while STATE.load(Ordering::Relaxed) == INITIALIZING {
1502 std::hint::spin_loop();
1503 }
1504 Err(SetLoggerError(()))
1505 }
1506 _ => Err(SetLoggerError(())),
1507 }
1508}
1509
1510pub unsafe fn set_logger_racy(logger: &'static dyn Log) -> Result<(), SetLoggerError> {
1530 match STATE.load(Ordering::Acquire) {
1531 UNINITIALIZED => {
1532 LOGGER = logger;
1533 STATE.store(INITIALIZED, Ordering::Release);
1534 Ok(())
1535 }
1536 INITIALIZING => {
1537 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("set_logger_racy must not be used with other initialization functions")));
}unreachable!("set_logger_racy must not be used with other initialization functions")
1539 }
1540 _ => Err(SetLoggerError(())),
1541 }
1542}
1543
1544#[allow(missing_copy_implementations)]
1548#[derive(#[automatically_derived]
#[allow(missing_copy_implementations)]
impl ::core::fmt::Debug for SetLoggerError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "SetLoggerError",
&&self.0)
}
}Debug)]
1549pub struct SetLoggerError(());
1550
1551impl fmt::Display for SetLoggerError {
1552 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1553 fmt.write_str(SET_LOGGER_ERROR)
1554 }
1555}
1556
1557#[cfg(feature = "std")]
1559impl error::Error for SetLoggerError {}
1560
1561#[allow(missing_copy_implementations)]
1565#[derive(#[automatically_derived]
#[allow(missing_copy_implementations)]
impl ::core::fmt::Debug for ParseLevelError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ParseLevelError", &&self.0)
}
}Debug, #[automatically_derived]
#[allow(missing_copy_implementations)]
impl ::core::cmp::PartialEq for ParseLevelError {
#[inline]
fn eq(&self, other: &ParseLevelError) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
#[allow(missing_copy_implementations)]
impl ::core::cmp::Eq for ParseLevelError {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<()>;
}
}Eq)]
1566pub struct ParseLevelError(());
1567
1568impl fmt::Display for ParseLevelError {
1569 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1570 fmt.write_str(LEVEL_PARSE_ERROR)
1571 }
1572}
1573
1574#[cfg(feature = "std")]
1576impl error::Error for ParseLevelError {}
1577
1578pub fn logger() -> &'static dyn Log {
1582 if STATE.load(Ordering::Acquire) != INITIALIZED {
1591 static NOP: NopLogger = NopLogger;
1592 &NOP
1593 } else {
1594 unsafe { LOGGER }
1595 }
1596}
1597
1598#[doc(hidden)]
1600pub mod __private_api;
1601
1602pub const STATIC_MAX_LEVEL: LevelFilter = match truecfg!(debug_assertions) {
1612 false if falsecfg!(feature = "release_max_level_off") => LevelFilter::Off,
1613 false if falsecfg!(feature = "release_max_level_error") => LevelFilter::Error,
1614 false if falsecfg!(feature = "release_max_level_warn") => LevelFilter::Warn,
1615 false if falsecfg!(feature = "release_max_level_info") => LevelFilter::Info,
1616 false if falsecfg!(feature = "release_max_level_debug") => LevelFilter::Debug,
1617 false if falsecfg!(feature = "release_max_level_trace") => LevelFilter::Trace,
1618 _ if falsecfg!(feature = "max_level_off") => LevelFilter::Off,
1619 _ if falsecfg!(feature = "max_level_error") => LevelFilter::Error,
1620 _ if falsecfg!(feature = "max_level_warn") => LevelFilter::Warn,
1621 _ if falsecfg!(feature = "max_level_info") => LevelFilter::Info,
1622 _ if falsecfg!(feature = "max_level_debug") => LevelFilter::Debug,
1623 _ => LevelFilter::Trace,
1624};
1625
1626#[cfg(test)]
1627mod tests {
1628 use super::{Level, LevelFilter, ParseLevelError, STATIC_MAX_LEVEL};
1629
1630 #[test]
1631 fn test_levelfilter_from_str() {
1632 let tests = [
1633 ("off", Ok(LevelFilter::Off)),
1634 ("error", Ok(LevelFilter::Error)),
1635 ("warn", Ok(LevelFilter::Warn)),
1636 ("info", Ok(LevelFilter::Info)),
1637 ("debug", Ok(LevelFilter::Debug)),
1638 ("trace", Ok(LevelFilter::Trace)),
1639 ("OFF", Ok(LevelFilter::Off)),
1640 ("ERROR", Ok(LevelFilter::Error)),
1641 ("WARN", Ok(LevelFilter::Warn)),
1642 ("INFO", Ok(LevelFilter::Info)),
1643 ("DEBUG", Ok(LevelFilter::Debug)),
1644 ("TRACE", Ok(LevelFilter::Trace)),
1645 ("asdf", Err(ParseLevelError(()))),
1646 ];
1647 for &(s, ref expected) in &tests {
1648 assert_eq!(expected, &s.parse());
1649 }
1650 }
1651
1652 #[test]
1653 fn test_level_from_str() {
1654 let tests = [
1655 ("OFF", Err(ParseLevelError(()))),
1656 ("error", Ok(Level::Error)),
1657 ("warn", Ok(Level::Warn)),
1658 ("info", Ok(Level::Info)),
1659 ("debug", Ok(Level::Debug)),
1660 ("trace", Ok(Level::Trace)),
1661 ("ERROR", Ok(Level::Error)),
1662 ("WARN", Ok(Level::Warn)),
1663 ("INFO", Ok(Level::Info)),
1664 ("DEBUG", Ok(Level::Debug)),
1665 ("TRACE", Ok(Level::Trace)),
1666 ("asdf", Err(ParseLevelError(()))),
1667 ];
1668 for &(s, ref expected) in &tests {
1669 assert_eq!(expected, &s.parse());
1670 }
1671 }
1672
1673 #[test]
1674 fn test_level_as_str() {
1675 let tests = &[
1676 (Level::Error, "ERROR"),
1677 (Level::Warn, "WARN"),
1678 (Level::Info, "INFO"),
1679 (Level::Debug, "DEBUG"),
1680 (Level::Trace, "TRACE"),
1681 ];
1682 for (input, expected) in tests {
1683 assert_eq!(*expected, input.as_str());
1684 }
1685 }
1686
1687 #[test]
1688 fn test_level_show() {
1689 assert_eq!("INFO", Level::Info.to_string());
1690 assert_eq!("ERROR", Level::Error.to_string());
1691 }
1692
1693 #[test]
1694 fn test_levelfilter_show() {
1695 assert_eq!("OFF", LevelFilter::Off.to_string());
1696 assert_eq!("ERROR", LevelFilter::Error.to_string());
1697 }
1698
1699 #[test]
1700 fn test_cross_cmp() {
1701 assert!(Level::Debug > LevelFilter::Error);
1702 assert!(LevelFilter::Warn < Level::Trace);
1703 assert!(LevelFilter::Off < Level::Error);
1704 }
1705
1706 #[test]
1707 fn test_cross_eq() {
1708 assert!(Level::Error == LevelFilter::Error);
1709 assert!(LevelFilter::Off != Level::Error);
1710 assert!(Level::Trace == LevelFilter::Trace);
1711 }
1712
1713 #[test]
1714 fn test_to_level() {
1715 assert_eq!(Some(Level::Error), LevelFilter::Error.to_level());
1716 assert_eq!(None, LevelFilter::Off.to_level());
1717 assert_eq!(Some(Level::Debug), LevelFilter::Debug.to_level());
1718 }
1719
1720 #[test]
1721 fn test_to_level_filter() {
1722 assert_eq!(LevelFilter::Error, Level::Error.to_level_filter());
1723 assert_eq!(LevelFilter::Trace, Level::Trace.to_level_filter());
1724 }
1725
1726 #[test]
1727 fn test_level_filter_as_str() {
1728 let tests = &[
1729 (LevelFilter::Off, "OFF"),
1730 (LevelFilter::Error, "ERROR"),
1731 (LevelFilter::Warn, "WARN"),
1732 (LevelFilter::Info, "INFO"),
1733 (LevelFilter::Debug, "DEBUG"),
1734 (LevelFilter::Trace, "TRACE"),
1735 ];
1736 for (input, expected) in tests {
1737 assert_eq!(*expected, input.as_str());
1738 }
1739 }
1740
1741 #[test]
1742 fn test_level_up() {
1743 let info = Level::Info;
1744 let up = info.increment_severity();
1745 assert_eq!(up, Level::Debug);
1746
1747 let trace = Level::Trace;
1748 let up = trace.increment_severity();
1749 assert_eq!(up, trace);
1751 }
1752
1753 #[test]
1754 fn test_level_filter_up() {
1755 let info = LevelFilter::Info;
1756 let up = info.increment_severity();
1757 assert_eq!(up, LevelFilter::Debug);
1758
1759 let trace = LevelFilter::Trace;
1760 let up = trace.increment_severity();
1761 assert_eq!(up, trace);
1763 }
1764
1765 #[test]
1766 fn test_level_down() {
1767 let info = Level::Info;
1768 let down = info.decrement_severity();
1769 assert_eq!(down, Level::Warn);
1770
1771 let error = Level::Error;
1772 let down = error.decrement_severity();
1773 assert_eq!(down, error);
1775 }
1776
1777 #[test]
1778 fn test_level_filter_down() {
1779 let info = LevelFilter::Info;
1780 let down = info.decrement_severity();
1781 assert_eq!(down, LevelFilter::Warn);
1782
1783 let error = LevelFilter::Error;
1784 let down = error.decrement_severity();
1785 assert_eq!(down, LevelFilter::Off);
1786 assert_eq!(down.decrement_severity(), down);
1788 }
1789
1790 #[test]
1791 #[cfg_attr(not(debug_assertions), ignore)]
1792 fn test_static_max_level_debug() {
1793 if cfg!(feature = "max_level_off") {
1794 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Off);
1795 } else if cfg!(feature = "max_level_error") {
1796 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Error);
1797 } else if cfg!(feature = "max_level_warn") {
1798 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Warn);
1799 } else if cfg!(feature = "max_level_info") {
1800 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Info);
1801 } else if cfg!(feature = "max_level_debug") {
1802 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Debug);
1803 } else {
1804 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Trace);
1805 }
1806 }
1807
1808 #[test]
1809 #[cfg_attr(debug_assertions, ignore)]
1810 fn test_static_max_level_release() {
1811 if cfg!(feature = "release_max_level_off") {
1812 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Off);
1813 } else if cfg!(feature = "release_max_level_error") {
1814 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Error);
1815 } else if cfg!(feature = "release_max_level_warn") {
1816 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Warn);
1817 } else if cfg!(feature = "release_max_level_info") {
1818 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Info);
1819 } else if cfg!(feature = "release_max_level_debug") {
1820 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Debug);
1821 } else if cfg!(feature = "release_max_level_trace") {
1822 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Trace);
1823 } else if cfg!(feature = "max_level_off") {
1824 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Off);
1825 } else if cfg!(feature = "max_level_error") {
1826 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Error);
1827 } else if cfg!(feature = "max_level_warn") {
1828 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Warn);
1829 } else if cfg!(feature = "max_level_info") {
1830 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Info);
1831 } else if cfg!(feature = "max_level_debug") {
1832 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Debug);
1833 } else {
1834 assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Trace);
1835 }
1836 }
1837
1838 #[test]
1839 #[cfg(feature = "std")]
1840 fn test_error_trait() {
1841 use super::SetLoggerError;
1842 let e = SetLoggerError(());
1843 assert_eq!(
1844 &e.to_string(),
1845 "attempted to set a logger after the logging system \
1846 was already initialized"
1847 );
1848 }
1849
1850 #[test]
1851 fn test_metadata_builder() {
1852 use super::MetadataBuilder;
1853 let target = "myApp";
1854 let metadata_test = MetadataBuilder::new()
1855 .level(Level::Debug)
1856 .target(target)
1857 .build();
1858 assert_eq!(metadata_test.level(), Level::Debug);
1859 assert_eq!(metadata_test.target(), "myApp");
1860 }
1861
1862 #[test]
1863 fn test_metadata_convenience_builder() {
1864 use super::Metadata;
1865 let target = "myApp";
1866 let metadata_test = Metadata::builder()
1867 .level(Level::Debug)
1868 .target(target)
1869 .build();
1870 assert_eq!(metadata_test.level(), Level::Debug);
1871 assert_eq!(metadata_test.target(), "myApp");
1872 }
1873
1874 #[test]
1875 fn test_record_builder() {
1876 use super::{MetadataBuilder, RecordBuilder};
1877 let target = "myApp";
1878 let metadata = MetadataBuilder::new().target(target).build();
1879 let fmt_args = format_args!("hello");
1880 let record_test = RecordBuilder::new()
1881 .args(fmt_args)
1882 .metadata(metadata)
1883 .module_path(Some("foo"))
1884 .file(Some("bar"))
1885 .line(Some(30))
1886 .build();
1887 assert_eq!(record_test.metadata().target(), "myApp");
1888 assert_eq!(record_test.module_path(), Some("foo"));
1889 assert_eq!(record_test.file(), Some("bar"));
1890 assert_eq!(record_test.line(), Some(30));
1891 }
1892
1893 #[test]
1894 fn test_record_convenience_builder() {
1895 use super::{Metadata, Record};
1896 let target = "myApp";
1897 let metadata = Metadata::builder().target(target).build();
1898 let fmt_args = format_args!("hello");
1899 let record_test = Record::builder()
1900 .args(fmt_args)
1901 .metadata(metadata)
1902 .module_path(Some("foo"))
1903 .file(Some("bar"))
1904 .line(Some(30))
1905 .build();
1906 assert_eq!(record_test.target(), "myApp");
1907 assert_eq!(record_test.module_path(), Some("foo"));
1908 assert_eq!(record_test.file(), Some("bar"));
1909 assert_eq!(record_test.line(), Some(30));
1910 }
1911
1912 #[test]
1913 fn test_record_complete_builder() {
1914 use super::{Level, Record};
1915 let target = "myApp";
1916 let record_test = Record::builder()
1917 .module_path(Some("foo"))
1918 .file(Some("bar"))
1919 .line(Some(30))
1920 .target(target)
1921 .level(Level::Error)
1922 .build();
1923 assert_eq!(record_test.target(), "myApp");
1924 assert_eq!(record_test.level(), Level::Error);
1925 assert_eq!(record_test.module_path(), Some("foo"));
1926 assert_eq!(record_test.file(), Some("bar"));
1927 assert_eq!(record_test.line(), Some(30));
1928 }
1929
1930 #[test]
1931 #[cfg(feature = "kv")]
1932 fn test_record_key_values_builder() {
1933 use super::Record;
1934 use crate::kv::{self, VisitSource};
1935
1936 struct TestVisitSource {
1937 seen_pairs: usize,
1938 }
1939
1940 impl<'kvs> VisitSource<'kvs> for TestVisitSource {
1941 fn visit_pair(
1942 &mut self,
1943 _: kv::Key<'kvs>,
1944 _: kv::Value<'kvs>,
1945 ) -> Result<(), kv::Error> {
1946 self.seen_pairs += 1;
1947 Ok(())
1948 }
1949 }
1950
1951 let kvs: &[(&str, i32)] = &[("a", 1), ("b", 2)];
1952 let record_test = Record::builder().key_values(&kvs).build();
1953
1954 let mut visitor = TestVisitSource { seen_pairs: 0 };
1955
1956 record_test.key_values().visit(&mut visitor).unwrap();
1957
1958 assert_eq!(2, visitor.seen_pairs);
1959 }
1960
1961 #[test]
1962 #[cfg(feature = "kv")]
1963 fn test_record_key_values_get_coerce() {
1964 use super::Record;
1965
1966 let kvs: &[(&str, &str)] = &[("a", "1"), ("b", "2")];
1967 let record = Record::builder().key_values(&kvs).build();
1968
1969 assert_eq!(
1970 "2",
1971 record
1972 .key_values()
1973 .get("b".into())
1974 .expect("missing key")
1975 .to_borrowed_str()
1976 .expect("invalid value")
1977 );
1978 }
1979
1980 #[test]
1983 fn test_foreign_impl() {
1984 use super::Log;
1985 #[cfg(feature = "std")]
1986 use std::sync::Arc;
1987
1988 fn assert_is_log<T: Log + ?Sized>() {}
1989
1990 assert_is_log::<&dyn Log>();
1991
1992 #[cfg(feature = "std")]
1993 assert_is_log::<Box<dyn Log>>();
1994
1995 #[cfg(feature = "std")]
1996 assert_is_log::<Arc<dyn Log>>();
1997
1998 #[allow(unused)]
2000 fn forall<T: Log + ?Sized>() {
2001 #[cfg(feature = "std")]
2002 assert_is_log::<Box<T>>();
2003
2004 assert_is_log::<&T>();
2005
2006 #[cfg(feature = "std")]
2007 assert_is_log::<Arc<T>>();
2008 }
2009 }
2010}