mirror of
https://github.com/openharmony/third_party_rust_log.git
synced 2026-07-19 19:43:45 -04:00
Add Log implementation on foreign types
Closes #458. Implements Log for references to loggers, as well as loggers wrapped in `Arc` or `Pin`. More may be added in the future. Especially, we probably will want to add a blanket implementation (bounded on `Borrow`) once we have impl specialization. (Technically, we could probably already do this now, but at the risk of painting ourselves into a corner.)
This commit is contained in:
+89
-1
@@ -269,7 +269,7 @@
|
||||
html_root_url = "https://docs.rs/log/0.4.14"
|
||||
)]
|
||||
#![warn(missing_docs)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
#![deny(missing_debug_implementations, unconditional_recursion)]
|
||||
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
|
||||
// When compiled for the rustc compiler itself we want to make sure that this is
|
||||
// an unstable crate
|
||||
@@ -1250,6 +1250,22 @@ impl Log for NopLogger {
|
||||
fn flush(&self) {}
|
||||
}
|
||||
|
||||
impl<T> Log for &'_ T
|
||||
where
|
||||
T: ?Sized + Log,
|
||||
{
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
(**self).enabled(metadata)
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
(**self).log(record)
|
||||
}
|
||||
fn flush(&self) {
|
||||
(**self).flush()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T> Log for std::boxed::Box<T>
|
||||
where
|
||||
@@ -1267,6 +1283,41 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<P, T> Log for std::pin::Pin<P>
|
||||
where
|
||||
P: std::ops::Deref<Target = T> + std::marker::Send + std::marker::Sync,
|
||||
T: Log + ?Sized,
|
||||
{
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
(**self).enabled(metadata)
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
(**self).log(record)
|
||||
}
|
||||
fn flush(&self) {
|
||||
(**self).flush()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T> Log for std::sync::Arc<T>
|
||||
where
|
||||
T: ?Sized + Log,
|
||||
{
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
self.as_ref().enabled(metadata)
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
self.as_ref().log(record)
|
||||
}
|
||||
fn flush(&self) {
|
||||
self.as_ref().flush()
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the global maximum log level.
|
||||
///
|
||||
/// Generally, this should only be called by the active logging implementation.
|
||||
@@ -1842,4 +1893,41 @@ mod tests {
|
||||
.expect("invalid value")
|
||||
);
|
||||
}
|
||||
|
||||
// Test that the `impl Log for Foo` blocks work
|
||||
// This test mostly operates on a type level, so failures will be compile errors
|
||||
#[test]
|
||||
fn test_foreign_impl() {
|
||||
use super::Log;
|
||||
#[cfg(feature = "std")]
|
||||
use std::{pin::Pin, sync::Arc};
|
||||
|
||||
fn assert_is_log<T: Log + ?Sized>() {}
|
||||
|
||||
assert_is_log::<&dyn Log>();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
assert_is_log::<Box<dyn Log>>();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
assert_is_log::<Pin<Box<dyn Log>>>();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
assert_is_log::<Arc<dyn Log>>();
|
||||
|
||||
// Assert these statements for all T: Log + ?Sized
|
||||
#[allow(unused)]
|
||||
fn forall<T: Log + ?Sized>() {
|
||||
#[cfg(feature = "std")]
|
||||
assert_is_log::<Box<T>>();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
assert_is_log::<Pin<Box<T>>>();
|
||||
|
||||
assert_is_log::<&T>();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
assert_is_log::<Arc<T>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user