Skip to main content

pixelflow_core/
log.rs

1//! Logging hook abstractions for libraries, CLI, and plugins.
2
3use std::sync::Arc;
4
5/// Severity for records emitted through PixelFlow logging hooks.
6#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
7pub enum LogLevel {
8    /// Detailed diagnostic event for troubleshooting.
9    Trace,
10    /// Developer-focused diagnostic event.
11    Debug,
12    /// Informational event for normal operation.
13    Info,
14    /// Recoverable problem or degraded behavior.
15    Warn,
16    /// Operation failed and returned an error.
17    Error,
18}
19
20/// Immutable log event delivered to a [`LogSink`].
21#[derive(Clone, Debug, Eq, PartialEq)]
22pub struct LogRecord {
23    level: LogLevel,
24    target: String,
25    message: String,
26}
27
28impl LogRecord {
29    /// Creates a log record for a target and message.
30    #[must_use]
31    pub fn new(level: LogLevel, target: impl Into<String>, message: impl Into<String>) -> Self {
32        Self {
33            level,
34            target: target.into(),
35            message: message.into(),
36        }
37    }
38
39    /// Returns record severity.
40    #[must_use]
41    pub const fn level(&self) -> LogLevel {
42        self.level
43    }
44
45    /// Returns module or subsystem target.
46    #[must_use]
47    pub fn target(&self) -> &str {
48        &self.target
49    }
50
51    /// Returns human-readable log message.
52    #[must_use]
53    pub fn message(&self) -> &str {
54        &self.message
55    }
56}
57
58/// Destination for PixelFlow log records.
59pub trait LogSink: Send + Sync {
60    /// Handles one immutable log record.
61    fn log(&self, record: &LogRecord);
62}
63
64/// Log sink that discards all records.
65#[derive(Debug, Default)]
66pub struct NoopLogSink;
67
68impl LogSink for NoopLogSink {
69    fn log(&self, _record: &LogRecord) {}
70}
71
72/// Cloneable logger handle used by core and downstream crates.
73#[derive(Clone)]
74pub struct Logger {
75    sink: Arc<dyn LogSink>,
76}
77
78impl Logger {
79    /// Creates a logger from a shared sink.
80    #[must_use]
81    pub fn new(sink: Arc<dyn LogSink>) -> Self {
82        Self { sink }
83    }
84
85    /// Emits one log record to the configured sink.
86    pub fn emit(&self, record: &LogRecord) {
87        self.sink.log(record);
88    }
89
90    /// Creates and emits one log record.
91    pub fn log(&self, level: LogLevel, target: impl Into<String>, message: impl Into<String>) {
92        self.emit(&LogRecord::new(level, target, message));
93    }
94}
95
96impl Default for Logger {
97    fn default() -> Self {
98        Self::new(Arc::new(NoopLogSink))
99    }
100}