A macro for formatting non literal strings at runtime in Rust.
formatx
is a dependency free string templating library with syntax derived from std::fmt. formatx exports formatx! macro which is similar to format! macro. formatx works by first parsing the template string and then it uses format!
macro internally to replicate it's behaviour. formatx aims for formatting strings and numbers although an generic type can also be formatted like an struct.
Add this to your Cargo.toml file.
[dependencies]
formatx = "0.2.3"
Or add from command line.
$ cargo add formatx
See docs and examples to know how to use it.
SOURCE: format! with non literal string
use formatx::formatx;
fn message(language: &str, name: &str, number: i32) -> String {
let s = match language {
"french" => "Bonjour {}, le nombre est {}",
"spanish" => "Hola {}, el numero es {}",
_ => "Hi {}, the number is {}",
};
formatx!(s, name, number).unwrap()
}
fn main() {
println!("{}", message("french", "Léa", 1));
println!("{}", message("spanish", "Sofia", 2));
println!("{}", message("english", "Ashley", 3));
}
OUTPUT
Bonjour Léa, le nombre est 1
Hola Sofia, el numero es 2
Hi Ashley, the number is 3
The main goal of formatx
is to provide a almost identical syntax as of rust's format syntax. The syntax of formatx
is identical to std::fmt. You can also see gettext documentation, the rust's format syntax specifications is mentioned there too.
Warning Examples given below will always panic.
-
Only types which implements Display + Debug traits are supported. Other formatting-traits aren't supported.
-
Local variable interpolation isn't supported.
let people = "Rustaceans";
formatx!("Hello {people}!").unwrap();
- Intermingling the two types of positional specifiers isn't supported.
formatx!("{1} {} {0} {}", 1, 2).unwrap();
- Parameter setting through
$
sign argument isn't supported.
formatx!("{:width$}!", "x", width = 5).unwrap();
- An asterisk
.*
can't be used to set precision.
formatx!("{:.*}", 5, 0.01).unwrap();
Positional arguments are handled by an internal key which increments itself whenever an postional argument is passed through the macro. So, the behaviour is very different when compared to format
macro.
By default this internal key is set to 0
and when an positional argument is passed. formatx
resolves the replacement by first checking if there is 0
key present in format string (eg. Hello {0}
) or not, if the 0
is present then it replaces it, else if the 0
key is not present in the format string (eg.Hello {}
) it replaces the first blank placeholder. After a replacement is made this internal key is increased by 1
.
asserteq!(
format!("{} {2} {} {1} {4} {} {3} {5} {6}", "zero", "one", "two", "three", "four", "five", "six"),
formatx!("{} {2} {} {1} {4} {} {3} {5} {6}", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight").unwrap() // This line won't panic
); // This line will panic
An error cannot be raised in such cases because formatx
works at runtime and it doesn't know the future upcoming postitional arguments. So while designing your app keep this point in mind or simply use key value arguments. See issue #7 for more info.
Unlike rust's built-in format!
macro, which reports an error if any provided arguments are not used in the format string, formatx!
allows unused arguments. This can be particularly useful in localization scenarios, where translations may or may not require certain arguments depending on grammatical rules.
Dual Licensed