Skip to content

Commit

Permalink
Split pattern template parser from spdlog-macros to spdlog-internal
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed Mar 9, 2024
1 parent 8042dbc commit 41fb149
Show file tree
Hide file tree
Showing 14 changed files with 949 additions and 778 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
resolver = "2"
members = [
"spdlog",
"spdlog-internal",
"spdlog-macros",
]
11 changes: 11 additions & 0 deletions spdlog-internal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "spdlog-internal"
version = "0.1.0"
edition = "2021"
rust-version = "1.56"

[dependencies]
nom = "7.1.3"
strum = { version = "0.24.1", features = ["derive"] }
strum_macros = "0.24.3"
thiserror = "1.0.40"
12 changes: 12 additions & 0 deletions spdlog-internal/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pub mod pattern_parser;

#[macro_export]
macro_rules! impossible {
( $dbg_lit:literal, $($fmt_arg:expr),* ) => {
panic!(
"this should not happen, please open an issue on 'spdlog-rs' Bug Tracker\n\nsource: {}\ndebug:{}",
format!("{}:{}", file!(), line!()),
format!($dbg_lit, $($fmt_arg),*),
)
};
}
106 changes: 106 additions & 0 deletions spdlog-internal/src/pattern_parser/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use std::fmt::{self, Display};

use nom::error::Error as NomError;
use thiserror::Error;

use super::PatternKind;
use crate::impossible;

#[derive(Error, Debug)]
pub enum Error {
ConflictName {
existing: PatternKind<()>,
incoming: PatternKind<()>,
},
Template(TemplateError),
Parse(NomError<String>),
}

impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::ConflictName { existing, incoming } => match (existing, incoming) {
(PatternKind::BuiltIn(_), PatternKind::Custom { .. }) => {
write!(
f,
"'{}' is already a built-in pattern, please try another name",
existing.placeholder()
)
}
(PatternKind::Custom { .. }, PatternKind::Custom { .. }) => {
write!(
f,
"the constructor of custom pattern '{}' is specified more than once",
existing.placeholder()
)
}
(_, PatternKind::BuiltIn { .. }) => {
impossible!("{}", self)
}
},
Error::Template(err) => {
write!(f, "template ill-format: {}", err)
}
Error::Parse(err) => {
write!(f, "failed to parse template string: {}", err)
}
}
}
}

#[derive(Error, Debug)]
pub enum TemplateError {
WrongPatternKindReference {
is_built_as_custom: bool,
placeholder: String,
},
UnknownPatternReference {
is_custom: bool,
placeholder: String,
},
MultipleStyleRange,
}

impl Display for TemplateError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TemplateError::WrongPatternKindReference {
is_built_as_custom,
placeholder,
} => {
if *is_built_as_custom {
write!(
f,
"'{}' is a built-in pattern, it cannot be used as a custom pattern. try to replace it with `{{{}}}`",
placeholder, placeholder
)
} else {
write!(
f,
"'{}' is a custom pattern, it cannot be used as a built-in pattern. try to replace it with `{{${}}}`",
placeholder, placeholder
)
}
}
TemplateError::UnknownPatternReference {
is_custom,
placeholder,
} => {
if *is_custom {
write!(
f,
"the constructor of custom pattern '{}' is not specified",
placeholder
)
} else {
write!(f, "no built-in pattern named '{}'", placeholder)
}
}
TemplateError::MultipleStyleRange => {
write!(f, "multiple style ranges are not currently supported")
}
}
}
}

pub type Result<T> = std::result::Result<T, Error>;
File renamed without changes.
144 changes: 144 additions & 0 deletions spdlog-internal/src/pattern_parser/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use std::borrow::Cow;

use strum::IntoEnumIterator;
use strum_macros::{EnumDiscriminants, EnumIter, EnumString, IntoStaticStr};

pub mod error;
mod helper;
pub mod parse;
mod registry;

pub use error::{Error, Result};
pub use registry::PatternRegistry;

#[derive(
Clone, Copy, Debug, Eq, PartialEq, IntoStaticStr, EnumDiscriminants, EnumIter, EnumString,
)]
#[strum_discriminants(derive(IntoStaticStr))]
pub enum BuiltInFormatterInner {
#[strum(serialize = "weekday_name")]
AbbrWeekdayName,
#[strum(serialize = "weekday_name_full")]
WeekdayName,
#[strum(serialize = "month_name")]
AbbrMonthName,
#[strum(serialize = "month_name_full")]
MonthName,
#[strum(serialize = "datetime")]
FullDateTime,
#[strum(serialize = "year_short")]
ShortYear,
#[strum(serialize = "year")]
Year,
#[strum(serialize = "date_short")]
ShortDate,
#[strum(serialize = "date")]
Date,
#[strum(serialize = "month")]
Month,
#[strum(serialize = "day")]
Day,
#[strum(serialize = "hour")]
Hour,
#[strum(serialize = "hour_12")]
Hour12,
#[strum(serialize = "minute")]
Minute,
#[strum(serialize = "second")]
Second,
#[strum(serialize = "millisecond")]
Millisecond,
#[strum(serialize = "microsecond")]
Microsecond,
#[strum(serialize = "nanosecond")]
Nanosecond,
#[strum(serialize = "am_pm")]
AmPm,
#[strum(serialize = "time_12")]
Time12,
#[strum(serialize = "time_short")]
ShortTime,
#[strum(serialize = "time")]
Time,
#[strum(serialize = "tz_offset")]
TzOffset,
#[strum(serialize = "unix_timestamp")]
UnixTimestamp,
#[strum(serialize = "full")]
Full,
#[strum(serialize = "level")]
Level,
#[strum(serialize = "level_short")]
ShortLevel,
#[strum(serialize = "source")]
Source,
#[strum(serialize = "file_name")]
SourceFilename,
#[strum(serialize = "file")]
SourceFile,
#[strum(serialize = "line")]
SourceLine,
#[strum(serialize = "column")]
SourceColumn,
#[strum(serialize = "module_path")]
SourceModulePath,
#[strum(serialize = "logger")]
LoggerName,
#[strum(serialize = "payload")]
Payload,
#[strum(serialize = "pid")]
ProcessId,
#[strum(serialize = "tid")]
ThreadId,
#[strum(serialize = "eol")]
Eol,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BuiltInFormatter(BuiltInFormatterInner);

impl BuiltInFormatter {
pub fn iter() -> impl Iterator<Item = BuiltInFormatter> {
BuiltInFormatterInner::iter().map(BuiltInFormatter)
}

pub fn struct_name(&self) -> &'static str {
BuiltInFormatterInnerDiscriminants::from(self.0).into()
}

pub fn placeholder(&self) -> &'static str {
self.0.into()
}

pub fn inner(&self) -> BuiltInFormatterInner {
self.0
}
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum PatternKind<F> {
BuiltIn(BuiltInFormatter),
Custom {
placeholder: Cow<'static, str>,
factory: F,
},
}

impl<F> PatternKind<F> {
pub(crate) fn placeholder(&self) -> &str {
match self {
PatternKind::BuiltIn(f) => f.placeholder(),
PatternKind::Custom { placeholder, .. } => placeholder,
}
}

pub(crate) fn to_factory_erased(&self) -> PatternKind<()> {
match self {
PatternKind::BuiltIn(b) => PatternKind::BuiltIn(b.clone()),
PatternKind::Custom { placeholder, .. } => PatternKind::Custom {
placeholder: placeholder.clone(),
factory: (),
},
}
}
}
Loading

0 comments on commit 41fb149

Please sign in to comment.