pumpkin_solver/statistics/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Contains structures related to the statistic logging of the [`Solver`]
pub(crate) mod statistic_logger;
pub(crate) mod statistic_logging;

use std::fmt::Display;
use std::fmt::Write;

pub use statistic_logger::StatisticLogger;
pub use statistic_logging::configure_statistic_logging;
pub use statistic_logging::log_statistic;
pub use statistic_logging::log_statistic_postfix;
pub use statistic_logging::should_log_statistics;
pub use statistic_logging::StatisticOptions;

#[cfg(doc)]
use crate::create_statistics_struct;
#[cfg(doc)]
use crate::Solver;

/// A simple trait for defining a loggable statistic.
///
/// See [`create_statistics_struct`] for creating a statistic struct automatically!
pub trait Statistic {
    /// Logs the [`Statistic`] using the provided [`StatisticLogger`].
    fn log(&self, statistic_logger: StatisticLogger);
}

impl<Value: Display> Statistic for Value {
    fn log(&self, mut statistic_logger: StatisticLogger) {
        write!(statistic_logger, "{self}").expect("Expected statistic to be logged");
    }
}

/// A macro for generating a struct for storing statistics.
///
/// # Example
/// ```rust
/// # use pumpkin_solver::create_statistics_struct;
/// create_statistics_struct!(Statistics {
///     number_of_calls: usize
/// });
///
/// let statistics = Statistics::default();
///
/// assert_eq!(statistics.number_of_calls, 0);
/// ```
#[macro_export]
macro_rules! create_statistics_struct {
    ($(#[$struct_documentation:meta])* $name:ident { $($(#[$variable_documentation:meta])* $field:ident : $type:ident),+ $(,)? }) => {
        $(#[$struct_documentation])*
        #[derive(Default, Debug, Copy, Clone)]
        pub(crate) struct $name {
            $($(#[$variable_documentation])* pub(crate) $field: $type),+
        }

        impl $crate::statistics::Statistic for $name {
            fn log(&self, statistic_logger: $crate::statistics::StatisticLogger) {
                $(self.$field.log(statistic_logger.attach_to_prefix(stringify!($field),)));+
            }
        }
    };
}