Skip to main content

reovim_kernel/printk/
level.rs

1//! Log level definitions for kernel messages.
2//!
3//! Linux equivalent: `KERN_*` constants in `include/linux/kern_levels.h`
4//!
5//! This module defines the severity levels for kernel log messages,
6//! ordered from most severe (Error) to most verbose (Trace).
7
8use std::{fmt, str::FromStr};
9
10/// Log level for kernel messages.
11///
12/// Levels are ordered by severity, with `Error` being the most severe
13/// and `Trace` being the most verbose. This ordering allows filtering:
14/// if a logger is configured for `Info` level, it will log `Error`,
15/// `Warn`, and `Info` messages, but not `Debug` or `Trace`.
16///
17/// # Linux Equivalent
18///
19/// | Level | Linux Constant | Usage |
20/// |-------|----------------|-------|
21/// | Error | `KERN_ERR` | Critical errors requiring immediate attention |
22/// | Warn | `KERN_WARNING` | Warning conditions |
23/// | Info | `KERN_INFO` | Informational messages |
24/// | Debug | `KERN_DEBUG` | Debug-level messages |
25/// | Trace | (custom) | Most verbose tracing |
26///
27/// # Example
28///
29/// ```
30/// use reovim_kernel::api::v1::*;
31/// use std::str::FromStr;
32///
33/// let level = Level::Info;
34/// assert!(level <= Level::Debug);  // Info is less verbose than Debug
35/// assert!(level >= Level::Error);  // Info is more verbose than Error
36///
37/// // Convert to/from string
38/// assert_eq!(Level::Error.as_str(), "ERROR");
39/// assert_eq!(Level::from_str("warn"), Ok(Level::Warn));
40/// ```
41#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
42#[repr(u8)]
43pub enum Level {
44    /// Critical errors requiring immediate attention.
45    ///
46    /// Use for conditions that prevent normal operation.
47    /// Linux equivalent: `KERN_ERR`
48    Error = 0,
49
50    /// Warning conditions.
51    ///
52    /// Use for potentially harmful situations that don't prevent operation.
53    /// Linux equivalent: `KERN_WARNING`
54    Warn = 1,
55
56    /// Informational messages.
57    ///
58    /// Use for general operational messages.
59    /// Linux equivalent: `KERN_INFO`
60    #[default]
61    Info = 2,
62
63    /// Debug-level messages.
64    ///
65    /// Use for detailed diagnostic information during development.
66    /// Linux equivalent: `KERN_DEBUG`
67    Debug = 3,
68
69    /// Trace-level messages.
70    ///
71    /// Most verbose level, for detailed tracing of execution flow.
72    Trace = 4,
73}
74
75impl Level {
76    /// All log levels in order of severity.
77    pub const ALL: [Self; 5] = [
78        Self::Error,
79        Self::Warn,
80        Self::Info,
81        Self::Debug,
82        Self::Trace,
83    ];
84
85    /// Returns the string representation of this level.
86    ///
87    /// # Example
88    ///
89    /// ```
90    /// use reovim_kernel::api::v1::*;
91    ///
92    /// assert_eq!(Level::Error.as_str(), "ERROR");
93    /// assert_eq!(Level::Warn.as_str(), "WARN");
94    /// assert_eq!(Level::Info.as_str(), "INFO");
95    /// assert_eq!(Level::Debug.as_str(), "DEBUG");
96    /// assert_eq!(Level::Trace.as_str(), "TRACE");
97    /// ```
98    #[must_use]
99    pub const fn as_str(&self) -> &'static str {
100        match self {
101            Self::Error => "ERROR",
102            Self::Warn => "WARN",
103            Self::Info => "INFO",
104            Self::Debug => "DEBUG",
105            Self::Trace => "TRACE",
106        }
107    }
108
109    /// Check if this level is at least as severe as the given level.
110    ///
111    /// # Example
112    ///
113    /// ```
114    /// use reovim_kernel::api::v1::*;
115    ///
116    /// assert!(Level::Error.is_at_least(Level::Info));   // Error is more severe
117    /// assert!(Level::Info.is_at_least(Level::Info));    // Same level
118    /// assert!(!Level::Debug.is_at_least(Level::Info));  // Debug is less severe
119    /// ```
120    #[must_use]
121    pub const fn is_at_least(&self, other: Self) -> bool {
122        (*self as u8) <= (other as u8)
123    }
124}
125
126/// Error returned when parsing a level from a string fails.
127#[derive(Debug, Clone, Copy, PartialEq, Eq)]
128pub struct ParseLevelError;
129
130impl fmt::Display for ParseLevelError {
131    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132        write!(f, "unknown log level")
133    }
134}
135
136impl std::error::Error for ParseLevelError {}
137
138impl FromStr for Level {
139    type Err = ParseLevelError;
140
141    /// Parses a level from a string (case-insensitive).
142    ///
143    /// # Example
144    ///
145    /// ```
146    /// use reovim_kernel::api::v1::*;
147    /// use std::str::FromStr;
148    ///
149    /// assert_eq!(Level::from_str("error"), Ok(Level::Error));
150    /// assert_eq!(Level::from_str("WARN"), Ok(Level::Warn));
151    /// assert_eq!(Level::from_str("Info"), Ok(Level::Info));
152    /// assert!(Level::from_str("unknown").is_err());
153    /// ```
154    fn from_str(s: &str) -> Result<Self, Self::Err> {
155        match s.to_ascii_lowercase().as_str() {
156            "error" | "err" => Ok(Self::Error),
157            "warn" | "warning" => Ok(Self::Warn),
158            "info" => Ok(Self::Info),
159            "debug" => Ok(Self::Debug),
160            "trace" => Ok(Self::Trace),
161            _ => Err(ParseLevelError),
162        }
163    }
164}
165
166impl fmt::Display for Level {
167    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168        f.write_str(self.as_str())
169    }
170}