Release build

In our final chapter, we’ll build a release version of our project then talk about where to go from here.

We’re almost finished!

# Releasing & sharing our tool

Up until now, every time we have built our project using cargo build or cargo run to trigger a build, our executable (tinymd.exe) has been built in the “debug” folder that is located inside the “target” folder in the project root:

C:\RustTutorials\
  tinymd\
    \target
      \debug
        tinymd.exe

When you run cargo build with the --release flag, Rust will do a special optimization build of your project, and store it in a “release” folder:

C:\RustTutorials\
  tinymd\
    \target
      \debug
        tinymd.exe <- the development version of the compiler
      \release
        tinymd.exe <- the release version of the compiler

Let’s go ahead and build it now:

$ cargo build --release
   Compiling tinymd v0.1.0 (C:\RustTutorials\tinymd)
    Finished release [optimized] target(s) in 0.76s

Pretty easy!

The development version has debug symbols that Cargo uses to help you during development, which is one reason that the debug version is always going to be slower than the release version. In the release version, Cargo removes all that and also performs some code optimizations. Building a release version takes a little bit more time, but the end result is a faster and smaller executable.

You can now take the executable from the release directory and put it in any folder you want, and as long as you pass it a path with a valid Markdown file that ends in *.md (that only has first-order headings and paragraphs), it will produce a valid HTML file!

After you run cargo build --release, any code changes you make will only appear in the debug version after running cargo build or cargo run. If you want your changes to appear in a new release version, run cargo build --release again.

Congratulations!

You’ve created a working CLI tool that converts Markdown to HTML, and you wrote it all yourself. I’m proud of you!

I hope that this experience has helped you build confidence with Rust so that you are well-equipped mentally and emotionally to start tackling some of the more difficult aspects of this really fun and unique language.

Looking for what to work on next? Consider trying one of the challenges!

# Where to go from here

I hope you’ve enjoyed this experience with Rust, because if you don’t enjoy it at this point I really don’t think you’ll enjoy what comes after this: traits and lifetimes and, depending on what you’re building, mutexes and unsafe and all sorts of little goodies. We’ve really only begun to scratch the surface of what you can do with Rust!

As far as our tiny Markdown compiler goes, I’ve added some challenges below for you to continue on your journey. Do note that you will have to do some self-study to solve these. The Official Rust Book is a great place to start.

I’m also working on a follow-up book to this one, in which we build out the Campfire compiler. If it’s already out and this is still here, can you please let me know? Thanks!

Challenges

  • At the end of the match first_char.pop() block, we have to repeat ourselves by checking whether the ptag or htag are open. How could you encapsulate this logic in a function to better adhere to the DRY principle?

  • The way we are opening and reading the input file is not the same as what you find in the Rust docs for read_lines here. How (and why) is the linked Rust code different?

  • How could you add in some other HTML tags at the top of your output file, like a <style> tag or even a link to a CSS file before you iterate over each line from the input file?

  • How would you add support for more than one character as the flag? For example, how could you parse ## This is a second-order heading? (Hint: the first_char is only the first character of line_contents because we used .take(1)…)

  • Try to add support for <em> (asterisks) and <strong> (double asterisks)

  • When it comes to error checking, Rust has evolved over time to be less verbose. Try out some of the ways Rust lets you skip the verbosity in error-handing by updating parts of the code we wrote to manually unwrap Result objects.

  • This tutorial hasn’t even touched on one of the coolest parts of Cargo–integrated testing built right into the ecosystem! Challenge yourself to use some TDD practices on your next tinker project in Rust.

What now?

That’s it. That’s the end of the book. I hope you enjoyed the journey. For more about Rust, consider Rust By Example to learn more about the language and High Assurance Rust for a very deep dive into Rust and systems engineering. I have another book about Rust in the works that will immediately follow this one under active development. Stay connected on social media

-Jesse

“But what if I want to play a game?”

Checkpoint

Before moving on, you should be able to confidently:

  • Build a release version of a project in Rust