`Debug` in rust, but only supports valid rust syntax and outputs nicely formatted using pretty-please

Overview

dbg-pls

A Debug-like trait for rust that outputs properly formatted code

Showcase

Take the following code:

let code = r#"
    [
        "Hello, World! I am a long string",
        420,
        "Wait, you can't mix and match types in arrays, is this python?",
        69,
        "Nice."
    ]
"#;
let expr: syn::Expr = syn::parse_str(code).unwrap();
println!("{expr:?}");

This outputs

Array(ExprArray { attrs: [], bracket_token: Bracket, elems: [Lit(ExprLit { attrs: [], lit: Str(LitStr { token: "Hello, World! I am a long string" }) }), Comma, Lit(ExprLit { attrs: [], lit: Int(LitInt { token: 420 }) }), Comma, Lit(ExprLit { attrs: [], lit: Str(LitStr { token: "Wait, you can't mix and match types in arrays, is this python?" }) }), Comma, Lit(ExprLit { attrs: [], lit: Int(LitInt { token: 69 }) }), Comma, Lit(ExprLit { attrs: [], lit: Str(LitStr { token: "Nice." }) })] })

which is far too dense to read.

If we change the println to use the alternate printing (:#?), then we get

Array(
    ExprArray {
        attrs: [],
        bracket_token: Bracket,
        elems: [
            Lit(
                ExprLit {
                    attrs: [],
                    lit: Str(
                        LitStr {
                            token: "Hello, World! I am a long string",
                        },
                    ),
                },
            ),
            Comma,
            Lit(
                ExprLit {
                    attrs: [],
                    lit: Int(
                        LitInt {
                            token: 420,
                        },
                    ),
                },
            ),
            Comma,
            Lit(
                ExprLit {
                    attrs: [],
                    lit: Str(
                        LitStr {
                            token: "Wait, you can't mix and match types in arrays, is this python?",
                        },
                    ),
                },
            ),
            Comma,
            Lit(
                ExprLit {
                    attrs: [],
                    lit: Int(
                        LitInt {
                            token: 69,
                        },
                    ),
                },
            ),
            Comma,
            Lit(
                ExprLit {
                    attrs: [],
                    lit: Str(
                        LitStr {
                            token: "Nice.",
                        },
                    ),
                },
            ),
        ],
    },
)

which is far too spread out to be natural.

This is where dbg_pls comes in. Replace the println with

println!("{}", dbg_pls::color(&expr));

And you get

Usage in libraries

Add to your Cargo.toml

dbg-pls = "*"

Add to your types

#[derive(dbg_pls::DebugPls)]

Usage for applications

Add to your Cargo.toml

dbg-pls = { version = "0.1", features = ["pretty"] }

And print using pretty, eg

println!("{}", dbg_pls::pretty(&value));

Features

  • derive - enables the #[derive(DebugPls)] derive
  • pretty - enables the pretty function for pretty printing
  • colors - enables the color function for syntax highlighted printing

Example

use dbg_pls::{pretty, DebugPls};

#[derive(DebugPls, Copy, Clone)]
pub struct Demo {
    foo: i32,
    bar: &'static str,
}

let mut val = [Demo { foo: 5, bar: "hello" }; 10];
val[6].bar = "Hello, world! I am a very long string";

println!("{}", pretty(&val));

Outputs

[
    Demo { foo: 5, bar: "hello" },
    Demo { foo: 5, bar: "hello" },
    Demo { foo: 5, bar: "hello" },
    Demo { foo: 5, bar: "hello" },
    Demo { foo: 5, bar: "hello" },
    Demo { foo: 5, bar: "hello" },
    Demo {
        foo: 5,
        bar: "Hello, world! I am a very long string",
    },
    Demo { foo: 5, bar: "hello" },
    Demo { foo: 5, bar: "hello" },
    Demo { foo: 5, bar: "hello" },
]

Example (highlighting)

use dbg_pls::{color, DebugPls};

#[derive(DebugPls, Copy, Clone)]
pub struct Demo {
    foo: i32,
    bar: &'static str,
}

let mut val = [Demo { foo: 5, bar: "hello" }; 10];
val[6].bar = "Hello, world! I am a very long string";

println!("{}", color(&val));

Outputs:

Example (dbg-style macros)

use dbg_pls::{color, DebugPls};

#[derive(DebugPls, Copy, Clone)]
pub struct Demo {
    foo: i32,
    bar: &'static str,
}

let foo = 5;
let bar = "hello";
let _ = color!(Demo { foo, bar });

Outputs:

use dbg_pls::{pretty, DebugPls};

#[derive(DebugPls, Copy, Clone)]
pub struct Demo {
    foo: i32,
    bar: &'static str,
}

let foo = 5;
let bar = "hello";
let _ = pretty!(Demo { foo, bar });

Outputs:

[src/lib.rs:558] Demo { foo, bar } => Demo {
    foo: 5,
    bar: "Hello, World! This is the color macro",
}
You might also like...
Analogous, indented syntax for the Rust programming language.

Note: After experimenting with this in the wild, I have found representing keywords as symbols to be far less readable in large codebases. Additionall

A syntax exploration of eventually stable Rust Iterator items

Rust Iterator Items: a syntax exploration This crate is a thin wrapper around the unstable generator feature, allowing users to create new items that

This crate converts Rust compatible regex-syntax to Vim's NFA engine compatible regex.

This crate converts Rust compatible regex-syntax to Vim's NFA engine compatible regex.

Rust macro to use a match-like syntax as a elegant alternative to nesting if-else statement

cond Rust macro to use a match-like syntax as an elegant alternative to many if-else statements. I got the idea from empty Go switch statements. I tho

tr-lang is a language that aims to bring programming language syntax closer to Turkish.

tr-lang Made with ❤️ in 🇹🇷 tr-lang is a language that aims to bring programming language syntax closer to Turkish. tr-lang is a stack based language

kindly is a simple Rust implementation of a set-user-ID-root program, similar to sudo but in a much reduced way.

kindly is a simple Rust implementation of a set-user-ID-root program, similar to sudo but in a much reduced way.

Quinine is a Rust library that implements atomic, lock-free, but write-once versions of containers like `Box` or `Arc`

Quinine is a Rust library that implements atomic, lock-free, but write-once versions of containers like `Box` or `Arc`

Fetch all your fetches, but in rust
Fetch all your fetches, but in rust

fetchfetch, but in rust Fetch all of your fetches. written in go rust. Installation You can either download the latest release or build from source (r

Do the RWKV thing, but now in Rust with GGML

RWKV, but in Rust with ggml A project which reimplementation llama.cpp in rustformers/llm style. Current situation Performance issue: current version

Comments
  • Cannot derive `DebugPls` for uninhabited enum

    Cannot derive `DebugPls` for uninhabited enum

    I tried the code:

    #[derive(Debug, DebugPls)]
    pub enum DirectDeclarator {}
    

    The error:

    error[E0004]: non-exhaustive patterns: type `&DirectDeclarator` is non-empty
      --> parser/src/ast.rs:51:17
       |
    51 | #[derive(Debug, DebugPls)]
       |                 ^^^^^^^^
       |
    note: `DirectDeclarator` defined here
      --> parser/src/ast.rs:52:10
       |
    52 | pub enum DirectDeclarator {}
       |          ^^^^^^^^^^^^^^^^
       = note: the matched value is of type `&DirectDeclarator`
       = note: references are always considered inhabited
       = note: this error originates in the derive macro `DebugPls` (in Nightly builds, run with -Z macro-backtrace for more info)
    help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
       |
    51 ~ #[derive(Debug, DebugPls {
    52 +     _ => todo!(),
    53 ~ })]
    

    The std::fmt::Debug derive works fine with it.

    opened by Nilstrieb 6
  • Derive triggers clippy lint

    Derive triggers clippy lint

    #[derive(dbg_pls::DebugPls)]
    pub struct Foo;
    
    fn main() {
        println!("Hello, world!");
    }
    
    warning: unnecessary structure name repetition
     --> src\main.rs:2:12
      |
    2 | pub struct Foo;
      |            ^^^ help: use the applicable keyword: `Self`
      |
      = note: `-W clippy::use-self` implied by `-W clippy::nursery`
      = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#use_self
    

    No such warning is generated for any derived traits in std. This lint is still being fostered in the nursery, but I say it's better to nip these things in the bud 🐱. I'll take an educated guess that this lint might be triggering because the expanded code is missing an #[automatically_derived] attribute.

    opened by OliveIsAWord 0
  • [feature] add custom syn highlight theme from .tmTheme file

    [feature] add custom syn highlight theme from .tmTheme file

    here's a simple example of what I would like, look in the comments

    use dbg_pls::{pretty, DebugPls, color};  
      
    #[derive(DebugPls, Copy, Clone, Debug)]  
    pub struct Demo {  
        foo: i32,  
        bar: &'static str,  
    }  
      
    fn main() {  
        let mut val = [Demo { foo: 5, bar: "hello" }; 10];  
        val[6].bar = "Hello, world! I am a very long string";  
        
    	// to specify a theme file as parameter
    	let output = format!("{}", color(&val, "path/to/tmTheme"));  
    	println!("{}", output);  
    	
    	color!(&val, "path/to/tmTheme");  
    	
    	// and to have a builder pattern to cache the theme load
    	// the API doesnt need to be like that, you decide
    	let colorizer = Colorizer::new().theme("path/to/tmTheme").build();
    	// just pass the object as ref
    	let colored_string_repr = colorizer.color(&val);
    	// just like color! macro
    	colorizer.dbg(&val);	
    	// this will print module and line information just like dbg!
    }
    

    thats all, in short

    i just want to be able to load a custom theme.

    opened by alexzanderr 0
Owner
Conrad Ludgate
Conrad Ludgate
A dynamic output configuration tool that automatically detects and configures connected outputs based on a set of profiles.

shikane A dynamic output configuration tool that automatically detects and configures connected outputs based on a set of profiles. Each profile speci

Hendrik Wolff 15 May 4, 2023
`grep` but with PEG patterns. Define grammars (e.g. `digit`), functions for matching. No more regex syntax!

PEG peggrep Example file demo_file: THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE. this line is the 1st lower case line in this file. This Line Ha

IchHabeKeineNamen 3 Apr 18, 2023
Achieve it! How you ask? Well, it's pretty simple; just use greatness!

Greatness! Achieve it! How you ask? Well, it's pretty simple; just use greatness! Disclaimer I do not believe that greatness is the best. It fits a me

Isacc Barker (Milo Banks) 107 Sep 28, 2022
Kalker (or "kalk") is a calculator program/website that supports user-defined variables, functions, derivation, and integration

Kalker (or "kalk") is a calculator program/website that supports user-defined variables, functions, derivation, and integration. It runs on Windows, macOS, Linux, Android, and in web browsers (with WebAssembly).

null 1.2k Dec 27, 2022
A Simple, But amazing telegram bot, Made using the Rust language!

Telegram bot in Rust A fun Telegram bot made using Rust language.

Deep Alchemy 2 Dec 21, 2021
A simple and fast FRC autonomous path planner (designed for swerve drive)! (Desktop/Laptop only)

This is a website developed for planning autonomous paths for FRC robots. It is intended to be a simple and fast tool to create autos, which works offline at competitions.

Weaver Goldman 2 Jan 6, 2023
Try to find the correct word with only first letter and unknown letter count

Try to find the correct word with only first letter and unknown letter count

Alexandre 6 Apr 11, 2022
Shows only the first page of rustc output

cargo-first-page Shows only the first page of rustc output. Installation cargo install cargo-firstpage Usage Prefix the cargo command by firstpage: T

Cecile Tonglet 11 Dec 19, 2021
An example of Brainf*** JIT-compiler with only the standard library.

jit-compiler An example of Brainf*** JIT-compiler with only the standard library. Prerequisite Rust(1.56.0-nightly or later, but it must work kind of

Akihito KIRISAKI 18 Jan 22, 2022
a simple compiled language i made in rust. it uses intermediate representation (IR) instead of an abstract syntax tree (AST).

a simple compiled language i made in rust. it uses intermediate representation (IR) instead of an abstract syntax tree (AST).

null 4 Oct 3, 2022