- Not compatible with non-ANSI terminals.
- Currently only supports the basic 8 colours + 8 HL variants.
- Does not respect NO_COLOR env var or perform runtime checks for compatibility.
say!(Blue Bold "The most ergonomic printing macro.", Italic " Is finally here");cargo add saying
- Zero dependencies (only uses std)
- No runtime overhead, just parses into a single println!() at compile time using macro_rules (no proc macros)
- Ergonomic and readable
- Any expression can just be used as an argument in position
Prints to stdout only and automatically adds a newline (unless you use the Inline style).
Once a colour or style is set, all proceeding arguments will use the same style until it is changed or reset.
Just chuck some styles in front of your expressions (no need for anything between them), and you're good to go.
// Basic usage
say!("Hi");
say!(Green "Hi");
say!(Yellow 2 + 2);
// Multiple arguments
say!("Hi", " there");
// Mixing different styles on the same line
say!(Red "Hi", Blue " there");
// Multiple styles and multiple arguments
// Using numbered colours for different palettes
say!(
Red "Hello ",
Blue Bold " World",
Red "!",
);Instead of using the println "{}" syntax, you add your expressions in order. Positional formatting is not supported. This is an arguably a more readable alternative.
Any expression can have colours / styles in front of them. Even if it's not a string literal.
You can use # in front of an expression to debug print it. Use the keyword "Pretty" to pretty print it.
// Using Variables in the macro
let subject = "world";
let collection = vec![0, 1, 2];
say!(Red Underline "Hello ", Cyan subject, "!");
// Using expressions in the macro -
// You can optionally wrap expressions in parentheses or brackets if you really want.
// But due to BIG BRAIN PARSING™ this is not required.
// You can just yeet expressions straight into the macro.
say!(Dark Magenta "Extreme Mathematics ", Bright 2 + 1);
// With a debug print
say!(Green "Numbers: ", #collection);
// With a pretty debug print
say!(Blue "Numbers: ", Pretty #collection);
All the basic colour keywords:
-
White
-
Black
-
Red
-
Green
-
Yellow
-
Blue
-
Magenta
-
Cyan
In conjunction with colours, basic style keywords can be used.
Styling
- Bold (This can affect brightness in some terminals)
- Underline
- Invert (Swapped background and foreground colour)
- Italics (Not as widely compatible)
- Bright (Makes the colours brighter)
- Dark (Makes the colours darker but can be inconsistent in different terminals)
Formatting
- Reset (Resets all colours and styles)
- Inline (Keeps this print inline with the previous one, removing the automatically inserted newline)
Colour can also be a highlight for the background of the text. You can change the background colour by adding "HL" after the colour name:
- BlackHL
- WhiteHL
- RedHL
- GreenHL
- YellowHL
- BlueHL
- MagentaHL
- CyanHL
// Basic usage
say!(RedHL "Hi");
say!(GreenHL "Hi");
say!(Black YellowHL "Hi");You can use the # keyword to debug print expressions. The "Pretty" keyword pretty prints expressions.
The macro also supports various other formatting prefixes that start with a #:
let var = String::new();
say!(Green "Hex: ", #x 255); // 0xff
say!(Blue "Binary: ", #b 15); // 0b1111
say!(Red "Octal: ", #o 64); // 0o100
say!(Yellow "Pointer: ", #p &var); // 0x7fff...
say!(Green "Scientific: ", #e 123456.789); // 1.23456789e5
say!(Blue "Scientific: ", #E 0.000123); // 1.23E-4Loads of usage examples can be found in the test file.
You will get all the normal print!() errors if your arguments aren't valid. But the macro does throw a CompileError when you have styles in a macro, but no expressions.
This may be extended for advanced styling in the future with backwards compatibility. This will allow opting into higher compatibility risk for the sake of some more pretty colours. Yay.
big Todo:
- Generalise into a custom string formatter (instead of format!()) and replace invoking print!() with calling _print!() with this custom formatter. This will reduce compile time cost even further and allow curly braces to be used without the need for escaping.