turul_mcp_builders/traits/
logging_traits.rs

1//! Framework traits for MCP logging construction
2//!
3//! **IMPORTANT**: These are framework features, NOT part of the MCP specification.
4
5use turul_mcp_protocol::logging::{LoggingLevel, LoggingMessageNotification, SetLevelRequest};
6use serde_json::Value;
7
8/// Trait for logging metadata (method, logger name)
9pub trait HasLoggingMetadata {
10    /// The logging method name
11    fn method(&self) -> &str;
12
13    /// Optional logger name/identifier
14    fn logger_name(&self) -> Option<&str> {
15        None
16    }
17}
18
19/// Trait for logging level configuration
20pub trait HasLogLevel {
21    /// The current or target logging level
22    fn level(&self) -> LoggingLevel;
23
24    /// Check if a message at the given level should be logged
25    fn should_log(&self, message_level: LoggingLevel) -> bool {
26        message_level.should_log(self.level())
27    }
28}
29
30/// Trait for log message formatting and data
31pub trait HasLogFormat {
32    /// Get the log data
33    fn data(&self) -> &Value;
34
35    /// Format the log message for output
36    fn format_message(&self) -> String {
37        // Default: try to format as string, fallback to JSON
38        match self.data() {
39            Value::String(s) => s.clone(),
40            other => {
41                serde_json::to_string(other).unwrap_or_else(|_| "<invalid log data>".to_string())
42            }
43        }
44    }
45}
46
47/// Trait for logging transport and delivery
48pub trait HasLogTransport {
49    /// Optional filtering criteria
50    fn should_deliver(&self, _level: LoggingLevel) -> bool {
51        true
52    }
53
54    /// Optional batching configuration
55    fn batch_size(&self) -> Option<usize> {
56        None
57    }
58}
59
60/// Complete MCP Logger Definition trait
61///
62/// This trait represents a complete, working MCP logger.
63/// When you implement the required traits, you automatically get
64/// `LoggerDefinition` for free via blanket implementation.
65pub trait LoggerDefinition:
66    HasLoggingMetadata + HasLogLevel + HasLogFormat + HasLogTransport
67{
68    /// Convert this logger definition to a LoggingMessageNotification
69    fn to_message_notification(&self) -> LoggingMessageNotification {
70        let mut notification = LoggingMessageNotification::new(self.level(), self.data().clone());
71        if let Some(logger) = self.logger_name() {
72            notification = notification.with_logger(logger);
73        }
74        notification
75    }
76
77    /// Convert this logger definition to a SetLevelRequest
78    fn to_set_level_request(&self) -> SetLevelRequest {
79        SetLevelRequest::new(self.level())
80    }
81}
82
83// Blanket implementation: any type implementing the fine-grained traits automatically gets LoggerDefinition
84impl<T> LoggerDefinition for T where
85    T: HasLoggingMetadata + HasLogLevel + HasLogFormat + HasLogTransport
86{
87}