Skip to content

Commit b0452a2

Browse files
committed
2
1 parent 15ba14c commit b0452a2

File tree

4 files changed

+128
-22
lines changed

4 files changed

+128
-22
lines changed

spdlog/src/config/mod.rs

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ mod source;
33

44
pub(crate) mod deser;
55

6-
use std::{collections::HashMap, convert::Infallible};
6+
use std::{
7+
cell::RefCell,
8+
collections::{hash_map::Entry, HashMap},
9+
convert::Infallible,
10+
};
711

812
pub use registry::*;
913
use serde::{de::DeserializeOwned, Deserialize};
1014
pub use source::*;
1115

12-
use crate::{sync::*, Result};
16+
use crate::{sync::*, Logger, LoggerBuilder, LoggerParams, Result};
1317

1418
// TODO: Builder?
1519
#[derive(PartialEq, Eq, Hash)]
@@ -57,25 +61,78 @@ pub trait Configurable: Sized {
5761

5862
// #[derive(Deserialize)]
5963
// #[serde(deny_unknown_fields)]
60-
// pub(super) struct Logger(#[serde(deserialize_with =
64+
// struct Logger(#[serde(deserialize_with =
6165
// "crate::config::deser::logger")] crate::Logger);
6266

63-
#[derive(PartialEq, Debug, Deserialize)]
67+
#[derive(Deserialize)]
6468
#[serde(deny_unknown_fields)]
65-
pub(super) struct ConfigView {
66-
loggers: HashMap<String, toml::Value>,
69+
struct ConfigView {
70+
loggers: HashMap<String, LoggerParams>,
71+
}
72+
73+
#[derive(Debug, Hash, Eq, PartialEq)]
74+
enum LoggerKind {
75+
Default,
76+
Named(String),
6777
}
6878

69-
#[derive(PartialEq, Debug)]
7079
pub struct Config {
71-
view: ConfigView, // Stores the config values only, build lazily
80+
view: ConfigView, // Stores the config values only, build loggers lazily
81+
built: RefCell<HashMap<LoggerKind, Weak<Logger>>>,
82+
}
83+
// TODO: But only build once! For later acquires, return the built `Arc<Logger>`
84+
// Stores `Weak`?
85+
86+
impl Config {
87+
pub fn acquire_default_logger(&self) -> Option<Result<Arc<Logger>>> {
88+
self.acquire_logger_inner(LoggerKind::Default)
89+
}
90+
91+
pub fn acquire_logger<S>(&self, name: S) -> Option<Result<Arc<Logger>>>
92+
where
93+
S: AsRef<str>,
94+
{
95+
self.acquire_logger_inner(LoggerKind::Named(name.as_ref().into()))
96+
}
97+
}
98+
99+
impl Config {
100+
fn acquire_logger_inner(&self, logger_kind: LoggerKind) -> Option<Result<Arc<Logger>>> {
101+
let logger_name = match &logger_kind {
102+
LoggerKind::Default => "default",
103+
LoggerKind::Named(name) => name,
104+
};
105+
let logger_params = self.view.loggers.get(logger_name)?;
106+
107+
// TODO: Factually unnecessary clone in the argument of `build_config`, could be
108+
// avoided with some effort
109+
Some((|| match self.built.borrow_mut().entry(logger_kind) {
110+
Entry::Occupied(mut entry) => match entry.get().upgrade() {
111+
None => {
112+
let new = Arc::new(LoggerBuilder::build_config(logger_params.clone())?);
113+
entry.insert(Arc::downgrade(&new));
114+
Ok(new)
115+
}
116+
Some(built) => Ok(built),
117+
},
118+
Entry::Vacant(entry) => {
119+
let new = Arc::new(LoggerBuilder::build_config(logger_params.clone())?);
120+
entry.insert(Arc::downgrade(&new));
121+
Ok(new)
122+
}
123+
})())
124+
}
72125
}
73126

127+
// TODO: temp code
74128
impl Config {
75129
// TODO: Remember to remove me
76130
pub fn new_for_test(inputs: &str) -> Result<Self> {
77131
let view = toml::from_str(inputs).unwrap();
78-
Ok(Self { view })
132+
Ok(Self {
133+
view,
134+
built: RefCell::new(HashMap::new()),
135+
})
79136
}
80137
}
81138

spdlog/src/config/registry.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ mod erased_serde_ext {
4444
use erased_serde_ext::*;
4545

4646
type ComponentDeser<C> = fn(de: &mut dyn ErasedDeserializer) -> Result<C>;
47-
4847
type RegisteredComponents<C> = HashMap<&'static str, ComponentDeser<C>>;
4948

5049
pub struct Registry {

spdlog/src/logger.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,20 @@ use crate::{
1616
fn check_logger_name(name: impl AsRef<str>) -> StdResult<(), SetLoggerNameError> {
1717
let name = name.as_ref();
1818

19-
if name.chars().any(|ch| {
20-
ch == ','
21-
|| ch == '='
22-
|| ch == '*'
23-
|| ch == '?'
24-
|| ch == '$'
25-
|| ch == '{'
26-
|| ch == '}'
27-
|| ch == '"'
28-
|| ch == '\''
29-
|| ch == ';'
30-
}) || name.starts_with(' ')
19+
if name.to_ascii_lowercase() == "default"
20+
|| name.chars().any(|ch| {
21+
ch == ','
22+
|| ch == '='
23+
|| ch == '*'
24+
|| ch == '?'
25+
|| ch == '$'
26+
|| ch == '{'
27+
|| ch == '}'
28+
|| ch == '"'
29+
|| ch == '\''
30+
|| ch == ';'
31+
})
32+
|| name.starts_with(' ')
3133
|| name.ends_with(' ')
3234
{
3335
Err(SetLoggerNameError::new(name))

spdlog/tests/config.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use std::{
2+
fs,
3+
path::{Path, PathBuf},
4+
sync::Arc,
5+
};
6+
7+
use once_cell::sync::Lazy;
8+
use spdlog::{
9+
config::{self, Config},
10+
formatter::{pattern, PatternFormatter},
11+
};
12+
13+
include!(concat!(
14+
env!("OUT_DIR"),
15+
"/test_utils/common_for_integration_test.rs"
16+
));
17+
use test_utils::*;
18+
19+
static TEMP_DIR: Lazy<PathBuf> = Lazy::new(|| {
20+
let temp_dir = PathBuf::from(env!("OUT_DIR"))
21+
.join("dev")
22+
.join("integration-test-config");
23+
fs::create_dir_all(&temp_dir).unwrap();
24+
temp_dir
25+
});
26+
27+
#[test]
28+
fn test_config_full() {
29+
let path = TEMP_DIR.join("file-sink.log");
30+
let inputs = format!(
31+
r#"
32+
[loggers.default]
33+
sinks = [
34+
{{ name = "$ConfigMockSink1", arg = 114 }},
35+
{{ name = "$ConfigMockSink2", arg = 514 }},
36+
{{ name = "$ConfigMockSink3", arg = 1919 }},
37+
{{ name = "FileSink", path = "{}", formatter = {{ name = "PatternFormatter", template = "Meow! {{payload}}{{eol}}" }} }}
38+
]
39+
flush_level_filter = "Equal(Info)" # TODO: reconsider the syntax
40+
41+
[loggers.network]
42+
sinks = [ {{ name = "$ConfigMockSink2", arg = 810 }} ]
43+
# TODO: flush_period = "10s"
44+
"#,
45+
path.display()
46+
);
47+
let config = Config::new_for_test(&inputs).unwrap();
48+
}

0 commit comments

Comments
 (0)