#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(missing_docs)]
use std::ops::Deref;
use std::sync::Arc;
use log::Metadata;
use log::Record;
use logforth_core::Logger;
use logforth_core::record::FilterCriteria;
#[derive(Debug)]
pub struct LogBridge {
logger: Arc<Logger>,
}
impl LogBridge {
pub fn new(logger: impl Into<Arc<Logger>>) -> Self {
Self {
logger: logger.into(),
}
}
}
impl Deref for LogBridge {
type Target = Logger;
fn deref(&self) -> &Self::Target {
&self.logger
}
}
impl log::Log for LogBridge {
fn enabled(&self, metadata: &Metadata) -> bool {
forward_enabled(&self.logger, metadata)
}
fn log(&self, record: &Record) {
forward_log(&self.logger, record);
}
fn flush(&self) {
self.logger.flush();
}
}
fn forward_enabled(logger: &Logger, metadata: &Metadata) -> bool {
let criteria = FilterCriteria::builder()
.target(metadata.target())
.level(level_to_level(metadata.level()))
.build();
Logger::enabled(logger, &criteria)
}
fn forward_log(logger: &Logger, record: &Record) {
if !forward_enabled(logger, record.metadata()) {
return;
}
let mut builder = logforth_core::record::Record::builder()
.level(level_to_level(record.level()))
.target(record.target())
.line(record.line());
builder = if let Some(module_path) = record.module_path_static() {
builder.module_path_static(module_path)
} else {
builder.module_path(record.module_path())
};
builder = if let Some(file) = record.file_static() {
builder.file_static(file)
} else {
builder.file(record.file())
};
builder = builder.payload(*record.args());
#[cfg(not(feature = "serde"))]
{
let kvs = kv::key_values_stage_one(record.key_values());
let new_kvs = kv::key_value_stage_two(&kvs);
builder = builder.key_values(new_kvs.to_key_values());
Logger::log(logger, &builder.build());
}
#[cfg(feature = "serde")]
{
let kvs = kv::key_values(record.key_values());
builder = builder.key_values(kvs.to_key_values());
Logger::log(logger, &builder.build());
}
}
fn level_to_level(level: log::Level) -> logforth_core::record::Level {
match level {
log::Level::Error => logforth_core::record::Level::Error,
log::Level::Warn => logforth_core::record::Level::Warn,
log::Level::Info => logforth_core::record::Level::Info,
log::Level::Debug => logforth_core::record::Level::Debug,
log::Level::Trace => logforth_core::record::Level::Trace,
}
}
#[cfg(not(feature = "serde"))]
mod kv {
pub(super) struct KeyValuesStageOne<'a> {
kvs: Vec<(KeyStageOne<'a>, ValueStageOne<'a>)>,
}
struct KeyStageOne<'a>(log::kv::Key<'a>);
struct ValueStageOne<'a>(MaybeOwnedValue<'a>);
enum MaybeOwnedValue<'a> {
Borrowed(logforth_core::kv::Value<'a>),
Owned(String),
}
pub(super) fn key_values_stage_one<'a>(
source: &'a dyn log::kv::Source,
) -> KeyValuesStageOne<'a> {
let mut kvs = Vec::with_capacity(log::kv::Source::count(source));
struct KeyValueVisitor<'a, 'b> {
kvs: &'b mut Vec<(KeyStageOne<'a>, ValueStageOne<'a>)>,
}
impl<'a, 'b> log::kv::VisitSource<'a> for KeyValueVisitor<'a, 'b> {
fn visit_pair(
&mut self,
key: log::kv::Key<'a>,
value: log::kv::Value<'a>,
) -> Result<(), log::kv::Error> {
let key = KeyStageOne(key);
let value = ValueStageOne(value_to_value(value));
self.kvs.push((key, value));
Ok(())
}
}
let mut visitor = KeyValueVisitor { kvs: &mut kvs };
log::kv::Source::visit(source, &mut visitor).unwrap();
KeyValuesStageOne { kvs }
}
fn value_to_value(value: log::kv::Value) -> MaybeOwnedValue {
struct ValueVisitor<'a>(MaybeOwnedValue<'a>);
impl<'a> log::kv::VisitValue<'a> for ValueVisitor<'a> {
fn visit_any(&mut self, value: log::kv::Value) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Owned(value.to_string());
Ok(())
}
fn visit_null(&mut self) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::none());
Ok(())
}
fn visit_u64(&mut self, value: u64) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::u64(value));
Ok(())
}
fn visit_i64(&mut self, value: i64) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::i64(value));
Ok(())
}
fn visit_u128(&mut self, value: u128) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::u128(value));
Ok(())
}
fn visit_i128(&mut self, value: i128) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::i128(value));
Ok(())
}
fn visit_f64(&mut self, value: f64) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::f64(value));
Ok(())
}
fn visit_bool(&mut self, value: bool) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::bool(value));
Ok(())
}
fn visit_str(&mut self, value: &str) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Owned(value.to_string());
Ok(())
}
fn visit_borrowed_str(&mut self, value: &'a str) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::str(value));
Ok(())
}
fn visit_char(&mut self, value: char) -> Result<(), log::kv::Error> {
self.0 = MaybeOwnedValue::Borrowed(logforth_core::kv::Value::char(value));
Ok(())
}
}
let mut visitor = ValueVisitor(MaybeOwnedValue::Borrowed(logforth_core::kv::Value::none()));
value.visit(&mut visitor).unwrap();
visitor.0
}
pub(super) struct KeyValuesStageTwo<'a> {
kvs: Vec<(KeyStageTwo<'a>, ValueStageTwo<'a>)>,
}
impl<'a> KeyValuesStageTwo<'a> {
pub(super) fn to_key_values(&self) -> logforth_core::kv::KeyValues<'_> {
logforth_core::kv::KeyValues::from(self.kvs.as_slice())
}
}
type KeyStageTwo<'a> = logforth_core::kv::Key<'a>;
type ValueStageTwo<'a> = logforth_core::kv::Value<'a>;
pub(super) fn key_value_stage_two<'a>(kvs: &'a KeyValuesStageOne<'a>) -> KeyValuesStageTwo<'a> {
let mut new_kvs = Vec::with_capacity(kvs.kvs.len());
for (k, v) in &kvs.kvs {
let k = if let Some(k) = k.0.to_static_str() {
logforth_core::kv::Key::new(k)
} else {
logforth_core::kv::Key::borrowed(k.0.as_str())
};
let v = match &v.0 {
MaybeOwnedValue::Borrowed(v) => v.clone(),
MaybeOwnedValue::Owned(s) => logforth_core::kv::Value::str(s.as_str()),
};
new_kvs.push((k, v));
}
KeyValuesStageTwo { kvs: new_kvs }
}
}
#[cfg(feature = "serde")]
mod kv {
use std::collections::HashMap;
use std::fmt;
use std::marker::PhantomData;
use logforth_core::kv::KeyOwned;
use logforth_core::kv::ValueOwned;
use logforth_core::kv::ValueView;
pub(super) struct KeyValues<'a> {
kvs: Vec<(KeyOwned, ValueOwned)>,
p: PhantomData<&'a ()>,
}
impl<'a> KeyValues<'a> {
pub(super) fn to_key_values(&self) -> logforth_core::kv::KeyValues<'_> {
logforth_core::kv::KeyValues::from(self.kvs.as_slice())
}
}
pub(super) fn key_values<'a>(source: &'a dyn log::kv::Source) -> KeyValues<'a> {
struct KeyValueVisitor(Vec<(KeyOwned, ValueOwned)>);
impl<'a> log::kv::VisitSource<'a> for KeyValueVisitor {
fn visit_pair(
&mut self,
key: log::kv::Key<'a>,
value: log::kv::Value<'a>,
) -> Result<(), log::kv::Error> {
let key = if let Some(key) = key.to_static_str() {
KeyOwned::new(key)
} else {
KeyOwned::new(key.to_string())
};
if let Some(value) = value_to_value(value) {
self.0.push((key, value));
}
Ok(())
}
}
let mut visitor = KeyValueVisitor(Vec::with_capacity(log::kv::Source::count(source)));
log::kv::Source::visit(source, &mut visitor).unwrap();
KeyValues {
kvs: visitor.0,
p: PhantomData,
}
}
fn value_to_value(value: impl serde::Serialize) -> Option<ValueOwned> {
value.serialize(ValueSerializer).ok()
}
struct ValueSerializer;
struct ValueSerializeSeq {
value: Vec<ValueOwned>,
}
struct ValueSerializeTuple {
value: Vec<ValueOwned>,
}
struct ValueSerializeTupleStruct {
value: Vec<ValueOwned>,
}
struct ValueSerializeMap {
key: Option<KeyOwned>,
value: HashMap<KeyOwned, ValueOwned>,
}
struct ValueSerializeStruct {
value: HashMap<KeyOwned, ValueOwned>,
}
struct ValueSerializeTupleVariant {
variant: &'static str,
value: Vec<ValueOwned>,
}
struct ValueSerializeStructVariant {
variant: &'static str,
value: HashMap<KeyOwned, ValueOwned>,
}
#[derive(Debug)]
struct ValueError(String);
impl fmt::Display for ValueError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl serde::ser::Error for ValueError {
fn custom<T>(msg: T) -> Self
where
T: fmt::Display,
{
ValueError(msg.to_string())
}
}
impl std::error::Error for ValueError {}
impl serde::Serializer for ValueSerializer {
type Ok = ValueOwned;
type Error = ValueError;
type SerializeSeq = ValueSerializeSeq;
type SerializeTuple = ValueSerializeTuple;
type SerializeTupleStruct = ValueSerializeTupleStruct;
type SerializeTupleVariant = ValueSerializeTupleVariant;
type SerializeMap = ValueSerializeMap;
type SerializeStruct = ValueSerializeStruct;
type SerializeStructVariant = ValueSerializeStructVariant;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::bool(v))
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::i64(v))
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
if let Ok(v) = v.try_into() {
self.serialize_i64(v)
} else {
self.collect_str(&v)
}
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.serialize_u64(v as u64)
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.serialize_u64(v as u64)
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.serialize_u64(v as u64)
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::u64(v))
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
if let Ok(v) = v.try_into() {
self.serialize_u64(v)
} else {
self.collect_str(&v)
}
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.serialize_f64(v as f64)
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::f64(v))
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::char(v))
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::str(v.to_string()))
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::bytes(v.to_vec()))
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::none())
}
fn serialize_some<T: serde::Serialize + ?Sized>(
self,
value: &T,
) -> Result<Self::Ok, Self::Error> {
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::none())
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::str(name))
}
fn serialize_unit_variant(
self,
_: &'static str,
_: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::str(variant))
}
fn serialize_newtype_struct<T: serde::Serialize + ?Sized>(
self,
_: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error> {
value.serialize(self)
}
fn serialize_newtype_variant<T: serde::Serialize + ?Sized>(
self,
_: &'static str,
_: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error> {
let mut map = self.serialize_map(Some(1))?;
serde::ser::SerializeMap::serialize_entry(&mut map, variant, value)?;
serde::ser::SerializeMap::end(map)
}
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Ok(ValueSerializeSeq { value: vec![] })
}
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
Ok(ValueSerializeTuple { value: vec![] })
}
fn serialize_tuple_struct(
self,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Ok(ValueSerializeTupleStruct { value: vec![] })
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
variant: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Ok(ValueSerializeTupleVariant {
variant,
value: vec![],
})
}
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Ok(ValueSerializeMap {
key: None,
value: HashMap::new(),
})
}
fn serialize_struct(
self,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Ok(ValueSerializeStruct {
value: HashMap::new(),
})
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
variant: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
Ok(ValueSerializeStructVariant {
variant,
value: HashMap::new(),
})
}
}
impl serde::ser::SerializeSeq for ValueSerializeSeq {
type Ok = ValueOwned;
type Error = ValueError;
fn serialize_element<T: serde::Serialize + ?Sized>(
&mut self,
value: &T,
) -> Result<(), Self::Error> {
self.value.push(value.serialize(ValueSerializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::from_vec(self.value))
}
}
impl serde::ser::SerializeTuple for ValueSerializeTuple {
type Ok = ValueOwned;
type Error = ValueError;
fn serialize_element<T: serde::Serialize + ?Sized>(
&mut self,
value: &T,
) -> Result<(), Self::Error> {
self.value.push(value.serialize(ValueSerializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::from_vec(self.value))
}
}
impl serde::ser::SerializeTupleStruct for ValueSerializeTupleStruct {
type Ok = ValueOwned;
type Error = ValueError;
fn serialize_field<T: serde::Serialize + ?Sized>(
&mut self,
value: &T,
) -> Result<(), Self::Error> {
self.value.push(value.serialize(ValueSerializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::from_vec(self.value))
}
}
impl serde::ser::SerializeTupleVariant for ValueSerializeTupleVariant {
type Ok = ValueOwned;
type Error = ValueError;
fn serialize_field<T: serde::Serialize + ?Sized>(
&mut self,
value: &T,
) -> Result<(), Self::Error> {
self.value.push(value.serialize(ValueSerializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::from_hash_map({
let mut variant = HashMap::<KeyOwned, ValueOwned>::new();
variant.insert(KeyOwned::new(self.variant), ValueOwned::list(self.value));
variant
}))
}
}
impl serde::ser::SerializeMap for ValueSerializeMap {
type Ok = ValueOwned;
type Error = ValueError;
fn serialize_key<T: serde::Serialize + ?Sized>(
&mut self,
key: &T,
) -> Result<(), Self::Error> {
let key = match key.serialize(ValueSerializer)?.view() {
ValueView::StaticStr(s) => KeyOwned::new(s),
value => KeyOwned::new(value.to_string()),
};
self.key = Some(key);
Ok(())
}
fn serialize_value<T: serde::Serialize + ?Sized>(
&mut self,
value: &T,
) -> Result<(), Self::Error> {
let key = self
.key
.take()
.ok_or_else(|| serde::ser::Error::custom("missing key"))?;
let value = value.serialize(ValueSerializer)?;
self.value.insert(key, value);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::from_hash_map(self.value))
}
}
impl serde::ser::SerializeStruct for ValueSerializeStruct {
type Ok = ValueOwned;
type Error = ValueError;
fn serialize_field<T: serde::Serialize + ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error> {
let key = KeyOwned::new(key);
let value = value.serialize(ValueSerializer)?;
self.value.insert(key, value);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::from_hash_map(self.value))
}
}
impl serde::ser::SerializeStructVariant for ValueSerializeStructVariant {
type Ok = ValueOwned;
type Error = ValueError;
fn serialize_field<T: serde::Serialize + ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error> {
let key = KeyOwned::new(key);
let value = value.serialize(ValueSerializer)?;
self.value.insert(key, value);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(ValueOwned::from_hash_map({
let mut variant = HashMap::<KeyOwned, ValueOwned>::new();
variant.insert(
KeyOwned::new(self.variant),
ValueOwned::from_hash_map(self.value),
);
variant
}))
}
}
}