You could be more clear in what your asking. What's the desired behavior? What part isn't clear?
Note that formatting strings (i. e. values of type String or &str or similar) happens either by taking their content verbatim, or by showing an escaped literal with "s around it and with \n in place of line breaks, etc. This choice is made by adding :? to the format string, so that
{input}, or {} (in the latter case passing the input as an additional argument) behaves the same and produces the content verbatim. This works via the Display trait.
{input:?}, or {:?} (in the latter case passing the input as an additional argument) behaves the same and produces an escaped literal. This works via the Debug trait.
If there's a type that doesn't implement Display or Debug how you like, you can wrap it in a newtype and implement Display and/or Debug on that instead:
use std::fmt;
struct TempDisplayer(String);
impl fmt::Display for TempDisplayer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for line in self.0.lines() {
writeln!(f, ":-) {line}")?;
}
Ok(())
}
}
It also seems you're confused between argument positions and argument formatter. I recommend to read the full document steffahn linked, but why don't you test these 4 variants yourself?
If I understand you right, I think what you search for is:
println!("{}", input);
And:
println!("{input:?}");
Whenever you use a colon (:) in the formatting string, the following characters specify how to format the output. Before the colon (or if you don't use any colon at all), you may state a local variable name or named argument to the println! macro.
If you omit the variable name, then println! (as well as many other formatting macros) will expect an unnamed argument instead.
So argument-style and formatting can be selected individually.
Some examples:
fn main() {
let s = "Hello World!";
println!("Local variable in format string: {s}");
println!("Argument name in format string: {foo}", foo = s);
// The same works with debug formatting:
println!("Local variable in format string (with debug): {s:?}");
println!("Argument name in format string (with debug): {foo:?}", foo = s);
// Or we can do:
println!("No name: {}", s);
println!("No name (with debug): {:?}", s);
// Other formatting is possible too:
println!("{s:-^20}");
println!("{:-^20}", s);
// Why do we need debug formatting, for example?
let y = "";
println!("We can't see well what the string {y} is containing.");
println!("But when we use debug output for {y:?}, then it's easier.");
}
That said, I felt very much confused by the formatting syntax in the beginning too. I think that's because tutorials often only teach you {} and {:?}. I didn't understand what the : really means until some time later.
Thank You, now I have fully understood (I think fully).. There are traits Debug and Display..
I many times saw messages about display and debug, but did not pay attention..