Awesome
fomat-macros
This crate provides alternative syntax for
write!
, writeln!
, print!
, println!
, eprint!
, eprintln!
and format!
macros
from the Rust standard library.
The names of macros in this crate
are formed by removing the letter r
from their std
counterparts:
wite!
, witeln!
, pint!
, pintln!
,
epint!
, epintln!
, fomat!
.
Installation
Add this to your Cargo.toml
:
[dependencies]
fomat-macros = "0.3.2"
And use
the macros in your .rs
file, eg.:
use fomat_macros::pintln;
This version requires Rust 1.30. For support for older versions, see version 0.2.1.
Examples
pintln!("Hello, world!");
pintln!(); // empty line
pintln!("The answer is "(40 + 2)); // parentheses use the Display trait
pintln!([vec![1, 2, 3]] " -- numbers"); // brackets use the Debug trait
As you can see, instead the format string and arguments,
we have a list of things to print
without any separators.
Each thing may be a string literal or an expression in brackets
(apart of ()
and []
there are also braces {}
, which may
be used for more advanced format specifiers, see the docs).
You can also use if
, if let
, match
and for
constructs
inside the macro. They use regular Rust syntax, except
everything inside the {}
blocks will use the
list-of-things-to-print syntax again.
let list = vec![1, 2, 3];
let s = fomat!( for x in &list { (x) " :: " } "nil" );
// s == "1 :: 2 :: 3 :: nil"
For loops can also use an optional separator. For details, see the docs.
There's also a shorthand for debugging, which prints both
the expression and value. To enable, put =
as the first
character inside the any kind of brackets.
let list = vec![1, 2, 3];
epintln!([=list]); // prints list = [1, 2, 3]
Why?
What was the motivation to create this crate?
-
More locality – everything is written in the same order it will be printed. But that might a personal preference.
-
Easier to refactor – especially when you suddenly want to add a conditional print inside a long format string. Compare:
let s = fomat!( "first line\n" if condition() { (foo) } "third line\n" );
let s = { use ::std::fmt::Write; let mut s = "first line\n".to_owned(); if condition() { write!(s, "{}", foo).unwrap() } write!(s, "third line\n").unwrap(); s };
-
Speed!
fomat!
may be faster thanformat!
(seecargo bench
). That's because there's just one virtual call for single invocation offomat!
instead of one per each argument instd::format!
.
Limitations
The write!
and writeln!
macros work on everything that
has a .write_fmt
method. This crate requires also
the .write_str
method. It works for any io::Write
or
fmt::Write
, but in unlikely circumstances if you're using something
custom, you should consult the source.
Is it a templating language?
Kind of, but please don't use it as HTML-templating language for security critical code, as it performs no escaping of special characters.