Skip to content

Commit

Permalink
Optimize binary size
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Jul 11, 2023
1 parent cab1088 commit 1b59e61
Show file tree
Hide file tree
Showing 3 changed files with 344 additions and 93 deletions.
236 changes: 236 additions & 0 deletions src/__private_api.rs
@@ -0,0 +1,236 @@
use self::sealed::{LogKVs, LogLevel, LogTarget};
use crate::{Level, LevelFilter, Metadata, Record};
use std::cmp::Ordering;
pub use std::convert::identity;
use std::fmt::Arguments;
use std::option::Option;
pub use std::primitive::str;
pub use std::{file, format_args, line, module_path, stringify};

#[cfg(feature = "kv_unstable")]
pub type LogKvValue<'a> = dyn crate::kv::value::ToValue + 'a;

#[cfg(not(feature = "kv_unstable"))]
pub type LogKvValue<'a> = str;

mod sealed {
use crate::Level;

pub trait LogLevel {
fn into_log_level(self) -> Level;
}

pub trait LogTarget {
fn with<R>(self, module_path: &'static str, f: impl FnOnce(&str) -> R) -> R;
}

pub trait LogKVs {
fn with<R>(self, f: impl FnOnce(&[(&str, &super::LogKvValue)]) -> R) -> R;
}
}

// `LogLevel`.

impl LogLevel for Level {
#[inline]
fn into_log_level(self) -> Level {
self
}
}

macro_rules! define_static_levels {
($($ty:ident => $lvl:ident,)*) => {
$(
#[derive(Debug)]
pub struct $ty;

impl LogLevel for $ty {
#[inline]
fn into_log_level(self) -> Level {
Level::$lvl
}
}

impl PartialEq<LevelFilter> for $ty {
#[inline]
fn eq(&self, other: &LevelFilter) -> bool {
Level::$lvl.eq(other)
}
}

impl PartialOrd<LevelFilter> for $ty {
#[inline]
fn partial_cmp(&self, other: &LevelFilter) -> Option<Ordering> {
Level::$lvl.partial_cmp(other)
}

#[inline]
fn lt(&self, other: &LevelFilter) -> bool {
Level::$lvl.lt(other)
}

#[inline]
fn le(&self, other: &LevelFilter) -> bool {
Level::$lvl.le(other)
}

#[inline]
fn gt(&self, other: &LevelFilter) -> bool {
Level::$lvl.gt(other)
}

#[inline]
fn ge(&self, other: &LevelFilter) -> bool {
Level::$lvl.ge(other)
}
}
)*
};
}

define_static_levels![
StaticLevelError => Error,
StaticLevelWarn => Warn,
StaticLevelInfo => Info,
StaticLevelDebug => Debug,
StaticLevelTrace => Trace,
];

// `LogTarget`.

impl LogTarget for &str {
#[inline]
fn with<R>(self, _module_path: &'static str, f: impl FnOnce(&str) -> R) -> R {
f(self)
}
}

#[derive(Debug)]
pub struct TargetIsModulePath;

impl LogTarget for TargetIsModulePath {
#[inline]
fn with<R>(self, module_path: &'static str, f: impl FnOnce(&str) -> R) -> R {
f(module_path)
}
}

// `LogKVs`.

impl LogKVs for &[(&str, &LogKvValue<'_>)] {
#[inline]
fn with<R>(self, f: impl FnOnce(&[(&str, &LogKvValue)]) -> R) -> R {
f(self)
}
}

#[derive(Debug)]
pub struct EmptyKVs;

impl LogKVs for EmptyKVs {
#[inline]
fn with<R>(self, f: impl FnOnce(&[(&str, &LogKvValue)]) -> R) -> R {
f(&[])
}
}

// Log functions.

fn log_0(
module_path: &'static str,
file: &'static str,
line: u32,
args: Arguments,
level: Level,
target: &str,
kvs: &[(&str, &LogKvValue)],
) {
#[cfg(not(feature = "kv_unstable"))]
if !kvs.is_empty() {
panic!(
"key-value support is experimental and must be enabled using the `kv_unstable` feature"
);
}

let mut builder = Record::builder();

builder
.args(args)
.level(level)
.target(target)
.module_path_static(Some(module_path))
.file_static(Some(file))
.line(Some(line));

#[cfg(feature = "kv_unstable")]
builder.key_values(&kvs);

crate::logger().log(&builder.build());
}

fn log_1<K>(
module_path: &'static str,
file: &'static str,
line: u32,
args: Arguments,
level: Level,
target: &str,
kvs: K,
) where
K: LogKVs,
{
kvs.with(|kvs| log_0(module_path, file, line, args, level, target, kvs));
}

fn log_2<T, K>(
module_path: &'static str,
file: &'static str,
line: u32,
args: Arguments,
level: Level,
target: T,
kvs: K,
) where
T: LogTarget,
K: LogKVs,
{
target.with(module_path, |target| {
log_1(
module_path,
file,
line,
args,
level.into_log_level(),
target,
kvs,
)
});
}

pub fn log<L, T, K>(
module_path: &'static str,
file: &'static str,
line: u32,
args: Arguments,
level: L,
target: T,
kvs: K,
) where
L: LogLevel,
T: LogTarget,
K: LogKVs,
{
log_2(
module_path,
file,
line,
args,
level.into_log_level(),
target,
kvs,
)
}

pub fn enabled(level: Level, target: &str) -> bool {
crate::logger().enabled(&Metadata::builder().level(level).target(target).build())
}
60 changes: 1 addition & 59 deletions src/lib.rs
Expand Up @@ -1466,65 +1466,7 @@ pub fn logger() -> &'static dyn Log {

// WARNING: this is not part of the crate's public API and is subject to change at any time
#[doc(hidden)]
#[cfg(not(feature = "kv_unstable"))]
pub fn __private_api_log(
args: fmt::Arguments,
level: Level,
&(target, module_path, file, line): &(&str, &'static str, &'static str, u32),
kvs: Option<&[(&str, &str)]>,
) {
if kvs.is_some() {
panic!(
"key-value support is experimental and must be enabled using the `kv_unstable` feature"
)
}

logger().log(
&Record::builder()
.args(args)
.level(level)
.target(target)
.module_path_static(Some(module_path))
.file_static(Some(file))
.line(Some(line))
.build(),
);
}

// WARNING: this is not part of the crate's public API and is subject to change at any time
#[doc(hidden)]
#[cfg(feature = "kv_unstable")]
pub fn __private_api_log(
args: fmt::Arguments,
level: Level,
&(target, module_path, file, line): &(&str, &'static str, &'static str, u32),
kvs: Option<&[(&str, &dyn kv::ToValue)]>,
) {
logger().log(
&Record::builder()
.args(args)
.level(level)
.target(target)
.module_path_static(Some(module_path))
.file_static(Some(file))
.line(Some(line))
.key_values(&kvs)
.build(),
);
}

// WARNING: this is not part of the crate's public API and is subject to change at any time
#[doc(hidden)]
pub fn __private_api_enabled(level: Level, target: &str) -> bool {
logger().enabled(&Metadata::builder().level(level).target(target).build())
}

// WARNING: this is not part of the crate's public API and is subject to change at any time
#[doc(hidden)]
pub mod __private_api {
pub use std::option::Option;
pub use std::{file, format_args, line, module_path, stringify};
}
pub mod __private_api;

/// The statically resolved maximum log level.
///
Expand Down

0 comments on commit 1b59e61

Please sign in to comment.