nekoprint

nekoprint is a powerful procedural macro for Rust that automatically generates printing methods for a struct's fields and the entire struct itself. It lets you create fluid, asynchronous logs with different severity levels using a simple, chained syntax.
This library is ideal for debugging, monitoring, and diagnostics in Rust applications, especially those using async/await.
✨ Features
- Automatic Generation: Creates methods like
print_field() and print() for every decorated struct.
- Customizable Transporters: Define your own message transport logic using the
#[transporter] attribute.
- Integrated Log Levels: Built-in support for the following fluid log levels:
.err()
.info()
.success()
.warning()
.critical()
.panic()
.rust() (useful for standard debug logs)
- Personalized Messages: Add specific log messages to each call with the
.message() method.
async/await Compatible: Fully integrated with the tokio ecosystem.
⚙️ Installation
Add nekoprint to your Cargo.toml:
cargo add nekoprint
Make sure the nekoprint macro is in scope.
🚀 Usage
Defining Your Struct
Decorate your struct with #[derive(NekoPrint)] and use the #[transporter] attribute to define how the log message will be processed. The transporter is an async function that takes a message variable (a CString).
use nekoprint::NekoPrint;
#[derive(Debug, NekoPrint, Default, Clone)]
#[transporter(async fn procedure() {
println!("{message}");
let m = message.to_string();
assert!(
m.contains("message")
);
})]
pub struct User {
id: i32,
name: String,
friend: Friend,
}
#[derive(Debug, NekoPrint, Default, Clone)]
#[transporter(async fn procedure() {
println!("{message}");
let m = message.to_string();
assert!(
m.contains("message")
);
})]
pub struct Friend {
id: i32,
name: String,
}
Full Usage Example
The NekoPrint macro generates methods like print_id(), print_name(), and print() for the User and Friend structs. You can then chain the .message() and .level() methods to customize the output.
#[tokio::test]
async fn test_print_user() {
let user = User {
id: 1,
name: "name".into(),
friend: Friend {
id: 1,
name: "name".into(),
},
};
user.print_id().message("custom message for id").err().await;
user.print_id().message("info id message").info().await;
user.print_id().message("success id message").success().await;
user.print_id().message("warning id message").warning().await;
user.print_id().message("critical id message").critical().await;
user.print_id().message("panic id message").panic().await;
user.print_id().message("rust debug id message").rust().await;
user.print_name().message("custom message for name").err().await;
user.print_name().message("info name message").info().await;
user.print_name().message("success name message").success().await;
user.print_name().message("warning name message").warning().await;
user.print_name().message("critical name message").critical().await;
user.print_name().message("panic name message").panic().await;
user.print_name().message("rust debug name message").rust().await;
user.print().message("custom message for all").err().await;
user.print().message("custom message for all").info().await;
user.print().message("custom message for all").success().await;
user.print().message("custom message for all").warning().await;
user.print().message("custom message for all").panic().await;
user.print().message("custom message for all").critical().await;
user.print().message("custom message for all").rust().await;
}