Skip to content

Commit fed1d43

Browse files
committed
Loggable trait and derive macro.
1 parent b0ed2e6 commit fed1d43

14 files changed

Lines changed: 99 additions & 124 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libclide-macros/src/lib.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,17 @@ use proc_macro::TokenStream;
66
use quote::quote;
77
use syn::{ItemStruct, parse_macro_input};
88

9-
#[proc_macro_attribute]
10-
pub fn log_id(_attr: TokenStream, item: TokenStream) -> TokenStream {
9+
#[proc_macro_derive(Loggable)]
10+
pub fn loggable(item: TokenStream) -> TokenStream {
1111
let input = parse_macro_input!(item as ItemStruct);
1212
let struct_name = &input.ident;
1313
let generics = &input.generics;
1414

1515
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
1616
let struct_name_str = struct_name.to_string();
1717
let expanded = quote! {
18-
#input
19-
20-
impl #impl_generics #struct_name #type_generics #where_clause {
21-
#[allow(unused)]
22-
pub const ID: &'static str = #struct_name_str;
18+
impl #impl_generics libclide::log::Loggable for #struct_name #type_generics #where_clause {
19+
const ID: &'static str = #struct_name_str;
2320
}
2421
};
2522

libclide/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ anyhow = { workspace = true }
88
strum = { workspace = true }
99
log = { workspace = true }
1010
devicons = { workspace = true }
11+
libclide-macros = { path = "../libclide-macros" }

libclide/src/log.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
// SPDX-License-Identifier: GNU General Public License v3.0 or later
44

55
pub mod macros;
6+
7+
pub trait Loggable {
8+
const ID: &'static str;
9+
}

libclide/src/log/macros.rs

Lines changed: 15 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,111 +9,67 @@
99
//! explicitly set. This is to avoid implicit pooling of log messages under the same default target,
1010
//! which can make it difficult to filter log messages by their source.
1111
//!
12-
//! The target argument can be overridden using one of the following macros.
13-
//! ```
14-
//! libclide::log!(target: "CustomTarget", "This log message will have the target 'CustomTarget'");
15-
//! ```
16-
//!
17-
//! The target argument will default to Self::ID if not provided.
18-
//! This is an error if Self::ID is not defined, forcing you to use the explicit form.
19-
//! ```
20-
//! libclide::log!("This log message will use target Self::ID, the name of the struct it was invoked in");
12+
//! The Loggable trait can be implemented to automatically associate log messages with a struct.
2113
//! ```
14+
//! use libclide_macros::Loggable;
2215
//!
23-
//! Self::ID can be defined using the `#[log_id]` attribute macro, which will automatically generate
24-
//! a constant ID field with the name of the struct as its value.
25-
//! ```
26-
//! #[log_id]
16+
//! #[derive(Loggable)]
2717
//! struct MyStruct;
2818
//! impl MyStruct {
2919
//! fn my_method(&self) {
30-
//! libclide::log!("This log message will use target Self::ID, which is 'MyStruct'");
20+
//! libclide::info!("This log message will use target <Self as Loggable>::ID, which is 'MyStruct'");
3121
//! }
3222
//! }
3323
//! ```
3424
//!
25+
//! If the struct does not derive or implement Loggable, the target variant of the log macros must
26+
//! be used instead.
27+
//! ```
28+
//! libclide::info!(target: "CustomTarget", "This log message will have the target 'CustomTarget'");
29+
//! ```
30+
//!
3531
3632
#[macro_export]
3733
macro_rules! info {
38-
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
39-
log::info!(logger: $logger, target: $target, $($arg)+)
40-
});
41-
4234
(target: $target:expr, $($arg:tt)+) => ({
4335
log::info!(target: $target, $($arg)+)
4436
});
4537

46-
(logger: $logger:expr, $($arg:tt)+) => ({
47-
log::info!(logger: $logger, target: Self::ID, $($arg)+)
48-
});
49-
50-
($($arg:tt)+) => (log::info!(target: Self::ID, $($arg)+))
38+
($($arg:tt)+) => (log::info!(target: <Self as libclide::log::Loggable>::ID, $($arg)+))
5139
}
5240

5341
#[macro_export]
5442
macro_rules! debug {
55-
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
56-
log::debug!(logger: $logger, target: $target, $($arg)+)
57-
});
58-
5943
(target: $target:expr, $($arg:tt)+) => ({
6044
log::debug!(target: $target, $($arg)+)
6145
});
6246

63-
(logger: $logger:expr, $($arg:tt)+) => ({
64-
log::debug!(logger: $logger, target: Self::ID, $($arg)+)
65-
});
66-
67-
($($arg:tt)+) => (log::debug!(target: Self::ID, $($arg)+))
47+
($($arg:tt)+) => (log::debug!(target: <Self as libclide::log::Loggable>::ID, $($arg)+))
6848
}
6949

7050
#[macro_export]
7151
macro_rules! warn {
72-
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
73-
log::warn!(logger: $logger, target: $target, $($arg)+)
74-
});
75-
7652
(target: $target:expr, $($arg:tt)+) => ({
7753
log::warn!(target: $target, $($arg)+)
7854
});
7955

80-
(logger: $logger:expr, $($arg:tt)+) => ({
81-
log::warn!(logger: $logger, target: Self::ID, $($arg)+)
82-
});
83-
84-
($($arg:tt)+) => (log::warn!(target: Self::ID, $($arg)+))
56+
($($arg:tt)+) => (log::warn!(target: <Self as libclide::log::Loggable>::ID, $($arg)+))
8557
}
8658

8759
#[macro_export]
8860
macro_rules! error {
89-
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
90-
log::error!(logger: $logger, target: $target, $($arg)+)
91-
});
92-
9361
(target: $target:expr, $($arg:tt)+) => ({
9462
log::error!(target: $target, $($arg)+)
9563
});
9664

97-
(logger: $logger:expr, $($arg:tt)+) => ({
98-
log::error!(logger: $logger, target: Self::ID, $($arg)+)
99-
});
100-
101-
($($arg:tt)+) => (log::error!(target: Self::ID, $($arg)+))
65+
($($arg:tt)+) => (log::error!(target: <Self as libclide::log::Loggable>::ID, $($arg)+))
10266
}
10367

10468
#[macro_export]
10569
macro_rules! trace {
106-
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
107-
log::trace!(logger: $logger, target: $target, $($arg)+)
108-
});
109-
11070
(target: $target:expr, $($arg:tt)+) => ({
11171
log::trace!(target: $target, $($arg)+)
11272
});
11373

114-
(logger: $logger:expr, $($arg:tt)+) => ({
115-
log::trace!(logger: $logger, target: Self::ID, $($arg)+)
116-
});
117-
118-
($($arg:tt)+) => (log::trace!(target: Self::ID, $($arg)+))
74+
($($arg:tt)+) => (log::trace!(target: <Self as libclide::log::Loggable>::ID, $($arg)+))
11975
}

src/tui.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod menu_bar;
1313

1414
use crate::AppContext;
1515
use anyhow::{Context, Result};
16-
use libclide_macros::log_id;
16+
use libclide_macros::Loggable;
1717
use log::LevelFilter;
1818
use ratatui::Terminal;
1919
use ratatui::backend::CrosstermBackend;
@@ -29,20 +29,19 @@ use tui_logger::{
2929
TuiLoggerFile, TuiLoggerLevelOutput, init_logger, set_default_level, set_log_file,
3030
};
3131

32-
#[log_id]
32+
#[derive(Loggable)]
3333
struct Tui {
3434
terminal: Terminal<CrosstermBackend<Stdout>>,
3535
root_path: std::path::PathBuf,
3636
}
3737

3838
pub fn run(app_context: AppContext) -> Result<()> {
39-
libclide::trace!(target:Tui::ID, "Starting TUI");
39+
libclide::trace!(target: "clide::tui::run", "Starting TUI");
4040
Tui::new(app_context)?.start()
4141
}
4242

4343
impl Tui {
4444
fn new(app_context: AppContext) -> Result<Self> {
45-
libclide::trace!("Building {}", Self::ID);
4645
init_logger(LevelFilter::Trace)?;
4746
set_default_level(LevelFilter::Trace);
4847
libclide::debug!("Logging initialized");

src/tui/about.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
//
33
// SPDX-License-Identifier: GNU General Public License v3.0 or later
44

5-
use libclide_macros::log_id;
5+
use libclide_macros::Loggable;
66
use ratatui::buffer::Buffer;
77
use ratatui::layout::{Constraint, Direction, Layout, Rect};
88
use ratatui::text::{Line, Span};
99
use ratatui::widgets::{Block, Borders, Clear, Padding, Paragraph, Widget, Wrap};
1010

11-
#[log_id]
11+
#[derive(Loggable)]
1212
pub struct About {}
1313

1414
impl About {

src/tui/app.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use crate::tui::explorer::Explorer;
99
use crate::tui::logger::Logger;
1010
use crate::tui::menu_bar::MenuBar;
1111
use anyhow::{Context, Result};
12-
use libclide_macros::log_id;
12+
use libclide::log::Loggable;
13+
use libclide_macros::Loggable;
1314
use ratatui::DefaultTerminal;
1415
use ratatui::buffer::Buffer;
1516
use ratatui::crossterm::event;
@@ -30,7 +31,7 @@ pub enum AppComponent {
3031
MenuBar,
3132
}
3233

33-
#[log_id]
34+
#[derive(Loggable)]
3435
pub struct App<'a> {
3536
editor_tab: EditorTab,
3637
explorer: Explorer<'a>,
@@ -42,7 +43,7 @@ pub struct App<'a> {
4243

4344
impl<'a> App<'a> {
4445
pub fn new(root_path: PathBuf) -> Result<Self> {
45-
libclide::trace!(target:Self::ID, "Building {}", Self::ID);
46+
libclide::trace!("Building {}", <Self as Loggable>::ID);
4647
let app = Self {
4748
editor_tab: EditorTab::new(),
4849
explorer: Explorer::new(&root_path)?,
@@ -56,13 +57,13 @@ impl<'a> App<'a> {
5657

5758
/// Logic that should be executed once on application startup.
5859
pub fn start(&mut self) -> Result<()> {
59-
libclide::trace!(target:Self::ID, "Starting App");
60+
libclide::trace!("Starting App");
6061
Ok(())
6162
}
6263

6364
pub fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
6465
self.start()?;
65-
libclide::trace!(target:Self::ID, "Entering App run loop");
66+
libclide::trace!("Entering App run loop");
6667
loop {
6768
terminal.draw(|f| {
6869
f.render_widget(&mut self, f.area());
@@ -88,7 +89,7 @@ impl<'a> App<'a> {
8889
Some(editor) => editor.component_state.help_text.clone(),
8990
None => {
9091
if !self.editor_tab.is_empty() {
91-
libclide::error!(target:Self::ID, "Failed to get Editor while drawing bottom status bar");
92+
libclide::error!("Failed to get Editor while drawing bottom status bar");
9293
}
9394
"Failed to get current Editor while getting widget help text".to_string()
9495
}
@@ -112,26 +113,26 @@ impl<'a> App<'a> {
112113
}
113114

114115
fn clear_focus(&mut self) {
115-
libclide::info!(target:Self::ID, "Clearing all widget focus");
116+
libclide::info!("Clearing all widget focus");
116117
self.explorer.component_state.set_focus(Focus::Inactive);
117118
self.explorer.component_state.set_focus(Focus::Inactive);
118119
self.logger.component_state.set_focus(Focus::Inactive);
119120
self.menu_bar.component_state.set_focus(Focus::Inactive);
120121
match self.editor_tab.current_editor_mut() {
121122
None => {
122-
libclide::error!(target:Self::ID, "Failed to get current Editor while clearing focus")
123+
libclide::error!("Failed to get current Editor while clearing focus")
123124
}
124125
Some(editor) => editor.component_state.set_focus(Focus::Inactive),
125126
}
126127
}
127128

128129
fn change_focus(&mut self, focus: AppComponent) {
129-
libclide::info!(target:Self::ID, "Changing widget focus to {:?}", focus);
130+
libclide::info!("Changing widget focus to {:?}", focus);
130131
self.clear_focus();
131132
match focus {
132133
AppComponent::Editor => match self.editor_tab.current_editor_mut() {
133134
None => {
134-
libclide::error!(target:Self::ID, "Failed to get current Editor while changing focus")
135+
libclide::error!("Failed to get current Editor while changing focus")
135136
}
136137
Some(editor) => editor.component_state.set_focus(Focus::Active),
137138
},
@@ -274,13 +275,15 @@ impl<'a> Component for App<'a> {
274275
Action::Quit | Action::Handled => Ok(action),
275276
Action::Save => match self.editor_tab.current_editor_mut() {
276277
None => {
277-
libclide::error!(target:Self::ID, "Failed to get current editor while handling App Action::Save");
278+
libclide::error!(
279+
"Failed to get current editor while handling App Action::Save"
280+
);
278281
Ok(Action::Noop)
279282
}
280283
Some(editor) => match editor.save() {
281284
Ok(_) => Ok(Action::Handled),
282285
Err(e) => {
283-
libclide::error!(target:Self::ID, "Failed to save editor contents: {e}");
286+
libclide::error!("Failed to save editor contents: {e}");
284287
Ok(Action::Noop)
285288
}
286289
},
@@ -299,14 +302,16 @@ impl<'a> Component for App<'a> {
299302
Err(_) => Ok(Action::Noop),
300303
},
301304
Action::ReloadFile => {
302-
libclide::trace!(target:Self::ID, "Reloading file for current editor");
305+
libclide::trace!("Reloading file for current editor");
303306
if let Some(editor) = self.editor_tab.current_editor_mut() {
304307
editor
305308
.reload_contents()
306309
.map(|_| Action::Handled)
307310
.context("Failed to handle Action::ReloadFile")
308311
} else {
309-
libclide::error!(target:Self::ID, "Failed to get current editor while handling App Action::ReloadFile");
312+
libclide::error!(
313+
"Failed to get current editor while handling App Action::ReloadFile"
314+
);
310315
Ok(Action::Noop)
311316
}
312317
}

src/tui/component.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::tui::component::Focus::Inactive;
88
use Focus::Active;
99
use anyhow::Result;
1010
use libclide::theme::colors::Colors;
11-
use libclide_macros::log_id;
11+
use libclide_macros::Loggable;
1212
use ratatui::crossterm::event::{Event, KeyEvent, MouseEvent};
1313
use ratatui::style::Color;
1414

@@ -62,8 +62,7 @@ pub trait Component {
6262
}
6363
}
6464

65-
#[derive(Debug, Clone, Default)]
66-
#[log_id]
65+
#[derive(Debug, Clone, Default, Loggable)]
6766
pub struct ComponentState {
6867
pub(crate) focus: Focus,
6968
pub(crate) vis: Visibility,

0 commit comments

Comments
 (0)