Skip to main content

reovim_kernel/printk/
record.rs

1//! Log record containing message and metadata.
2//!
3//! Linux equivalent: `struct printk_log` in `kernel/printk/printk_ringbuffer.h`
4//!
5//! A `Record` contains all the information about a single log entry:
6//! the log level, message, and source location metadata.
7
8use super::level::Level;
9
10/// A log record containing message and source location metadata.
11///
12/// This struct is lifetime-bound to the message string to avoid
13/// allocations during logging. The source location fields (`module_path`,
14/// `file`, `line`) are captured at the call site using compiler intrinsics.
15///
16/// # Example
17///
18/// ```
19/// use reovim_kernel::api::v1::*;
20///
21/// let record = Record::builder(Level::Info)
22///     .message("buffer opened")
23///     .module_path("reovim_kernel::mm")
24///     .file("buffer.rs")
25///     .line(42)
26///     .build();
27///
28/// assert_eq!(record.level(), Level::Info);
29/// assert_eq!(record.message(), "buffer opened");
30/// assert_eq!(record.line(), 42);
31/// ```
32#[derive(Debug, Clone)]
33pub struct Record<'a> {
34    level: Level,
35    message: &'a str,
36    module_path: &'static str,
37    file: &'static str,
38    line: u32,
39}
40
41impl<'a> Record<'a> {
42    /// Creates a new record builder with the given level.
43    ///
44    /// # Example
45    ///
46    /// ```
47    /// use reovim_kernel::api::v1::*;
48    ///
49    /// let record = Record::builder(Level::Error)
50    ///     .message("something went wrong")
51    ///     .build();
52    /// ```
53    #[must_use]
54    pub const fn builder(level: Level) -> RecordBuilder<'a> {
55        RecordBuilder::new(level)
56    }
57
58    /// Returns the log level.
59    #[must_use]
60    pub const fn level(&self) -> Level {
61        self.level
62    }
63
64    /// Returns the log message.
65    #[must_use]
66    pub const fn message(&self) -> &str {
67        self.message
68    }
69
70    /// Returns the module path where the log was emitted.
71    #[must_use]
72    pub const fn module_path(&self) -> &'static str {
73        self.module_path
74    }
75
76    /// Returns the file where the log was emitted.
77    #[must_use]
78    pub const fn file(&self) -> &'static str {
79        self.file
80    }
81
82    /// Returns the line number where the log was emitted.
83    #[must_use]
84    pub const fn line(&self) -> u32 {
85        self.line
86    }
87}
88
89/// Builder for constructing log records.
90///
91/// Use [`Record::builder`] to create an instance.
92///
93/// # Example
94///
95/// ```
96/// use reovim_kernel::api::v1::*;
97///
98/// let record = Record::builder(Level::Debug)
99///     .message("entering function")
100///     .module_path("reovim_kernel::core")
101///     .file("motion.rs")
102///     .line(100)
103///     .build();
104/// ```
105#[derive(Debug)]
106pub struct RecordBuilder<'a> {
107    level: Level,
108    message: &'a str,
109    module_path: &'static str,
110    file: &'static str,
111    line: u32,
112}
113
114impl<'a> RecordBuilder<'a> {
115    /// Creates a new builder with the given level.
116    #[must_use]
117    const fn new(level: Level) -> Self {
118        Self {
119            level,
120            message: "",
121            module_path: "",
122            file: "",
123            line: 0,
124        }
125    }
126
127    /// Sets the log message.
128    #[must_use]
129    pub const fn message(mut self, message: &'a str) -> Self {
130        self.message = message;
131        self
132    }
133
134    /// Sets the module path.
135    #[must_use]
136    pub const fn module_path(mut self, module_path: &'static str) -> Self {
137        self.module_path = module_path;
138        self
139    }
140
141    /// Sets the file name.
142    #[must_use]
143    pub const fn file(mut self, file: &'static str) -> Self {
144        self.file = file;
145        self
146    }
147
148    /// Sets the line number.
149    #[must_use]
150    pub const fn line(mut self, line: u32) -> Self {
151        self.line = line;
152        self
153    }
154
155    /// Builds the record.
156    #[must_use]
157    pub const fn build(self) -> Record<'a> {
158        Record {
159            level: self.level,
160            message: self.message,
161            module_path: self.module_path,
162            file: self.file,
163            line: self.line,
164        }
165    }
166}