In this lesson we’re going to learn how to use the format!
macro to template a string using the variables we declared in previous lessons.
❯ cargo run post rust,bevy "Doing shader stuff in Bevy" doing-shader-stuff-in-bevy.md
Compiling first v0.1.0 (/Users/chris/github/rust-adventure/first-cli)
warning: unused variable: `filename`
--> src/main.rs:10:9
|
10 | let filename = &args[4];
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_filename`
|
= note: `#[warn(unused_variables)]` on by default
warning: `first` (bin "first") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/first post rust,bevy 'Doing shader stuff in Bevy' doing-shader-stuff-in-bevy.md`
[src/main.rs:5] &args = [
"target/debug/first",
"post",
"rust,bevy",
"Doing shader stuff in Bevy",
"doing-shader-stuff-in-bevy.md",
]
[src/main.rs:23] new_file_contents = "---\nlayout: post\ntags: rust,bevy\nstatus: draft\n---\n\n# Doing shader stuff in Bevy\n\n"
The Code
We’re going to end up with this code.
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
dbg!(&args);
let layout = &args[1];
let tags = &args[2];
let heading = &args[3];
let filename = &args[4];
let new_file_contents = format!(
"---
layout: {layout}
tags: {tags}
status: draft
---
# {heading}
"
);
dbg!(new_file_contents);
}
The format! macro
Once we have the arguments to our CLI, we need to use them to do something.
In this case, we’ll be scaffolding out a new fake blog post template.
The blog post template will include some yaml frontmatter and a markdown heading. The output will end up looking like this example.
---
layout: post
tags: rust,bevy
status: draft
---
# Doing shader stuff in Bevy
The format!
macro is a lot like the dbg!
macro with the big difference being that it doesn’t print to the console, it only constructs the string for us.
We can add the format!
macro in, and store the return value in the new_file_contents
variable.
Strings in Rust are multi-line by default, so we can either use literal newlines as I’ve done here or we can write in \n
, the escape sequence for a newline.
let new_file_contents = format!(
"---
layout: {layout}
tags: {tags}
status: draft
---
# {heading}
"
);
dbg!(new_file_contents);
The format!
macro allows us to use Formatters
, which are curly braces inside the string: {}
, to define what variables to use and how to turn those variables into a string.
One of the most common formatters is called the Display
formatter, and it’s the two curly braces together: {}
.
We can also use the name of a variable in the middle of the display formatter and format!
will use the value from that variable and turn it into a string for us using the Display
trait implementation.
In our case, all of our variables reference strings, so turning them into strings is… uneventful.
We’ll also dbg!
out the new_file_contents
and see what it looks like.
Using cargo run with the following arguments will allow our program to format the string and print out the result.
Note that in this output, I’ve removed all of the dbg!
calls except for the one for new_file_contents
.
❯ cargo run post rust,bevy "Doing shader stuff in Bevy" doing-shader-stuff-in-bevy.md
Compiling first v0.1.0 (/Users/chris/github/rust-adventure/first-cli)
warning: unused variable: `filename`
--> src/main.rs:10:9
|
10 | let filename = &args[4];
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_filename`
|
= note: `#[warn(unused_variables)]` on by default
warning: `first` (bin "first") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/first post rust,bevy 'Doing shader stuff in Bevy' doing-shader-stuff-in-bevy.md`
[src/main.rs:23] new_file_contents = "---\nlayout: post\ntags: rust,bevy\nstatus: draft\n---\n\n# Doing shader stuff in Bevy\n\n"
filename
unused variable: Even though our program runs and creates the string we’re going to write to a file later, we get a compiler warning because we haven’t used the filename
variable for anything.
warning: unused variable: `filename`
--> src/main.rs:9:9
|
9 | let filename = &args[4];
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_filename`
|
= note: `#[warn(unused_variables)]` on by default
If we wanted to show that we aren’t using this variable in our code, we could use an _
before the variable name to silence the warning and show that we aren’t using it.
That would look like this
let _filename = &args[4];
We’ll use the filename in the next video though, so I’m going to leave it without the underscore.