use super::{callsite, field};
use std::fmt;
pub struct Metadata<'a> {
name: &'static str,
target: &'a str,
level: Level,
module_path: Option<&'a str>,
file: Option<&'a str>,
line: Option<u32>,
fields: field::FieldSet,
kind: Kind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Kind(KindInner);
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Level(LevelInner);
impl<'a> Metadata<'a> {
pub const fn new(
name: &'static str,
target: &'a str,
level: Level,
file: Option<&'a str>,
line: Option<u32>,
module_path: Option<&'a str>,
fields: field::FieldSet,
kind: Kind,
) -> Self {
Metadata {
name,
target,
level,
module_path,
file,
line,
fields,
kind,
}
}
pub fn fields(&self) -> &field::FieldSet {
&self.fields
}
pub fn level(&self) -> &Level {
&self.level
}
pub fn name(&self) -> &'static str {
self.name
}
pub fn target(&self) -> &'a str {
self.target
}
pub fn module_path(&self) -> Option<&'a str> {
self.module_path
}
pub fn file(&self) -> Option<&'a str> {
self.file
}
pub fn line(&self) -> Option<u32> {
self.line
}
#[inline]
pub fn callsite(&self) -> callsite::Identifier {
self.fields.callsite()
}
pub fn is_event(&self) -> bool {
self.kind.is_event()
}
pub fn is_span(&self) -> bool {
self.kind.is_span()
}
}
impl<'a> fmt::Debug for Metadata<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut meta = f.debug_struct("Metadata");
meta.field("name", &self.name)
.field("target", &self.target)
.field("level", &self.level);
if let Some(path) = self.module_path() {
meta.field("module_path", &path);
}
match (self.file(), self.line()) {
(Some(file), Some(line)) => {
meta.field("location", &format_args!("{}:{}", file, line));
}
(Some(file), None) => {
meta.field("file", &format_args!("{}", file));
}
(None, Some(line)) => {
meta.field("line", &line);
}
(None, None) => {}
};
meta.field("fields", &format_args!("{}", self.fields))
.field("callsite", &self.callsite())
.field("kind", &self.kind)
.finish()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
enum KindInner {
Event,
Span,
}
impl Kind {
pub const EVENT: Kind = Kind(KindInner::Event);
pub const SPAN: Kind = Kind(KindInner::Span);
pub fn is_span(&self) -> bool {
match self {
Kind(KindInner::Span) => true,
_ => false,
}
}
pub fn is_event(&self) -> bool {
match self {
Kind(KindInner::Event) => true,
_ => false,
}
}
}
impl Level {
pub const ERROR: Level = Level(LevelInner::Error);
pub const WARN: Level = Level(LevelInner::Warn);
pub const INFO: Level = Level(LevelInner::Info);
pub const DEBUG: Level = Level(LevelInner::Debug);
pub const TRACE: Level = Level(LevelInner::Trace);
}
#[repr(usize)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
enum LevelInner {
Error = 1,
Warn,
Info,
Debug,
Trace,
}