pumpkin_core/statistics/
statistic_logging.rs1use std::fmt::Debug;
5use std::fmt::Display;
6use std::fmt::Formatter;
7use std::io::Write;
8use std::io::stdout;
9use std::sync::OnceLock;
10use std::sync::RwLock;
11
12use convert_case::Case;
13use convert_case::Casing;
14
15pub struct StatisticOptions<'a> {
18 statistic_prefix: &'a str,
21 after_statistics: Option<&'a str>,
23 statistics_casing: Option<Case<'static>>,
25 statistics_writer: Box<dyn Write + Send + Sync>,
27}
28
29impl Debug for StatisticOptions<'_> {
30 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
31 f.debug_struct("StatisticOptions")
32 .field("statistic_prefix", &self.statistic_prefix)
33 .field("after_statistics", &self.after_statistics)
34 .field("statistics_casing", &self.statistics_casing)
35 .field("statistics_writer", &"<Writer>")
36 .finish()
37 }
38}
39
40static STATISTIC_OPTIONS: OnceLock<RwLock<StatisticOptions>> = OnceLock::new();
41
42pub fn configure_statistic_logging(
49 prefix: &'static str,
50 after: Option<&'static str>,
51 casing: Option<Case<'static>>,
52 writer: Option<Box<dyn Write + Send + Sync>>,
53) {
54 let _ = STATISTIC_OPTIONS.get_or_init(|| {
55 RwLock::from(StatisticOptions {
56 statistic_prefix: prefix,
57 after_statistics: after,
58 statistics_casing: casing,
59 statistics_writer: writer.unwrap_or(Box::new(stdout())),
60 })
61 });
62}
63
64pub fn log_statistic(name: impl Display, value: impl Display) {
67 let Some(statistic_options_lock) = STATISTIC_OPTIONS.get() else {
68 return;
69 };
70
71 let Ok(mut statistic_options) = statistic_options_lock.write() else {
72 return;
73 };
74
75 let name = if let Some(casing) = &statistic_options.statistics_casing {
76 name.to_string().to_case(*casing)
77 } else {
78 name.to_string()
79 };
80 let prefix = statistic_options.statistic_prefix;
81 let _ = writeln!(
82 statistic_options.statistics_writer,
83 "{prefix} {name}={value}"
84 );
85}
86
87pub fn log_statistic_postfix() {
93 let Some(statistic_options_lock) = STATISTIC_OPTIONS.get() else {
94 return;
95 };
96
97 let Ok(mut statistic_options) = statistic_options_lock.write() else {
98 return;
99 };
100
101 let Some(post_fix) = statistic_options.after_statistics else {
102 return;
103 };
104
105 let _ = writeln!(statistic_options.statistics_writer, "{post_fix}");
106}
107
108pub fn should_log_statistics() -> bool {
111 STATISTIC_OPTIONS.get().is_some()
112}