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}