Documentation

Sure, here's the README for nekoprint in English, ready for you to copy and paste.


nekoprint

Crates.io Docs.rs License GitHub top language GitHub stars GitHub forks Tests Crates.io downloads GitHub last commit

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 String).

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(),
        },
    };

    // Print the `id` field with different log levels
    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;

    // Print the `name` field with different log levels
    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;

    // Print the entire struct with different log levels
    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;
}