<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Doken Edgar</title>
    <description>The latest articles on Forem by Doken Edgar (@doken).</description>
    <link>https://forem.com/doken</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1154853%2F914c1b0f-e57f-49c2-aaf2-5f9172bfab0e.png</url>
      <title>Forem: Doken Edgar</title>
      <link>https://forem.com/doken</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/doken"/>
    <language>en</language>
    <item>
      <title>Starting to Rust</title>
      <dc:creator>Doken Edgar</dc:creator>
      <pubDate>Mon, 04 Nov 2024 17:59:05 +0000</pubDate>
      <link>https://forem.com/doken/starting-to-rust-35pf</link>
      <guid>https://forem.com/doken/starting-to-rust-35pf</guid>
      <description>&lt;h2&gt;
  
  
  Starting to Rust: A Developer’s Journey into the Rust Language
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This article is just me and my thoughts basically; trying to walk through my code and thought-processes, as I learn Rust.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;A couple of weeks ago, I decided to challenge myself by learning a new programming language alongside what I use in my day job. That’s how I found myself diving into Rust. The steep learning curve was one of the things that attracted me to it (yes, I’m that kind of developer—you're welcome). Beyond the challenge, I believe Rust will make me a stronger developer overall. Concepts like memory management and data ownership, which are often handled behind the scenes in other languages, are front and center here. And, of course, working without a garbage collector adds a unique layer of excitement (and occasional frustration) with the borrow checker!&lt;/p&gt;

&lt;p&gt;Anyways, according to &lt;a href="https://en.wikipedia.org/wiki/Rust_(programming_language)" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;, Rust is a general-purpose programming language, emphasizing performance, type safety, and concurrency. It enforces memory safety, meaning that all references point to valid memory. It does so without a traditional garbage collector; instead, both memory safety errors and data races are prevented by the "borrow checker", which tracks the object lifetime of references at compile time. &lt;/p&gt;

&lt;p&gt;It has excellent documentation on how to get started at the &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;official site&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I was using the &lt;a href="https://doc.rust-lang.org/book" rel="noopener noreferrer"&gt;Rust Book&lt;/a&gt;, (I still am), but in order to avoid being caught in tutorial hell, I asked Chat-GPT to suggest projects I can build in order of difficulty to solidify the concepts as I go along. It came back with the following suggestions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To-Do App&lt;/li&gt;
&lt;li&gt;Password Manager&lt;/li&gt;
&lt;li&gt;Conway’s Game&lt;/li&gt;
&lt;li&gt;Web Scraper&lt;/li&gt;
&lt;li&gt;Crate for Utilities&lt;/li&gt;
&lt;li&gt;Web Server&lt;/li&gt;
&lt;li&gt;URL Shortener&lt;/li&gt;
&lt;li&gt;Chat Application&lt;/li&gt;
&lt;li&gt;2D Game&lt;/li&gt;
&lt;li&gt;Blockchain&lt;/li&gt;
&lt;li&gt;Text Editor&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, I started with the almighty Command-Line To-Do App. &lt;/p&gt;

&lt;p&gt;The acceptance criteria was pretty straight forward: add tasks via the command line, display items from the todo list, save, update and delete items, and ensure the data is persisted by writing to a file.&lt;/p&gt;

&lt;p&gt;The goal here is to basically get a feel of the Rust language with a specific project and goal in mind, whilst also learning concepts around File I/O, mutability, dealing with the dreaded borrow checker, vectors, modules, external crates and so on.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In order for this not to be an extremely long post, I'll break the write up into multiple parts, each focusing on addressing a single item from the acceptance criteria of the To-Do App.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;A word of caution, these are my first forays into the Rust world, hence some of the code may not be the most efficient or idiomatic Rust code you'll ever see (I have this mental note that I can't wait to comeback to this code in a few months/years and see how far I've improved).&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With that out of the way, here's my Command-Line To-do App in Rust!&lt;/p&gt;

&lt;p&gt;As stated earlier, this is a simple command-line tool where users can manage a to-do list. The app allows users to add tasks, mark them as complete, display a list of tasks, and remove tasks. The list of tasks is saved to a file so that it persists across sessions.&lt;/p&gt;

&lt;p&gt;Firstly, for this one app, I envisioned it's flow to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the app starts, and a menu is printed out on the terminal&lt;/li&gt;
&lt;li&gt;the menu items are the operations that the app supports. These are view all tasks, add a task, update a task and delete a task&lt;/li&gt;
&lt;li&gt;each menu item will have a number, and the user is expected to reply back with the menu number, signifying which operation they want to perform. This is because, it is a command line app, and so there's no GUI to use the mouse.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I created a project after setting up my development environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;cli_to_do&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Cargo&lt;/em&gt; is a tool that helps manage Rust projects. It's not compulsory to use it, but it's quite beneficial especially when you start to add dependencies (called &lt;em&gt;crates&lt;/em&gt; in Rust) and handling a large project, so it's not the worst idea to be using it here too.&lt;/p&gt;

&lt;p&gt;Now, for a Rust app, the entry point is the &lt;code&gt;main.rs&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mh2marshw25hyyrehd4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mh2marshw25hyyrehd4.png" alt="main.rs" width="800" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As can be seen in the &lt;code&gt;main()&lt;/code&gt;, I'm using a number of &lt;em&gt;modules&lt;/em&gt;, which needed to be imported first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;delete_task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;helpers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;to_do_struct&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;update_task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;view_all_tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the folder structure looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcanuzmiw9o4yqppvebm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcanuzmiw9o4yqppvebm.png" alt="CLI To-Do folder structure" width="744" height="1121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code and functions for each menu item are saved in their individual modules, whilst the common functionalities are in the &lt;code&gt;helpers&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;As seen from the &lt;code&gt;main()&lt;/code&gt; function, when the program starts, the &lt;code&gt;create_file_if_not_exists()&lt;/code&gt; function in the &lt;code&gt;helpers&lt;/code&gt; module is called. This is to ensure that there's a file ready to work with, so if the file exists, it gets loaded, but if the file doesn't exist, it gets created so that the todo items can be saved on it.&lt;/p&gt;

&lt;p&gt;Notice the usage of the double colon (&lt;code&gt;::&lt;/code&gt;); in Rust, this can be / is used as a path separator, similar to the forward slash(/) in a file system. It basically points to where a module or function is found.&lt;br&gt;
So&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;helpers&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_file_if_not_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FILE_PATH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means in the &lt;code&gt;helpers&lt;/code&gt; module that we've already imported, there's a function called &lt;code&gt;create_file_if_not_exists()&lt;/code&gt; that should be called. And that function takes an argument, which is a path to determine if the file exists at that location or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_file_if_not_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path_string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;check_file_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path_string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this completes, the app then displays the available menu items that a user can choose from, &lt;code&gt;menu::show_menu(true);&lt;/code&gt;&lt;br&gt;
This command displays:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvclwzt5tg4a27deeyn80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvclwzt5tg4a27deeyn80.png" alt="Menu showing available actions" width="800" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the user is expected to type in their response on the cli. This is retrieved by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ParseIntError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_menu_selection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a couple of things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;mut&lt;/code&gt; in the &lt;code&gt;menu_input&lt;/code&gt; variable declaration indicates that this is a mutable variable. By default, variables in Rust are immutable, but if you require them to be mutable, then you need to use the &lt;code&gt;mut&lt;/code&gt; keyword when declaring that variable.&lt;/li&gt;
&lt;li&gt;The second thing to note is the data type, &lt;code&gt;Result&amp;lt;usize, ParseIntError&amp;gt;&lt;/code&gt;. What this means is, the function we're calling (&lt;code&gt;menu::get_menu_selection()&lt;/code&gt;) returns a type which is a &lt;code&gt;Result&lt;/code&gt;, but it can be one of two things: either we get a value of type &lt;code&gt;usize&lt;/code&gt; (a built-in type in Rust), or we get a value of &lt;code&gt;ParseIntError&lt;/code&gt;, the result of trying to parse an invalid value into a number. 
This is possibly because the user tried inputting words (or any character that cannot be passed into a number) instead of a number. The &lt;code&gt;get_menu_selection()&lt;/code&gt; function in the &lt;code&gt;menu&lt;/code&gt; module is where the input of the user is received, and that input is parsed to get the actual number, but if the parsing fails, the method returns the &lt;code&gt;ParseIntError&lt;/code&gt; object.
Now, we don't want the application to just crash because some fellow (&lt;em&gt;definitely not from Dumne&lt;/em&gt; 🌚), either intentionally or not, decided to provide an invalid input, so in the &lt;code&gt;while {}&lt;/code&gt; block, we check if the result of parsing the input results in an error, if it does, we prompt the user to provide the input again, and don't move forward until a valid number is provided and parsed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this happens, we need to then extract the number. There are a couple of ways to do this, the recommended way is to use what's called &lt;code&gt;pattern matching&lt;/code&gt;. But that's not what was used here, and I'll explain why.&lt;br&gt;
Instead of matching, I used the &lt;code&gt;unwrap()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why matching is recommended is, it provides a way of handling both outcomes where a variable results in an error, as well as when it contains the actual value, but keep in mind that we've already ensured that the result can't be an error, because if it were, it wouldn't have passed the &lt;code&gt;while {}&lt;/code&gt; block, so it feels redundant to check for that error here again.&lt;/p&gt;

&lt;p&gt;When we get this number, we then need to ensure that the unwrapped value is not more than the available menu actions our app supports. So imagine someone enters the number 50, this is technically a valid number, but it's not logically valid in our case because the actions we support are numbered 1 - 5. That's what the next &lt;code&gt;while {}&lt;/code&gt; block guards against:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Selected value {menu_selection}, greater than options"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;show_menu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;menu_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_menu_selection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Error parsing menu selection.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Please try again:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;show_menu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;menu_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_menu_selection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: I just realized that instead of &lt;code&gt;"&amp;gt; 6"&lt;/code&gt; in the outer loop, it should've been &lt;code&gt;"&amp;gt; 5"&lt;/code&gt;, this doesn't really matter though, because we'll use pattern matching later on to map actions to the number inputs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The outer loop ensures that the input is within the required range of actions, and if it's not, it asks the user to re-enter the selection again, and this requires us to re-validate that they're not making invalid inputs, instead of a number, hence the inner &lt;code&gt;while {}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once a valid number has been provided, then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;extracts the number from the &lt;code&gt;Result&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This reassigning that occurs on the variables &lt;code&gt;menu_input&lt;/code&gt; and &lt;code&gt;menu_selection&lt;/code&gt; denotes why we needed to mark the variables with the &lt;code&gt;mut&lt;/code&gt; keyword, as they have the tendency of being updated, depending on whether the user decided to be sensible or not (😂).&lt;/p&gt;

&lt;p&gt;The last block/scope in the &lt;code&gt;main()&lt;/code&gt; function tries to match actions to be performed, based on the number that was entered from the command-line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;view_all_tasks&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;view_all&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_todo&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;update_task&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;update_todo&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;delete_task&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;delete_task&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Have a nice day, good bye!"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Don't know what action to perform&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is called &lt;code&gt;pattern matching&lt;/code&gt;. &lt;br&gt;
As the name suggest, it takes a variable, and provides &lt;code&gt;"arms"&lt;/code&gt; of what'll happen when there's a match.&lt;br&gt;
The last arm, "_", is used to catch all other cases, if the provided ones were not matched. &lt;br&gt;
Pattern matching is similar to &lt;code&gt;switch-case&lt;/code&gt; statements in other programming languages like Typescript and the likes.&lt;/p&gt;

&lt;p&gt;So in subsequent parts, I'll have posts to go through what happens at each "arm", that is, as we go from viewing all tasks, creating a new task, modifying an existing task and then deleting a task.&lt;/p&gt;

&lt;p&gt;Let me know your thoughts, and please be on the lookout for the follow-up parts to this as I explore Rust land!&lt;/p&gt;

&lt;p&gt;The repository with the code is &lt;a href="https://github.com/dokenedgar/cli_to_do" rel="noopener noreferrer"&gt;here&lt;/a&gt;. It's being updated as I go along.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Starting to Rust</title>
      <dc:creator>Doken Edgar</dc:creator>
      <pubDate>Mon, 04 Nov 2024 17:42:56 +0000</pubDate>
      <link>https://forem.com/doken/starting-to-rust-a-developers-journey-into-the-rust-language-4k6m</link>
      <guid>https://forem.com/doken/starting-to-rust-a-developers-journey-into-the-rust-language-4k6m</guid>
      <description>&lt;h2&gt;
  
  
  Starting to Rust: A Developer’s Journey into the Rust Language
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This article is just me and my thoughts basically; trying to walk through my code and thought-processes, as I learn Rust.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;A couple of weeks ago, I decided to challenge myself by learning a new programming language alongside what I use in my day job. That’s how I found myself diving into Rust. The steep learning curve was one of the things that attracted me to it (yes, I’m that kind of developer—you're welcome). Beyond the challenge, I believe Rust will make me a stronger developer overall. Concepts like memory management and data ownership, which are often handled behind the scenes in other languages, are front and center here. And, of course, working without a garbage collector adds a unique layer of excitement (and occasional frustration) with the borrow checker!&lt;/p&gt;

&lt;p&gt;Anyways, according to &lt;a href="https://en.wikipedia.org/wiki/Rust_(programming_language)" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;, Rust is a general-purpose programming language, emphasizing performance, type safety, and concurrency. It enforces memory safety, meaning that all references point to valid memory. It does so without a traditional garbage collector; instead, both memory safety errors and data races are prevented by the "borrow checker", which tracks the object lifetime of references at compile time. &lt;/p&gt;

&lt;p&gt;It has excellent documentation on how to get started at the &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;official site&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I was using the &lt;a href="https://doc.rust-lang.org/book" rel="noopener noreferrer"&gt;Rust Book&lt;/a&gt;, (I still am), but in order to avoid being caught in tutorial hell, I asked Chat-GPT to suggest projects I can build in order of difficulty to solidify the concepts as I go along. It came back with the following suggestions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To-Do App&lt;/li&gt;
&lt;li&gt;Password Manager&lt;/li&gt;
&lt;li&gt;Conway’s Game&lt;/li&gt;
&lt;li&gt;Web Scraper&lt;/li&gt;
&lt;li&gt;Crate for Utilities&lt;/li&gt;
&lt;li&gt;Web Server&lt;/li&gt;
&lt;li&gt;URL Shortener&lt;/li&gt;
&lt;li&gt;Chat Application&lt;/li&gt;
&lt;li&gt;2D Game&lt;/li&gt;
&lt;li&gt;Blockchain&lt;/li&gt;
&lt;li&gt;Text Editor&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, I started with the almighty Command-Line To-Do App. &lt;/p&gt;

&lt;p&gt;The acceptance criteria was pretty straight forward: add tasks via the command line, display items from the todo list, save, update and delete items, and ensure the data is persisted by writing to a file.&lt;/p&gt;

&lt;p&gt;The goal here is to basically get a feel of the Rust language with a specific project and goal in mind, whilst also learning concepts around File I/O, mutability, dealing with the dreaded borrow checker, vectors, modules, external crates and so on.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In order for this not to be an extremely long post, I'll break the write up into multiple parts, each focusing on addressing a single item from the acceptance criteria of the To-Do App.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;A word of caution, these are my first forays into the Rust world, hence some of the code may not be the most efficient or idiomatic Rust code you'll ever see (I have this mental note that I can't wait to comeback to this code in a few months/years and see how far I've improved).&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With that out of the way, here's my Command-Line To-do App in Rust!&lt;/p&gt;

&lt;p&gt;As stated earlier, this is a simple command-line tool where users can manage a to-do list. The app allows users to add tasks, mark them as complete, display a list of tasks, and remove tasks. The list of tasks is saved to a file so that it persists across sessions.&lt;/p&gt;

&lt;p&gt;Firstly, for this one app, I envisioned it's flow to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the app starts, and a menu is printed out on the terminal&lt;/li&gt;
&lt;li&gt;the menu items are the operations that the app supports. These are view all tasks, add a task, update a task and delete a task&lt;/li&gt;
&lt;li&gt;each menu item will have a number, and the user is expected to reply back with the menu number, signifying which operation they want to perform. This is because, it is a command line app, and so there's no GUI to use the mouse.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I created a project after setting up my development environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;cli_to_do&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Cargo&lt;/em&gt; is a tool that helps manage Rust projects. It's not compulsory to use it, but it's quite beneficial especially when you start to add dependencies (called &lt;em&gt;crates&lt;/em&gt; in Rust) and handling a large project, so it's not the worst idea to be using it here too.&lt;/p&gt;

&lt;p&gt;Now, for a Rust app, the entry point is the &lt;code&gt;main.rs&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mh2marshw25hyyrehd4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mh2marshw25hyyrehd4.png" alt="main.rs" width="800" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As can be seen in the &lt;code&gt;main()&lt;/code&gt;, I'm using a number of &lt;em&gt;modules&lt;/em&gt;, which needed to be imported first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;delete_task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;helpers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;to_do_struct&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;update_task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;view_all_tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the folder structure looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcanuzmiw9o4yqppvebm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcanuzmiw9o4yqppvebm.png" alt="CLI To-Do folder structure" width="744" height="1121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code and functions for each menu item are saved in their individual modules, whilst the common functionalities are in the &lt;code&gt;helpers&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;As seen from the &lt;code&gt;main()&lt;/code&gt; function, when the program starts, the &lt;code&gt;create_file_if_not_exists()&lt;/code&gt; function in the &lt;code&gt;helpers&lt;/code&gt; module is called. This is to ensure that there's a file ready to work with, so if the file exists, it gets loaded, but if the file doesn't exist, it gets created so that the todo items can be saved on it.&lt;/p&gt;

&lt;p&gt;Notice the usage of the double colon (&lt;code&gt;::&lt;/code&gt;); in Rust, this can be / is used as a path separator, similar to the forward slash(/) in a file system. It basically points to where a module or function is found.&lt;br&gt;
So&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;helpers&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_file_if_not_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FILE_PATH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means in the &lt;code&gt;helpers&lt;/code&gt; module that we've already imported, there's a function called &lt;code&gt;create_file_if_not_exists()&lt;/code&gt; that should be called. And that function takes an argument, which is a path to determine if the file exists at that location or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_file_if_not_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path_string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;check_file_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path_string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this completes, the app then displays the available menu items that a user can choose from, &lt;code&gt;menu::show_menu(true);&lt;/code&gt;&lt;br&gt;
This command displays:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvclwzt5tg4a27deeyn80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvclwzt5tg4a27deeyn80.png" alt="Menu showing available actions" width="800" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the user is expected to type in their response on the cli. This is retrieved by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ParseIntError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_menu_selection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a couple of things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;mut&lt;/code&gt; in the &lt;code&gt;menu_input&lt;/code&gt; variable declaration indicates that this is a mutable variable. By default, variables in Rust are immutable, but if you require them to be mutable, then you need to use the &lt;code&gt;mut&lt;/code&gt; keyword when declaring that variable.&lt;/li&gt;
&lt;li&gt;The second thing to note is the data type, &lt;code&gt;Result&amp;lt;usize, ParseIntError&amp;gt;&lt;/code&gt;. What this means is, the function we're calling (&lt;code&gt;menu::get_menu_selection()&lt;/code&gt;) returns a type which is a &lt;code&gt;Result&lt;/code&gt;, but it can be one of two things: either we get a value of type &lt;code&gt;usize&lt;/code&gt; (a built-in type in Rust), or we get a value of &lt;code&gt;ParseIntError&lt;/code&gt;, the result of trying to parse an invalid value into a number. 
This is possibly because the user tried inputting words (or any character that cannot be passed into a number) instead of a number. The &lt;code&gt;get_menu_selection()&lt;/code&gt; function in the &lt;code&gt;menu&lt;/code&gt; module is where the input of the user is received, and that input is parsed to get the actual number, but if the parsing fails, the method returns the &lt;code&gt;ParseIntError&lt;/code&gt; object.
Now, we don't want the application to just crash because some fellow (&lt;em&gt;definitely not from Dumne&lt;/em&gt; 😉), either intentionally or not, decided to provide an invalid input, so in the &lt;code&gt;while {}&lt;/code&gt; block, we check if the result of parsing the input results in an error, if it does, we prompt the user to provide the input again, and don't move forward until a valid number is provided and parsed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this happens, we need to then extract the number. There are a couple of ways to do this, the recommended way is to use what's called &lt;code&gt;pattern matching&lt;/code&gt;. But that's not what was used here, and I'll explain why.&lt;br&gt;
Instead of matching, I used the &lt;code&gt;unwrap()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why matching is recommended is, it provides a way of handling both outcomes where a variable results in an error, as well as when it contains the actual value, but keep in mind that we've already ensured that the result can't be an error, because if it were, it wouldn't have passed the &lt;code&gt;while {}&lt;/code&gt; block, so it feels redundant to check for that error here again.&lt;/p&gt;

&lt;p&gt;When we get this number, we then need to ensure that the unwrapped value is not more than the available menu actions our app supports. So imagine someone enters the number 50, this is technically a valid number, but it's not logically valid in our case because the actions we support are numbered 1 - 5. That's what the next &lt;code&gt;while {}&lt;/code&gt; block guards against:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Selected value {menu_selection}, greater than options"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;show_menu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;menu_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_menu_selection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Error parsing menu selection.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Please try again:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;show_menu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;menu_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_menu_selection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: I just realized that instead of &lt;code&gt;"&amp;gt; 6"&lt;/code&gt; in the outer loop, it should've been &lt;code&gt;"&amp;gt; 5"&lt;/code&gt;, this doesn't really matter though, because we'll use pattern matching later on to map actions to the number inputs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The outer loop ensures that the input is within the required range of actions, and if it's not, it asks the user to re-enter the selection again, and this requires us to re-validate that they're not making invalid inputs, instead of a number, hence the inner &lt;code&gt;while {}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once a valid number has been provided, then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;menu_input&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;extracts the number from the &lt;code&gt;Result&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This reassigning that occurs on the variables &lt;code&gt;menu_input&lt;/code&gt; and &lt;code&gt;menu_selection&lt;/code&gt; denotes why we needed to mark the variables with the &lt;code&gt;mut&lt;/code&gt; keyword, as they have the tendency of being updated, depending on whether the user decided to be sensible or not (😂).&lt;/p&gt;

&lt;p&gt;The last block/scope in the &lt;code&gt;main()&lt;/code&gt; function tries to match actions to be performed, based on the number that was entered from the command-line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;menu_selection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;view_all_tasks&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;view_all&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_todo&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;update_task&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;update_todo&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;delete_task&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;delete_task&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Have a nice day, good bye!"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Don't know what action to perform&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is called &lt;code&gt;pattern matching&lt;/code&gt;. &lt;br&gt;
As the name suggest, it takes a variable, and provides &lt;code&gt;"arms"&lt;/code&gt; of what'll happen when there's a match.&lt;br&gt;
The last arm, "_", is used to catch all other cases, if the provided ones were not matched. &lt;br&gt;
Pattern matching is similar to &lt;code&gt;switch-case&lt;/code&gt; statements in other programming languages like Typescript and the likes.&lt;/p&gt;

&lt;p&gt;So in subsequent parts, I'll have posts to go through what happens at each "arm", that is, as we go from viewing all tasks, creating a new task, modifying an existing task and then deleting a task.&lt;/p&gt;

&lt;p&gt;Let me know your thoughts, and please be on the lookout for the follow-up parts to this as I explore Rust land!&lt;/p&gt;

&lt;p&gt;The repository with the code is &lt;a href="https://github.com/dokenedgar/cli_to_do" rel="noopener noreferrer"&gt;here&lt;/a&gt;. It'll be updated as needed.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>todayilearned</category>
    </item>
  </channel>
</rss>
