<?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>DEV Community: Roger Torres (he/him/ele)</title>
    <description>The latest articles on DEV Community by Roger Torres (he/him/ele) (@rogertorres).</description>
    <link>https://dev.to/rogertorres</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%2F558604%2F06edfb61-a122-472e-9c0d-c73d9eaf31f6.png</url>
      <title>DEV Community: Roger Torres (he/him/ele)</title>
      <link>https://dev.to/rogertorres</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rogertorres"/>
    <language>en</language>
    <item>
      <title>[Rust] Tokio stack overview: Runtime</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Sun, 12 Sep 2021 13:39:39 +0000</pubDate>
      <link>https://dev.to/rogertorres/rust-tokio-stack-overview-runtime-9fh</link>
      <guid>https://dev.to/rogertorres/rust-tokio-stack-overview-runtime-9fh</guid>
      <description>&lt;p&gt;Quoting its &lt;a href="https://tokio.rs/blog/2017-01-tokio-0-1" rel="noopener noreferrer"&gt;first announcement&lt;/a&gt;, "Tokio is a platform for writing fast networking code in Rust [and] is primarily intended as a foundation for other libraries". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://tokio.rs/#tk-lib-tokio" rel="noopener noreferrer"&gt;&lt;img src="https://media.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%2Fyuzlo4csnkfvpl6gwnq8.png" alt="Tokio Stack" width="450" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The central piece of this platform, the runtime, is also named tokio, and that is what this post is about; for understanding tokio runtime is vital for understanding the platform as a whole and — given the current state of things — how to write asynchronous code in Rust.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is an asynchronous runtime?
&lt;/h2&gt;

&lt;p&gt;Core Rust provides the types to build asynchronous applications. However, when building, say, an asynchronous &lt;em&gt;network&lt;/em&gt; application, we found ourselves in the need of a lot of boilerplate code. We can write it ourselves, &lt;strong&gt;or&lt;/strong&gt; we can use a library that gives it to us ready-made (and probably better-made). And that is what an asynchronous runtime such as Tokio does, it provides the building blocks to construe such an application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Futures
&lt;/h2&gt;

&lt;p&gt;Let us start by taking a look at what core Rust brings to the table, so we can better understand what we would lack if we were to build an asynchronous network application all by ourselves.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;P.S. &lt;em&gt;I already wrote an &lt;a href="https://dev.to/rogertorres/asynchronous-rust-basic-concepts-44ed"&gt;introduction to async Rust&lt;/a&gt;, so this will be a dried out explanation.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Asynchronous Rust allows us to create concurrent applications. It does so via the syntax &lt;code&gt;async/.await&lt;/code&gt;. Basically, blocks and functions declared with &lt;code&gt;async&lt;/code&gt; &lt;em&gt;desugar&lt;/em&gt; into a block or function that returns an implementation of a trait called &lt;a href="https://aturon.github.io/blog/2016/08/11/futures/" rel="noopener noreferrer"&gt;&lt;code&gt;Future&lt;/code&gt;&lt;/a&gt;. &lt;code&gt;Future&lt;/code&gt; is a state machine, so it can keep up with the progress made in a certain operation, which means it can stop processing at some point and, when executing again, continue from where it stopped. On a higher level, we might say that a future is the representation of a value that may or may not be ready, a duality that is put forward using an enum called &lt;code&gt;Poll&lt;/code&gt; that has two variants: &lt;code&gt;Pending&lt;/code&gt; and &lt;code&gt;Ready&amp;lt;T&amp;gt;&lt;/code&gt;. The &lt;code&gt;Future&lt;/code&gt; trait also has a function, called &lt;code&gt;poll()&lt;/code&gt;, that will try to make as much progress as possible within the future (thus driving the state machine forward). This function, &lt;code&gt;poll()&lt;/code&gt;, is first executed when we &lt;code&gt;.await&lt;/code&gt; the future. To &lt;code&gt;.await&lt;/code&gt; the future is to deliver it to a &lt;strong&gt;scheduler&lt;/strong&gt; (formerly known as &lt;em&gt;executor&lt;/em&gt;) that will &lt;code&gt;poll()&lt;/code&gt; it. If it is processed through completion, &lt;code&gt;Ready&amp;lt;T&amp;gt;&lt;/code&gt; is returned, otherwise &lt;code&gt;Pending&lt;/code&gt; is returned and the scheduler keeps the future aside, waiting for a request to &lt;code&gt;poll()&lt;/code&gt; it again. This request comes from the &lt;strong&gt;driver&lt;/strong&gt; (formerly known as &lt;em&gt;reactor&lt;/em&gt;), which is an &lt;em&gt;I/O event loop&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Rust does not provide these last two. That is why we need a crate to help us with that. Furthermore, we also need some time-related utilities to handle all this scheduling stuff.&lt;/p&gt;

&lt;p&gt;Needless to say, this is precisely what the Tokio runtime provides. Quoting its &lt;a href="https://docs.rs/tokio/1.11.0/tokio/runtime/index.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unlike other Rust programs, asynchronous applications require runtime support. In particular, the following runtime services are necessary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An I/O event loop, called the driver, which drives I/O resources and dispatches I/O events to tasks that depend on them.&lt;/li&gt;
&lt;li&gt;A scheduler to execute tasks that use these I/O resources.&lt;/li&gt;
&lt;li&gt;A timer for scheduling work to run after a set period of time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Scheduler
&lt;/h2&gt;

&lt;p&gt;When you code an async function for the first time, you realize that the place from which you are calling this function also has to be async. And if you go all the way up and try to make your &lt;code&gt;main()&lt;/code&gt; function async, Rust will tell you that "&lt;code&gt;main&lt;/code&gt; function is not allowed to be &lt;code&gt;async&lt;/code&gt;". &lt;/p&gt;

&lt;p&gt;Asking Rust to &lt;code&gt;explain&lt;/code&gt; this error gives us a hint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rustc --explain E0752

`fn main()` or the specified start function is not allowed to be `async`. Not having a correct async runtime library setup may cause this error.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A quick search on the web is enough to provide the solution: we got to import &lt;code&gt;tokio&lt;/code&gt; and use this attribute macro:&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="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; 
    &lt;span class="c1"&gt;// ... &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, even thought it certainly works, a question remains…&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;Because at some point the futures have to be dealt with, and there is nothing above the &lt;code&gt;main()&lt;/code&gt; function in a Rust program, so whoever is handling them, have to be below &lt;code&gt;main()&lt;/code&gt;. Another way to put it is to say that the &lt;code&gt;main()&lt;/code&gt; is the entry door of your program. The operating system running the binary knows nothing about futures, so they have to be managed "inside the house", that is, after we entered the program. So, &lt;code&gt;main()&lt;/code&gt; has to be synchronous. &lt;/p&gt;

&lt;p&gt;If that is the case, how does Tokio manage to make &lt;code&gt;main()&lt;/code&gt; async, if the top-level function cannot be async? Well, it does not. &lt;code&gt;#[tokio::main]&lt;/code&gt; will desugar &lt;code&gt;async fn main()&lt;/code&gt; into something like this:&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;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_multi_thread&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.enable_all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.block_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&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;When using the attribute macro &lt;code&gt;#[tokio::main]&lt;/code&gt;, we are building a runtime below &lt;code&gt;main()&lt;/code&gt;, a runtime that will handle the tree of futures. Why am I calling it a tree? Because a future may &lt;code&gt;.await&lt;/code&gt; other futures. I will talk more about multiple &lt;code&gt;.await&lt;/code&gt; calls later. For now, let us move on with this idea of handling a tree of futures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling the tree of futures
&lt;/h3&gt;

&lt;p&gt;Consider the example below.&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="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;join!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;bar&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&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;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0:8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="nf"&gt;.accept&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_pair&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;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;"`foo()` is finished"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="s"&gt;"foo"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"error"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&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;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0:8081"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="nf"&gt;.accept&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_pair&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;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;"`bar()` is finished"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="s"&gt;"bar"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"error"&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;blockquote&gt;
&lt;p&gt;&lt;em&gt;Tip: run the code above and connect to both &lt;code&gt;0.0.0.0:8080&lt;/code&gt; and &lt;code&gt;0.0.0.0:8081&lt;/code&gt; using your browser and check the result in the terminal where you ran the program.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we call &lt;code&gt;foo().await&lt;/code&gt;, we are handing &lt;code&gt;foo()&lt;/code&gt;'s future to the runtime scheduler, the one responsible for calling &lt;code&gt;poll()&lt;/code&gt; on it. Futures are executed by the scheduler as part of &lt;a href="https://docs.rs/tokio/1.11.0/tokio/task/index.html" rel="noopener noreferrer"&gt;&lt;em&gt;tasks&lt;/em&gt;&lt;/a&gt;. You might think of a task as a thread that is not handled by the OS scheduler, but by the runtime scheduler (they are &lt;a href="https://en.wikipedia.org/wiki/Green_threads" rel="noopener noreferrer"&gt;virtual/green threads&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;This will run &lt;code&gt;foo()&lt;/code&gt; as far as possible towards completion, which means that the executor will not preemptively stop it to run something else in its stead (as the OS does with its threads). For the Tokio scheduler, as far as a task is doing relevant work, it may keep working. In a more technical jargon, tasks run until they &lt;em&gt;yield&lt;/em&gt;. In our example, &lt;code&gt;foo()&lt;/code&gt; runs until it starts listening at port &lt;code&gt;8080&lt;/code&gt;. If you're trying to understand which part of our code is explicitly yielding the task, give up. It is not there. We don't code yields, Rust manages that for us.&lt;/p&gt;

&lt;p&gt;After &lt;code&gt;foo()&lt;/code&gt; yields, &lt;code&gt;join!&lt;/code&gt;—a macro that &lt;code&gt;.await&lt;/code&gt;s—will call &lt;code&gt;bar()&lt;/code&gt;, which will run until it starts listening at port &lt;code&gt;8081&lt;/code&gt;. At this point, as both functions have yielded, we have two futures waiting to be polled again, and they may be polled in any order. Now, imagine that &lt;code&gt;foo()&lt;/code&gt; and/or &lt;code&gt;bar()&lt;/code&gt; call async functions inside them, giving new tasks to the scheduler. In a scenario like this, &lt;em&gt;we have a tree of futures.&lt;/em&gt; One important thing to understand here is that we have a "root-future" (the async book calls it “top-level future”, but I will stick with “root”); in this case, it is the future returned by that async block in &lt;code&gt;main&lt;/code&gt; (you will find inside &lt;code&gt;block_on()&lt;/code&gt; in the &lt;em&gt;desugared&lt;/em&gt; example). And this is important for at least two reasons.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;, a task is responsible for a tree of futures. So, let's say we have an &lt;code&gt;async fn main()&lt;/code&gt;. As we saw, under the hood this is a normal &lt;code&gt;main()&lt;/code&gt; that will &lt;code&gt;block_on()&lt;/code&gt; an async block. If inside this future we &lt;code&gt;.await&lt;/code&gt; another future, it will be dealt by the same task, as it is part of the same tree.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second&lt;/strong&gt;, it points to the &lt;a href="https://www.youtube.com/watch?v=ThjvMReOXYM&amp;amp;t=4757s" rel="noopener noreferrer"&gt;threshold between concurrency and parallelism&lt;/a&gt;. If you just &lt;code&gt;.await&lt;/code&gt; or &lt;code&gt;join!&lt;/code&gt; futures, you will never have two Tokio tasks running simultaneously because, at the end, our &lt;code&gt;main()&lt;/code&gt; is &lt;code&gt;.await&lt;/code&gt;ing the root-future, and its node-futures are executed one after the other as part of the same task, hence in the same OS thread. In other words, your async program will have concurrency, but not parallelism. &lt;/p&gt;

&lt;p&gt;Revisiting our example, even if ports &lt;code&gt;8080&lt;/code&gt; and &lt;code&gt;8081&lt;/code&gt; are accessed at the same time, &lt;code&gt;foo()&lt;/code&gt; and &lt;code&gt;bar()&lt;/code&gt; will be executed one after the other because they are &lt;del&gt;fruits&lt;/del&gt; futures of the same tree. Sure, this is no big deal here, but if you remember that we are talking about network applications and, by doing so, extrapolate over this silly example, you will quickly see this cannot be right.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scheduling parallel tasks
&lt;/h3&gt;

&lt;p&gt;As mentioned above, &lt;code&gt;main()&lt;/code&gt; is the entry point of our program, so everything we are doing is below it. And what we have below (what &lt;code&gt;#[tokio::main]&lt;/code&gt; desugars to) is a &lt;code&gt;runtime&lt;/code&gt; that was built using &lt;code&gt;new_multi_thread()&lt;/code&gt;: &lt;em&gt;a multi-threaded Tokio runtime&lt;/em&gt;. So far, we have been using only one of those threads; it is running our task spawned by &lt;code&gt;block_on()&lt;/code&gt;. If we want parallelism, we need to hand our futures to the runtime itself, so they can become a "root-future" and, as such, become new tasks. To achieve such parallelism, that is, to allow the runtime to execute our tasks with a different worker of its thread pool, we got to &lt;code&gt;spawn&lt;/code&gt; the tasks.&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
    &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
    &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&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;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0:8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="nf"&gt;.accept&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_pair&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.try_lock&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;"`foo()` is finished"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;break&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;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&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;"error"&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;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&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;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0:8081"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="nf"&gt;.accept&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_pair&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.try_lock&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;"`bar()` is finished"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;break&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;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&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;"error"&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;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.try_lock&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"f"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="k"&gt;break&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;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;In the example above, &lt;code&gt;foo()&lt;/code&gt; and &lt;code&gt;bar()&lt;/code&gt; become root-futures in their own right, and as &lt;code&gt;handle()&lt;/code&gt; is the single future within the &lt;code&gt;block_on()&lt;/code&gt; future, we end up with three different trees of futures. That way, if we call all three functions at the “same” time, they &lt;strong&gt;can&lt;/strong&gt; be executed in three different threads (assuming the runtime has these threads). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I might have went a little over the top by using &lt;code&gt;Arc&amp;lt;Mutex&amp;lt;HashMap&amp;gt;&amp;gt;&lt;/code&gt;, since it could be dealt with in an easier manner with &lt;a href="https://docs.rs/tokio/0.2.2/tokio/task/struct.JoinHandle.html" rel="noopener noreferrer"&gt;&lt;code&gt;JoinHandle&lt;/code&gt;&lt;/a&gt;. My reasoning was that using the smart pointers made it easier to see the parallelism, as the &lt;code&gt;JoinHandle&lt;/code&gt; &lt;em&gt;looks&lt;/em&gt; very similar to how we use &lt;code&gt;.await&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Going beyond
&lt;/h3&gt;

&lt;p&gt;If you want to go above and beyond, a good place to start is to understand how Tokio employs a work-stealing technique to manage its multithreaded scheduler.&lt;/p&gt;




&lt;h2&gt;
  
  
  Driver
&lt;/h2&gt;

&lt;p&gt;Let us reconsider our previous example. After &lt;code&gt;foo()&lt;/code&gt; and &lt;code&gt;bar()&lt;/code&gt; both yield, which happens once they start listening at &lt;code&gt;0.0.0.0&lt;/code&gt;, they return &lt;code&gt;Poll::Pending&lt;/code&gt;. As there is still work to be done, the scheduler will not get rid of them, but will not &lt;code&gt;poll()&lt;/code&gt; them again autonomously; it will &lt;code&gt;poll()&lt;/code&gt; them again under request. &lt;/p&gt;

&lt;p&gt;In this case, the source of the need to &lt;code&gt;poll()&lt;/code&gt; them again is the access to &lt;code&gt;0.0.0.0&lt;/code&gt;. However, if neither &lt;code&gt;foo()&lt;/code&gt; nor &lt;code&gt;bar()&lt;/code&gt; are actually running, which process will pull the trigger? Something has to be running to mediate our access to &lt;code&gt;0.0.0.0&lt;/code&gt; and the scheduler. That is the role of the &lt;strong&gt;driver&lt;/strong&gt;, which is how Tokio call its &lt;em&gt;I/O event loop&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Before diving into the driver, though, let us talk a bit more about what make it necessary: a pending future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pending future
&lt;/h3&gt;

&lt;p&gt;Maybe this topic belongs to the scheduler, but as it is vital for an understanding of the driver, I think it also fits here.&lt;/p&gt;

&lt;p&gt;When we poll a future, it receives a &lt;code&gt;Context&lt;/code&gt; as an argument. Currently, this &lt;code&gt;Context&lt;/code&gt; is just a wrapper for the &lt;code&gt;&amp;amp;Waker&lt;/code&gt;. This &lt;code&gt;&amp;amp;Waker&lt;/code&gt; is a reference to the &lt;code&gt;Waker&lt;/code&gt; found within the task that called &lt;code&gt;poll()&lt;/code&gt;. This &lt;code&gt;&amp;amp;Waker&lt;/code&gt; has a method &lt;code&gt;wake()&lt;/code&gt; that is called by the driver, so the task (that owns &lt;code&gt;Waker&lt;/code&gt;) becomes aware that it should &lt;code&gt;poll()&lt;/code&gt; the future once again. &lt;/p&gt;

&lt;p&gt;The following flow is an illustrative example of how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A future is &lt;code&gt;.await&lt;/code&gt;ed.&lt;/li&gt;
&lt;li&gt;As such, it is handed to the scheduler task that was created by &lt;code&gt;block_on()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;This task will &lt;code&gt;poll()&lt;/code&gt; the future, which will do some work until it reaches the point where it has to yield; let's say it is listening at some address, as our &lt;code&gt;foo()&lt;/code&gt; was.&lt;/li&gt;
&lt;li&gt;Before yielding, the future &lt;code&gt;clone()&lt;/code&gt; the &lt;code&gt;&amp;amp;Waker&lt;/code&gt; received as an argument in &lt;code&gt;poll()&lt;/code&gt;. That “binds” the future and the task.&lt;/li&gt;
&lt;li&gt;It yields, returning &lt;code&gt;Poll::Pending&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When the operating system's I/O receives a connection on that certain address, it will let the driver know.&lt;/li&gt;
&lt;li&gt;The driver will call &lt;code&gt;wake()&lt;/code&gt; on the &lt;code&gt;&amp;amp;Waker&lt;/code&gt; stored by the future, and this will wake up the task.&lt;/li&gt;
&lt;li&gt;The awoken task will then &lt;code&gt;poll()&lt;/code&gt; the future again. If it returns &lt;code&gt;Pending&lt;/code&gt;, the new &lt;code&gt;Waker&lt;/code&gt; that was passed by this last &lt;code&gt;poll()&lt;/code&gt; will be copied and the process restarts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The 6th and 7th steps describes the role of the driver as an interface between the OS and the task scheduler. This means that the driver* will perform system calls to the OS, such as &lt;code&gt;kqueue&lt;/code&gt; in BSD/macOS, &lt;code&gt;IPCP&lt;/code&gt; in Windows or &lt;code&gt;epoll&lt;/code&gt; in Linux (and now we are hearing more and more about &lt;code&gt;io_uring&lt;/code&gt;, which Tokio handles as well). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;*&lt;/strong&gt; &lt;em&gt;It is not really the driver that makes these system calls. The interaction is actually between the driver and &lt;code&gt;mio&lt;/code&gt;, so it is &lt;code&gt;mio&lt;/code&gt; who interacts with the OS. That being said, I will abstract from it here, so we can depict a simplified conversation between Tokio's driver and the OS I/O, which comprises the 6th step above&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The driver, being an event &lt;em&gt;loop&lt;/em&gt;, will keep polling the OS using one of these system calls. Let us retrieve our &lt;code&gt;foo()&lt;/code&gt; example. If the driver polls the OS and find out that there was a connection at &lt;code&gt;0.0.0.0:8080&lt;/code&gt;, it will then &lt;code&gt;wake()&lt;/code&gt; the task for it to &lt;code&gt;poll()&lt;/code&gt; the future.&lt;/p&gt;

&lt;p&gt;Sure, there is a myriad of details left out. For example, how the communication via &lt;a href="https://tokio.rs/tokio/tutorial/channels" rel="noopener noreferrer"&gt;channels&lt;/a&gt; between the scheduler and the driver actually works? Nevertheless, I will respect the &lt;code&gt;beginners&lt;/code&gt; tag with which I marked this post and stop here. (Even because, if I write posts for beginners, it is not only because I think we still miss more introductory content, but also because of my own current limitations; and here we are teetering on the edge of my knowledge gap 🙃). &lt;/p&gt;




&lt;h2&gt;
  
  
  Timer
&lt;/h2&gt;

&lt;p&gt;The module &lt;code&gt;tokio::time&lt;/code&gt; is part of the runtime and provides utilities for tracking time. I don't have much to talk about these, but I will, for the sake of completion, quote the part of the documentation that explains what this module provides:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Sleep&lt;/code&gt;&lt;/strong&gt; is a future that does no work and completes at a specific &lt;code&gt;Instant&lt;/code&gt; in time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Interval&lt;/code&gt;&lt;/strong&gt; is a stream yielding a value at a fixed period. It is initialized with a &lt;code&gt;Duration&lt;/code&gt; and repeatedly yields each time the duration elapses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Timeout&lt;/code&gt;&lt;/strong&gt;: Wraps a future or stream, setting an upper bound to the amount of time it is allowed to execute. If the future or stream does not complete in time, then it is canceled and an error is returned.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;p&gt;I will stop here for today. I feel there is a lot missing, but this post is already longer than I wanted. Hopefully, we will be able to revisit some topics as we move on to talk about the other crates.&lt;/p&gt;

&lt;p&gt;See you there!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/photos/4u2U8EO9OzY" rel="noopener noreferrer"&gt;Pawel Nolbert&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>tokio</category>
      <category>runtime</category>
    </item>
    <item>
      <title>Asynchronous Rust: basic concepts</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Sun, 29 Aug 2021 20:56:01 +0000</pubDate>
      <link>https://dev.to/rogertorres/asynchronous-rust-basic-concepts-44ed</link>
      <guid>https://dev.to/rogertorres/asynchronous-rust-basic-concepts-44ed</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;TL;DR: I will try to give an easy-to-understand account of some concepts surrounding asynchronous Rust: async, await, Future, Poll, Context, Waker, Executor and Reactor.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As with most things I write here, we already have good content related to asynchronous Rust. Let me mention a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://rust-lang.github.io/async-book"&gt;&lt;em&gt;Asynchronous Programming in Rust&lt;/em&gt;&lt;/a&gt;, a.k.a. &lt;em&gt;async book&lt;/em&gt;; incomplete, but great.&lt;/li&gt;
&lt;li&gt;Steve's talks on &lt;a href="https://www.youtube.com/watch?v=lJ3NC-R3gSI"&gt;Rust's Journey to async/await&lt;/a&gt; and on &lt;a href="https://www.youtube.com/watch?v=NNwK5ZPAJCk"&gt;how it works&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Without Boats' &lt;a href="https://without.boats/blog/await-decision/"&gt;proposal for await syntax&lt;/a&gt; (the other entries with the tags &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;Future&lt;/code&gt; are also excellent).&lt;/li&gt;
&lt;li&gt;Jon's stream on &lt;a href="https://www.youtube.com/watch?v=9_3krAQtD2k"&gt;how Futures and async/await works&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this amount of superb information, why writing about it? My answer here is the same for &lt;del&gt;almost&lt;/del&gt; every other entry on my DEV blog: to reach an audience for which this content is still a bit too hard to grasp.&lt;/p&gt;

&lt;p&gt;So, if you want something in a more intermediary level, go straight to the content listed above. Otherwise, let's go :)&lt;/p&gt;




&lt;h2&gt;
  
  
  async/.await
&lt;/h2&gt;

&lt;p&gt;Asynchronous Rust (async Rust, for short) is delivered through the &lt;code&gt;async/.await&lt;/code&gt; syntax. It means that these two keywords (&lt;code&gt;async&lt;/code&gt; and &lt;code&gt;.await&lt;/code&gt;) are the centerpieces of writing async Rust. But what is async Rust?&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;async book&lt;/em&gt; states that async is a &lt;em&gt;concurrent programming model&lt;/em&gt;. Concurrent means that different tasks will perform their activities alternatively; e.g., task A does a bit of work, hands the thread over to task B, who works a little and give it back, etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Do not confuse it with parallel programming, where different tasks are running&lt;/em&gt; simultaneously. &lt;em&gt;You &lt;strong&gt;can&lt;/strong&gt; combine concurrent and parallel programmin (e.g., by spawning futures), but I will not cover it here since &lt;code&gt;async/.await&lt;/code&gt; is used to enable&lt;/em&gt; concurrent &lt;em&gt;programming, so that is my focus here.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short, we use the &lt;code&gt;async&lt;/code&gt; keyword to tell Rust that a block or a function is going to be asynchronous.&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="c1"&gt;// asynchronous block&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// asynchronous function&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what does it mean &lt;strong&gt;for a Rust program&lt;/strong&gt; to be asynchronous? It means that it will return an implementation of the &lt;code&gt;Future&lt;/code&gt; trait. I will cover &lt;code&gt;Future&lt;/code&gt; in the next section; for now, it is enough to say that a &lt;code&gt;Future&lt;/code&gt; represents a value that may or may not be ready.&lt;/p&gt;

&lt;p&gt;We handle a &lt;code&gt;Future&lt;/code&gt; that is returned by an async block/function with the &lt;code&gt;.await&lt;/code&gt; keyword. Consider the silly example below:&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;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;bar&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// it is possible to .await only inside async fn or block&lt;/span&gt;
    &lt;span class="k"&gt;async&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;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&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;In this case, &lt;code&gt;x&lt;/code&gt; is not &lt;code&gt;i32&lt;/code&gt;, but the implementation of the &lt;code&gt;Future&lt;/code&gt; trait (&lt;code&gt;impl Future&amp;lt;Output = i32&amp;gt;&lt;/code&gt; in this case). The variable &lt;code&gt;y&lt;/code&gt; on the other hand, will be a &lt;code&gt;i32&lt;/code&gt;: &lt;strong&gt;11&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Other way to visualize this is to understand that Rust will &lt;em&gt;desugar&lt;/em&gt; this&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;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into something like this&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;fn&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, there is no asynchronous anything happening here. But if &lt;code&gt;foo()&lt;/code&gt; was complex, having to wait for &lt;a href="https://dev.to/rogertorres/smart-pointers-in-rust-what-why-and-how-oma"&gt;&lt;code&gt;Mutex&lt;/code&gt;&lt;/a&gt; locks or is listening to a network connection, instead of holding the thread for the whole time, Rust would do as much progress as possible on &lt;code&gt;foo()&lt;/code&gt; and then yields the thread to do something else, taking it back when it could do more work. &lt;/p&gt;

&lt;p&gt;Hopefully, it will make sense after we go through concepts like &lt;code&gt;Future&lt;/code&gt;, &lt;code&gt;Poll&lt;/code&gt; and &lt;code&gt;Wake&lt;/code&gt;. For now, it is enough that you have a general idea of the use of both &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Be sure to read the &lt;a href="https://rust-lang.github.io/async-book/01_getting_started/04_async_await_primer.html"&gt;async/.await Primer&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Futures
&lt;/h2&gt;

&lt;p&gt;I think it is not an exaggeration to say that the &lt;code&gt;Future&lt;/code&gt; trait is the heart of async Rust. &lt;/p&gt;

&lt;p&gt;A &lt;code&gt;Future&lt;/code&gt; is a trait that has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;Output&lt;/code&gt; type (&lt;code&gt;i32&lt;/code&gt; in the example above).&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;poll&lt;/code&gt; function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;poll()&lt;/code&gt; is a function that does as much work as it can, and then returns an enum called &lt;code&gt;Poll&lt;/code&gt;:&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;enum&lt;/span&gt; &lt;span class="n"&gt;Poll&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Pending&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;As you can see, my description of &lt;code&gt;.await&lt;/code&gt; and &lt;code&gt;poll()&lt;/code&gt; kind of overlap. That's because calling &lt;code&gt;.await&lt;/code&gt; will eventually call &lt;code&gt;poll()&lt;/code&gt;. More on this later.&lt;/p&gt;

&lt;p&gt;This enum is the representation of what I wrote earlier, that a Future represents a value that may or may not be ready.&lt;/p&gt;

&lt;p&gt;The general idea behind this function is simple: when someone calls &lt;code&gt;poll()&lt;/code&gt; on a future, if it went all the way through completion, it returns &lt;code&gt;Ready(T)&lt;/code&gt; and the &lt;code&gt;.await&lt;/code&gt; will return &lt;code&gt;T&lt;/code&gt;. Otherwise, it will return &lt;code&gt;Pending&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The question is, if it returns &lt;code&gt;Pending&lt;/code&gt;, how do we get back at it, so it can keep working towards completion? The short answer is the &lt;em&gt;reactor&lt;/em&gt;. However, we have some ground to cover before getting there.&lt;/p&gt;




&lt;h2&gt;
  
  
  Poll, Context, Waker, Executor and Reactor
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lots of words!&lt;/strong&gt; But I honestly think it is easier to bundle everything together because it is easier to understand what they do in context. And to illustrate this, I came up with a simplified hypothetical scenario.&lt;/p&gt;

&lt;p&gt;Suppose we have a &lt;code&gt;Future&lt;/code&gt; created via &lt;code&gt;async&lt;/code&gt; keyword. Let's remember what a Future is:&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="nd"&gt;#[must_use&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"futures do nothing unless you `.await` or poll them"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;poll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Pin&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Poll&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="o"&gt;&amp;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;blockquote&gt;
&lt;p&gt;&lt;em&gt;I will not cover&lt;/em&gt; &lt;code&gt;Pin&lt;/code&gt; &lt;em&gt;here, as it is somewhat complex and not necessary to understand what is going on here.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As hinted by the code above, futures in Rust are lazy, which means that just declaring them will not make them run.&lt;/p&gt;

&lt;p&gt;Now, let's say we run the future using &lt;code&gt;.await&lt;/code&gt;. "Run" here means delivering it to an "executor" that will call &lt;code&gt;poll()&lt;/code&gt; in the future. &lt;/p&gt;

&lt;p&gt;But what is the executor? Oversimplifying, it is a schedule algorithm that will actually poll the futures. So, when you call &lt;code&gt;.await&lt;/code&gt;, who are going to do the work is an executor.&lt;/p&gt;

&lt;p&gt;Ok, we called &lt;code&gt;.await&lt;/code&gt;, the future was polled and returned &lt;code&gt;Ready&amp;lt;T&amp;gt;&lt;/code&gt;. What happens? The &lt;code&gt;.await&lt;/code&gt; will return &lt;code&gt;T&lt;/code&gt; and the executor will get rid of the future, so it does not get polled again.&lt;/p&gt;

&lt;p&gt;Alternatively, if the polled future wasn't able to do all the work, it will return &lt;code&gt;Pending&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;After receiving &lt;code&gt;Pending&lt;/code&gt;, the executor will not poll the future again until it is told so. And who is going to tell him? The "reactor". It will call the &lt;code&gt;wake()&lt;/code&gt; function on the &lt;code&gt;Waker&lt;/code&gt; that was passed as an argument in the &lt;code&gt;poll()&lt;/code&gt; function. That allows the executor to know that the associated task is ready to move on. &lt;/p&gt;

&lt;p&gt;But what is the reactor? It is the executor's brother. While the executor is on the Olympus, managing things, listening to &lt;del&gt;prayers&lt;/del&gt; &lt;code&gt;.await&lt;/code&gt;s, the reactor is on the Hades, working alongside the system I/O, doing the heavy lifting. It is the reactor that will know the best time to &lt;code&gt;poll&lt;/code&gt; that future again, and it will do so calling &lt;code&gt;wake()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, should you, just starting to read Rust async stuff, worry about how executor and the reactor work behind the scene? Not really. Why? Because when we talk about executor and reactor we are already talking about runtimes; and when we talk about runtimes we are usually talking about &lt;a href="https://tokio.rs/"&gt;Tokio&lt;/a&gt;. In fact, calling it by the names &lt;a href="https://docs.rs/tokio/0.1.22/tokio/executor/index.html"&gt;executor&lt;/a&gt; and &lt;a href="https://docs.rs/tokio/0.1.22/tokio/reactor/index.html"&gt;reactor&lt;/a&gt; is already adhering to Tokio nomenclatures. So, at the end, all you have to do is incorporate Tokio on your project. The usual way to do this is using its procedural macro before the &lt;code&gt;main&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="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="c1"&gt;// your async code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Still about the reactor, &lt;a href="https://www.youtube.com/watch?v=9_3krAQtD2k&amp;amp;t=3004s"&gt;Jon spent 45 minutes explaining this while drawing on a blackboard,&lt;/a&gt; and I will not pretend I can do a better job. So, if you want to dive into this level of detail, check the link above.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Let us recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;async&lt;/code&gt; is used to create an asynchronous block or function, making it return a &lt;code&gt;Future&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.await&lt;/code&gt; will wait for the completion of the future and eventually give back the value (or an error, which is why it is common to use the &lt;a href="https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator"&gt;question mark operator&lt;/a&gt; in &lt;code&gt;.await?&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Future&lt;/code&gt; is the representation of an asynchronous computation, a value that may or may not be ready, something that is represented by the variants of the &lt;code&gt;Poll&lt;/code&gt; enum.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Poll&lt;/code&gt; is the enum returned by a future, whose variants can be either &lt;code&gt;Ready&amp;lt;T&amp;gt;&lt;/code&gt; or &lt;code&gt;Pending&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;poll()&lt;/code&gt; is the function that works the future towards its completion. It receives a &lt;code&gt;Context&lt;/code&gt; as a parameter and is called by the executor.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Context&lt;/code&gt; is a wrapper for &lt;code&gt;Waker&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Waker&lt;/code&gt; is a type that contains a &lt;code&gt;wake()&lt;/code&gt; function that will be called by the &lt;strong&gt;reactor&lt;/strong&gt;, telling the &lt;strong&gt;executor&lt;/strong&gt; that it may poll the future again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Executor&lt;/strong&gt; is a scheduler that executes the futures by calling &lt;code&gt;poll()&lt;/code&gt; repeatedly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reactor&lt;/strong&gt; is something like an event loop responsible for waking up the pending futures.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Ok, there is certainly more to talk about, such as the &lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt; traits, &lt;code&gt;Pinning&lt;/code&gt; and so on, but I think that, for a beginner post, we had enough.&lt;/p&gt;

&lt;p&gt;See you next time!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover art by &lt;a href="https://unsplash.com/photos/9AxFJaNySB8"&gt;TK&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Edit — Sep, 1st, 2021&lt;/strong&gt;: I made some changes, as I realized my effort to simplify some things made them sound just wrong. This problem might still haunt the text here and there, so if you read something where I sacrificed correctness in favor of simplicity, &lt;strong&gt;please&lt;/strong&gt; call me out.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Rust BDD tests with Cucumber</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Wed, 04 Aug 2021 14:31:01 +0000</pubDate>
      <link>https://dev.to/rogertorres/rust-bdd-with-cucumber-4p68</link>
      <guid>https://dev.to/rogertorres/rust-bdd-with-cucumber-4p68</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This post is out of date.&lt;/strong&gt; The &lt;code&gt;cucumber&lt;/code&gt; crate version used here is obsolete. Fortunately, the new version is not only better, but also easier to use and has excellent documentation, which you can find &lt;a href="https://cucumber-rs.github.io/cucumber/current/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Cucumber&lt;/strong&gt; is a tool for &lt;em&gt;behavior-driven development&lt;/em&gt; (BDD) that uses a language called &lt;strong&gt;Gherkin&lt;/strong&gt; to specify test scenarios with a syntax that is very close to natural language, using key-words such as &lt;code&gt;When&lt;/code&gt; and &lt;code&gt;Then&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here I will not explain the particularities of neither Cucumber nor Gherkin. My goal is to just show you how to use them with Rust. If you know nothing about them, I recommend you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Watch this &lt;a href="https://www.youtube.com/watch?v=lC0jzd8sGIA" rel="noopener noreferrer"&gt;soft introduction&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Refer to the &lt;a href="https://cucumber.io/docs/cucumber/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, specially the &lt;a href="https://cucumber.io/docs/gherkin/reference/" rel="noopener noreferrer"&gt;Gherkin reference guide&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That being said, the examples I am using are elementary, so you should have no problem following along even if you have never seen Cucumber and Gherkin before.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sample project
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The code used in this tutorial can be found &lt;a href="https://github.com/rogertorres/dev.to/tree/main/cucumber"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To focus on how to use Cucumber with Rust, I decided to code a dummy multiplication function, so you don't get distracted by the idiosyncrasies of a particular project.&lt;/p&gt;

&lt;p&gt;First, create a library crate:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ cargo new --lib bdd


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then, remove the mod &lt;code&gt;tests&lt;/code&gt; from &lt;code&gt;lib.rs&lt;/code&gt; and code this:&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;mult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And that's all for &lt;code&gt;lib.rs&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting up the manifest
&lt;/h2&gt;

&lt;p&gt;The manifest (&lt;code&gt;Cargo.toml&lt;/code&gt;) require these entries:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;

&lt;span class="nn"&gt;[[test]]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cucumber"&lt;/span&gt;
&lt;span class="py"&gt;harness&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;tokio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.9.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"rt-multi-thread"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"macros"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nn"&gt;[dev-dependencies]&lt;/span&gt;
&lt;span class="py"&gt;cucumber_rust&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.9"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In &lt;code&gt;[[test]]&lt;/code&gt; we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;, which is the name of the &lt;code&gt;.rs&lt;/code&gt; file where we will code the tests, &lt;code&gt;cucumber.rs&lt;/code&gt; in this case.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;harness&lt;/code&gt; is set to false, allowing us to provide our own &lt;code&gt;main&lt;/code&gt; function to handle the test run. This &lt;code&gt;main&lt;/code&gt; function will be placed inside the &lt;code&gt;.rs&lt;/code&gt; file specified above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;code&gt;[dependencies]&lt;/code&gt; we have &lt;code&gt;tokio&lt;/code&gt;, which is an &lt;em&gt;async&lt;/em&gt; runtime required to work with cucumber-rust (even if you are not testing anything &lt;em&gt;async&lt;/em&gt;). You may use another runtime.&lt;/p&gt;

&lt;p&gt;And in &lt;code&gt;[dev-dependencies]&lt;/code&gt; we have &lt;code&gt;cucumber_rust&lt;/code&gt;, the star of this show.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;

&lt;p&gt;We have to create a couple of files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tests/cucumber.rs&lt;/code&gt;, where we will have the &lt;code&gt;main&lt;/code&gt; function that will run the tests.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;features/operations.feature&lt;/code&gt;, where we will code our test scenario using Gherkin.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end, we have this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

bdd
├── features
│   └── operations.feature
├── src
│   └── lib.rs
├── tests
│   └── cucumber.rs
└── Cargo.toml


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Coding the test with Gherkin
&lt;/h2&gt;

&lt;p&gt;This is how the &lt;code&gt;operation.feature&lt;/code&gt; file looks like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;

&lt;span class="kd"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Arithmetic operations

  &lt;span class="c"&gt;# Let's start with addition. BTW, this is a comment.&lt;/span&gt;
  &lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; User wants to multiply two numbers
    &lt;span class="nf"&gt;Given &lt;/span&gt;the numbers &lt;span class="s"&gt;"2"&lt;/span&gt; and &lt;span class="s"&gt;"3"&lt;/span&gt;
    &lt;span class="nf"&gt;When &lt;/span&gt;the User adds them
    &lt;span class="nf"&gt;Then &lt;/span&gt;the User gets 6 as result


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here we have a context set by &lt;code&gt;Given&lt;/code&gt;, an event described by &lt;code&gt;When&lt;/code&gt; and an expected result expressed by &lt;code&gt;Then&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Although my purpose is not to teach Cucumber, I have to say that this is &lt;strong&gt;not&lt;/strong&gt; a good BDD scenario. Not so much because it is dead simple, but because it is a unit test in disguise. I have, nevertheless, kept it here because it has the virtue of making things crystal clear regarding how we are going to interpret this scenario with Rust. For best practices, check &lt;a href="https://support.smartbear.com/cucumberstudio/docs/tests/best-practices.html#testing-process-write-test-scenarios-at-early-st" rel="noopener noreferrer"&gt;this&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Handle the scenario with Rust
&lt;/h2&gt;

&lt;p&gt;From now on, we stick with &lt;a href="https://twitter.com/lunasorcery/status/1402372190033563650" rel="noopener noreferrer"&gt;&lt;del&gt;the mighty Crabulon&lt;/del&gt;&lt;/a&gt; Rust.&lt;/p&gt;

&lt;h3&gt;
  
  
  World object
&lt;/h3&gt;

&lt;p&gt;The first thing we need is a &lt;code&gt;World&lt;/code&gt;, an object that will hold the state of our test during execution.&lt;/p&gt;

&lt;p&gt;Let's start coding &lt;code&gt;cucumber.rs&lt;/code&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;use&lt;/span&gt; &lt;span class="nn"&gt;cucumber_rust&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;async_trait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Cucumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;MyWorld&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Init&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[async_trait(&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="nd"&gt;Send)]&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;MyWorld&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;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="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Init&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;For now, we created an &lt;code&gt;enum&lt;/code&gt; named &lt;code&gt;MyWorld&lt;/code&gt; that will be our "World object", holding the data between steps. &lt;code&gt;Init&lt;/code&gt; is its initial value.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;MyWorld&lt;/code&gt; object implements the trait &lt;code&gt;World&lt;/code&gt; provided by the &lt;code&gt;cucumber_rust&lt;/code&gt;, which in turn gives us the methods to map the steps (&lt;code&gt;Given&lt;/code&gt;, &lt;code&gt;When&lt;/code&gt;, &lt;code&gt;Then&lt;/code&gt;, etc.). &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Error&lt;/code&gt; type is a requirement from this trait, as is the attribute &lt;code&gt;#[async_trait(?Send)]&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step builder
&lt;/h3&gt;

&lt;p&gt;Now it is time to actually code the interpreter. I will explain the code block by block, so it might be useful to also have the &lt;a href="https://github.com/rogertorres/dev.to/blob/main/cucumber/tests/cucumber.rs"&gt;complete code&lt;/a&gt; open, so you don't lose sight of the whole picture.&lt;/p&gt;

&lt;h4&gt;
  
  
  Given
&lt;/h4&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;test_steps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MyWorld&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;cucumber_rust&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Steps&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;bdd&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Steps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyWorld&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Steps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyWorld&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;Steps&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.given_regex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="c1"&gt;// This will match the "given" of multiplication&lt;/span&gt;
            &lt;span class="s"&gt;r#"^the numbers "(\d)" and "(\d)"$"#&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="c1"&gt;// and store the values inside context, &lt;/span&gt;
            &lt;span class="c1"&gt;// which is a Vec&amp;lt;String&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_world&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// With regex we start from [1]&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;MyWorld&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="py"&gt;.matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="py"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="py"&gt;.matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="py"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&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;span class="n"&gt;world&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// The rest of the code will go here.&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;After declaring the &lt;code&gt;mod&lt;/code&gt;, we created our &lt;code&gt;builder&lt;/code&gt;, a &lt;code&gt;Steps&lt;/code&gt; struct that will store our steps.&lt;/p&gt;

&lt;p&gt;The crate &lt;code&gt;cucumber_rust&lt;/code&gt; provides three variations for the main Gherkin prefixes (&lt;code&gt;Given&lt;/code&gt;, &lt;code&gt;When&lt;/code&gt;, &lt;code&gt;Then&lt;/code&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The "normal" one that matches fixed values (e.g. &lt;code&gt;when()&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;regex&lt;/em&gt; version that parses the &lt;em&gt;regex&lt;/em&gt; input (e.g. &lt;code&gt;when_regex()&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;async&lt;/em&gt; version to handle &lt;em&gt;async&lt;/em&gt; tests, something I am not covering here (e.g. &lt;code&gt;when_async()&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;async&lt;/em&gt;+&lt;em&gt;regex&lt;/em&gt;, which is a combination of the last two (e.g. &lt;code&gt;when_regex_async()&lt;/code&gt;), also not covered here.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am using &lt;code&gt;given_regex()&lt;/code&gt; to parse the two numbers. Remember that in &lt;code&gt;operations.feature&lt;/code&gt; I specified this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;

&lt;span class="nf"&gt;Given &lt;/span&gt;the numbers &lt;span class="s"&gt;"2"&lt;/span&gt; and &lt;span class="s"&gt;"3"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When you call a step function such as &lt;code&gt;given_regex()&lt;/code&gt; you get a &lt;a href="https://doc.rust-lang.org/rust-by-example/fn/closures.html" rel="noopener noreferrer"&gt;closure&lt;/a&gt; containing the &lt;code&gt;World&lt;/code&gt; object and a &lt;code&gt;Context&lt;/code&gt;. The latter have a field called &lt;code&gt;matches&lt;/code&gt; that is a &lt;code&gt;Vec&amp;lt;String&amp;gt;&lt;/code&gt; containing the &lt;em&gt;regex&lt;/em&gt; matches (if you're not using a &lt;code&gt;_regex&lt;/code&gt; step, the Vector will be empty). In this case, as I am using &lt;em&gt;regex&lt;/em&gt;, it has three values: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[0] has the entire match, &lt;code&gt;the numbers "2" and "3"&lt;/code&gt; in this case.&lt;/li&gt;
&lt;li&gt;[1] has the first group, &lt;code&gt;2&lt;/code&gt; in this case.&lt;/li&gt;
&lt;li&gt;[2] has the first group, &lt;code&gt;3&lt;/code&gt; in this case.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This is the &lt;em&gt;regex&lt;/em&gt; "normal" behavior. If you are not familiar with &lt;em&gt;regex&lt;/em&gt;, &lt;a href="https://www.youtube.com/watch?v=sa-TUpSx1JA" rel="noopener noreferrer"&gt;this is a good intro&lt;/a&gt; (thank you YouTube for holding my &lt;em&gt;watch history&lt;/em&gt; for so long).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With these values, I return my &lt;code&gt;World&lt;/code&gt; object now set as &lt;code&gt;Input&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before we move to &lt;code&gt;when&lt;/code&gt;, I have two quick remarks to make:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I am not checking the &lt;code&gt;unrwap()&lt;/code&gt; because the &lt;em&gt;regex&lt;/em&gt; is only catching numbers with &lt;code&gt;(\d)&lt;/code&gt;. Sometimes you might want to capture everything with something like &lt;code&gt;(.*)&lt;/code&gt; and validate the content inside your code.&lt;/li&gt;
&lt;li&gt;If you want to change your &lt;code&gt;World&lt;/code&gt; object (for example, if it is a struct holding multiple values and/or states), just place &lt;code&gt;mut&lt;/code&gt; before &lt;code&gt;world&lt;/code&gt; in the closure, and you will get a mutable object.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"the User multiply them"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;|{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;MyWorld&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;MyWorld&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&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="nn"&gt;MyWorld&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&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;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This one is very straightforward. I use &lt;code&gt;match&lt;/code&gt; to get the &lt;code&gt;enum&lt;/code&gt; inner value, multiply both inputs and return the World object with a new value.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;mult&lt;/code&gt; is ratter useless, but it has a role to play here: to show you how to import what we declared within the library crate.&lt;/p&gt;

&lt;h4&gt;
  
  
  Then
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;


&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.then_regex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;r#"^the User gets "(\d)" as result$"#&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;|{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;MyWorld&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="py"&gt;.matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid world state"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="nn"&gt;MyWorld&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Init&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here I use &lt;em&gt;regex&lt;/em&gt; again to compare the value that was calculated in the &lt;code&gt;Then&lt;/code&gt; step with the value provided by Gherkin (which is, as I said, a very suspicious BDD scenario). &lt;/p&gt;

&lt;p&gt;At the very end, I return &lt;code&gt;builder&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The substitute &lt;code&gt;main&lt;/code&gt; function
&lt;/h2&gt;

&lt;p&gt;After the &lt;code&gt;mod&lt;/code&gt;, we declare our &lt;code&gt;main&lt;/code&gt; function:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;Cucumber&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyWorld&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.features&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"./features"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="nf"&gt;.steps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;test_steps&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.run_and_exit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here we are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating a &lt;code&gt;World&lt;/code&gt; object&lt;/li&gt;
&lt;li&gt;Pointing to the &lt;code&gt;.feature&lt;/code&gt; file containing the Gherkin test.&lt;/li&gt;
&lt;li&gt;Adding the steps defined with &lt;code&gt;cucumber_rust&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Running and exiting once it is done.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;await&lt;/code&gt; because &lt;code&gt;cucumber_rust&lt;/code&gt; requires the whole thing to be &lt;em&gt;async&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! To test it, all you have to do is to run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ cargo test


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Rust will run the &lt;code&gt;main&lt;/code&gt; function found in the file specified in the manifest: &lt;code&gt;cucumber.rs&lt;/code&gt;. This is the result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fd6euyxd80lhvblcfyqwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fd6euyxd80lhvblcfyqwj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recommend you to mess with the values and run the tests, so you can see how the errors are captured.&lt;/p&gt;




&lt;p&gt;Much more can be done with &lt;code&gt;cucumber_rust&lt;/code&gt;. I hope this tutorial helps you get started with it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover image by &lt;em&gt;&lt;a href="https://unsplash.com/photos/4jqhNG5SDtU" rel="noopener noreferrer"&gt;Roman Fox&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>cucumber</category>
      <category>testing</category>
      <category>beginners</category>
    </item>
    <item>
      <title>First steps with Rust declarative macros!</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Mon, 26 Jul 2021 14:09:13 +0000</pubDate>
      <link>https://dev.to/rogertorres/first-steps-with-rust-declarative-macros-1f8m</link>
      <guid>https://dev.to/rogertorres/first-steps-with-rust-declarative-macros-1f8m</guid>
      <description>&lt;p&gt;Macros are one of the ways to extend Rust syntax. As &lt;a href="https://doc.rust-lang.org/book/ch19-06-macros.html"&gt;&lt;em&gt;The Book&lt;/em&gt;&lt;/a&gt; calls it, “a way of writing code that writes other code”. Here, I will talk about &lt;em&gt;declarative macros&lt;/em&gt;, or as it is also called, &lt;em&gt;macros by example&lt;/em&gt;. Examples of declarative macros are &lt;code&gt;vec!&lt;/code&gt;, &lt;code&gt;println!&lt;/code&gt; and &lt;code&gt;format!&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The macros I will &lt;strong&gt;not&lt;/strong&gt; talk about are the &lt;em&gt;procedural macros&lt;/em&gt;, but you can read about them &lt;a href="https://doc.rust-lang.org/reference/procedural-macros.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As usual, &lt;strong&gt;I am writing for beginners&lt;/strong&gt;. If you want to jump to the next level, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;The Book's&lt;/em&gt; &lt;a href="https://doc.rust-lang.org/book/ch19-06-macros.html"&gt;section on macros&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The chapter about macros in &lt;a href="https://doc.rust-lang.org/reference/macros.html"&gt;&lt;em&gt;Rust by Example&lt;/em&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://danielkeep.github.io/tlborm/book/README.html"&gt;&lt;em&gt;The Little Book of Rust Macros&lt;/em&gt;&lt;/a&gt;, which is the most complete material I found about the topic (the second chapter is specially amusing).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why do I need macros?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The actual coding start in the next section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Declarative macros (from now on, just “macros”) are not functions, but it would be silly to deny the resemblance. Like functions, we use them to perform actions that would otherwise require too many lines of code or quirky commands (I am thinking about &lt;code&gt;vec!&lt;/code&gt; and &lt;code&gt;println!&lt;/code&gt;, respectively). These are (two of) the reasons to &lt;em&gt;use&lt;/em&gt; macros, but what about the reasons to &lt;em&gt;create&lt;/em&gt; them? &lt;/p&gt;

&lt;p&gt;Well, maybe you are developing a crate and want to offer this feature to the users, like warp did with &lt;a href="https://docs.rs/warp/0.1.20/warp/macro.path.html"&gt;&lt;code&gt;path!&lt;/code&gt;&lt;/a&gt;. Or maybe you want to use a macro as a boilerplate, so you don't have to create several similar functions, as I did &lt;a href="https://github.com/rogertorres/mtgsdk/blob/main/src/cards.rs#L197"&gt;here&lt;/a&gt;. It might be also the case that you need something that cannot be delivered by usual Rust syntax, like a function with initial values or structurally different parameters (such as &lt;code&gt;vec!&lt;/code&gt;, that allows calls like &lt;code&gt;vec![2,2,2]&lt;/code&gt; or &lt;code&gt;vec![2;3]&lt;/code&gt;—more on this later).&lt;/p&gt;

&lt;p&gt;That being said, I believe that the best approach is to learn how to use them, try them a few times, and when the time comes when they might be useful, you will remember this alternative.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Declaring macros
&lt;/h2&gt;

&lt;p&gt;This is how you declare a macro:&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;etwas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;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;You could call this macro with the commands &lt;code&gt;etwas!()&lt;/code&gt;, &lt;code&gt;etwas![]&lt;/code&gt; or &lt;code&gt;etwas!{}&lt;/code&gt;. There's no way to force one of those. When we call a macro always using one or the other—like parenthesis in &lt;code&gt;println!("text")&lt;/code&gt; or square-brackets in &lt;code&gt;vec![]&lt;/code&gt;—it is just a convention of usage (a convention that we should keep).&lt;/p&gt;

&lt;p&gt;But what is happening in this macro? Nothing. Let's add something to make it easier to visualize its structure:&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;double&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value:expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;double!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&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;The left side of &lt;code&gt;=&amp;gt;&lt;/code&gt; is the &lt;strong&gt;matcher&lt;/strong&gt;, the rules that define what the macro can receive as input. The right side is the &lt;strong&gt;transcriber&lt;/strong&gt;, the output processing. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not very important, but both matcher and transcriber could be writen using either &lt;code&gt;()&lt;/code&gt;, &lt;code&gt;[]&lt;/code&gt; or &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The matching
&lt;/h2&gt;

&lt;p&gt;This will become clear later, but let me tell you right the way: the matching resembles &lt;a href="https://en.wikipedia.org/wiki/Regular_expression"&gt;regex&lt;/a&gt;. You may ask for specific arguments, fixed values, define acceptable repetition, etc. If you are familiar with it, you should have no problems picking this up.&lt;/p&gt;

&lt;p&gt;Let's go through the most important things you should know about the matching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Variable argument
&lt;/h3&gt;

&lt;p&gt;Variable arguments begin with &lt;code&gt;$&lt;/code&gt; (e.g., &lt;code&gt;$value:expr&lt;/code&gt;). Their structure is: &lt;code&gt;$&lt;/code&gt; &lt;code&gt;name&lt;/code&gt; &lt;code&gt;:&lt;/code&gt; &lt;code&gt;designator&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both &lt;code&gt;$&lt;/code&gt; and &lt;code&gt;:&lt;/code&gt; are fixed.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;name&lt;/code&gt; follows Rust variables convention. When used in the transcriber (see below), they will be called &lt;em&gt;metavariables&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Designators are &lt;strong&gt;not&lt;/strong&gt; variable types. You may think of them as “syntax categories”. Here, I will stick with &lt;a href="https://doc.rust-lang.org/reference/expressions.html"&gt;expressions&lt;/a&gt; (&lt;code&gt;expr&lt;/code&gt;), since Rust is &lt;a href="https://doc.rust-lang.org/reference/statements-and-expressions.html"&gt;“primarily an expression language”&lt;/a&gt;. A list of possible designators can be found &lt;a href="https://doc.rust-lang.org/reference/macros-by-example.html#metavariables"&gt;here&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; There seems to be no consensus on the name "designator". &lt;a href="https://danielkeep.github.io/tlborm/book/mbe-min-captures-and-expansion-redux.html"&gt;The little book&lt;/a&gt; calls it "capture"; &lt;a href="https://doc.rust-lang.org/reference/macros-by-example.html"&gt;The Rust reference&lt;/a&gt; calls it "fragment-specifier"; and you will also find people referring them as "types". Just be aware of that when jumping from source to source. Here, I will stick with designator, as proposed in &lt;a href="https://doc.rust-lang.org/rust-by-example/macros/designators.html"&gt;Rust by example&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Fixed arguments
&lt;/h3&gt;

&lt;p&gt;No mystery here. Just add them without &lt;code&gt;$&lt;/code&gt;. For example:&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;power&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value:expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;squared&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&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;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;power!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3_i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;squared&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;I know there are things here that I have not explained yet. I will talk about them now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separator
&lt;/h3&gt;

&lt;p&gt;Some designators require some specific follow up. Expressions require one of these:  &lt;code&gt;=&amp;gt;&lt;/code&gt;, &lt;code&gt;,&lt;/code&gt; or &lt;code&gt;;&lt;/code&gt;. That is why I had to add a comma between &lt;code&gt;$value:expr&lt;/code&gt; and the fixed-value &lt;code&gt;squared&lt;/code&gt;. You will find a complete list of follow-ups &lt;a href="https://danielkeep.github.io/tlborm/book/mbe-min-captures-and-expansion-redux.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple matching
&lt;/h3&gt;

&lt;p&gt;What if we want our macro to not only calculate a number squared, but also a number cubed? We do this:&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;power&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value:expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;squared&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2_i32&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;span class="nv"&gt;$value:expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cubed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3_i32&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;Multiple matching can be used to capture different levels of specificity. Usually, you will want to write the matching rules from the most-specific to the least-specific, so your call doesn't fall in the wrong matching. A more technical explanation can be found &lt;a href="https://danielkeep.github.io/tlborm/book/mbe-min-captures-and-expansion-redux.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repetition
&lt;/h3&gt;

&lt;p&gt;Most macros that we use allow for a flexible number of inputs. For example, we may call &lt;code&gt;vec![2]&lt;/code&gt; or &lt;code&gt;vec![1, 2, 3]&lt;/code&gt;. This is where the matching resembles Regex the most. Basically, we wrap the variable inside &lt;code&gt;$()&lt;/code&gt; and follow up with a repetition operator:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; — indicates any number of repetitions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; — indicates any number, but at least one.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;?&lt;/code&gt; — indicates an optional, with zero or one occurrence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's say we want to add &lt;code&gt;n&lt;/code&gt; numbers. We need at least two addends, so we will have a single first value, and one or more (&lt;code&gt;+&lt;/code&gt;) second value. This is what such a matching would look like.&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;adder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$left:expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$right:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;adder!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&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;We will work on the transcriber latter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repetition separator
&lt;/h3&gt;

&lt;p&gt;As you can see in the example above, I added a comma before the repetition operator &lt;code&gt;+&lt;/code&gt;.  That's how we add a separator for each repetition without a trailing separator. But what if we want a trailing separator? Or maybe we want it to be flexible, allowing the user to have a trailing separator or not? You may have any of the three possibilities like this:&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;no_trailing&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;with_trailing&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e:expr&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;either&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(,)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;no_trailing!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;with_trailing!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,);&lt;/span&gt;
    &lt;span class="nd"&gt;either!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;either!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&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;h3&gt;
  
  
  Versatility
&lt;/h3&gt;

&lt;p&gt;Unlike functions, you may pass rather different arguments to macros. Let's consider the &lt;code&gt;vec!&lt;/code&gt; macro example. For that, I will omit the transcriber.&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;vec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$elem:expr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$n:expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$x:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(,)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;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;It deals with three kinds of calls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;vec![]&lt;/code&gt;, which creates an empty Vector.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vec!["text"; 10]&lt;/code&gt;, which repeats the first value ("text") &lt;code&gt;n&lt;/code&gt; times, where &lt;code&gt;n&lt;/code&gt; is the second value (10).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vec![1,2,3]&lt;/code&gt;, which creates a vector with all the listed elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to see the implementation of the &lt;code&gt;vec!&lt;/code&gt; macro, check &lt;a href="https://www.youtube.com/watch?v=q6paRBbLgNw"&gt;Jon's stream about macros&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The transcriber
&lt;/h2&gt;

&lt;p&gt;The magic happens after the &lt;code&gt;=&amp;gt;&lt;/code&gt;. Most of what you are going to do here is regular Rust, but I would like to bring your attention to some specificities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Type
&lt;/h3&gt;

&lt;p&gt;When I called the exponentiation macro &lt;code&gt;power!&lt;/code&gt;, I did this:&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="nd"&gt;power!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3_i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;squared&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had to specify the type &lt;code&gt;i32&lt;/code&gt; because I used the &lt;code&gt;pow()&lt;/code&gt; function, which cannot be called on ambiguous numeric type; and as we do not define types in macros, I had to let the compiler know this information somehow. This is something to be aware when dealing with macros. Of course, I could have forced it by declaring a variable and passing the metavariable value to it and thus fixing the variable type. However, to do such a thing, we need multiple statements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple statements
&lt;/h3&gt;

&lt;p&gt;To have more than one line in your transcriber, you have to use double curly brackets:&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;etwas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                             &lt;span class="c1"&gt;//v --- this one&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value:expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;squared&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;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;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}}&lt;/span&gt;
   &lt;span class="c1"&gt;//^ --- and this one&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using repetition
&lt;/h3&gt;

&lt;p&gt;Let us finish our &lt;code&gt;adder!&lt;/code&gt; macro.&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;adder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$right:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; 
            &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="n"&gt;total&lt;/span&gt;
    &lt;span class="p"&gt;}};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;adder!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;10&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;To handle repetition, all we have to do is to place the statement we want to repeat within &lt;code&gt;$()+&lt;/code&gt; (the repetition operator should match, that is why I am using &lt;code&gt;+&lt;/code&gt; here as well). &lt;/p&gt;

&lt;p&gt;But what if we have multiple repetitions? Consider the following code.&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;operations&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$addend:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;mult&lt;/span&gt; &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$multiplier:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$addend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;

         &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="nv"&gt;$multiplier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&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;"Sum: {} | Product: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&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;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;operations!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;mult&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&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;How does Rust know that it must repeat &lt;em&gt;four times&lt;/em&gt; during the first repetition block and only &lt;em&gt;three times&lt;/em&gt; in the second one? By context. It checks the variable that is being use and figure out what to do. Clever, huh?&lt;/p&gt;

&lt;p&gt;Sure, you can make things harder to Rust. In fact, you may turn them indecipherable, like this:&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="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;operations&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$addend:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;mult&lt;/span&gt; &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$multiplier:expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$addend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="nv"&gt;$multiplier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&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;"Sum: {} | Product: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&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;What does “clever Rust” do with something like this? Well, one of the things it does best: it gives you a clear compile error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;error: meta-variable &lt;span class="s1"&gt;'addend'&lt;/span&gt; repeats 4 &lt;span class="nb"&gt;times&lt;/span&gt;, but &lt;span class="s1"&gt;'multiplier'&lt;/span&gt; repeats 3 &lt;span class="nb"&gt;times&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/main.rs:43:10
   |
43 |           &lt;span class="si"&gt;$(&lt;/span&gt;
   |  __________^
44 | |             &lt;span class="nb"&gt;sum&lt;/span&gt; +&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$addend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
45 | |             product &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$multiplier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
46 | |         &lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;
   | |_________^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neat! 🦀&lt;/p&gt;




&lt;h2&gt;
  
  
  Expand
&lt;/h2&gt;

&lt;p&gt;As mentioned earlier, macros are syntax extensions, which means that Rust will turn them into regular Rust code. Sometimes, to understand what is going &lt;del&gt;wrong&lt;/del&gt; on, it is very helpful to see how rust pull that transformation off. To do so, use the following command.&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="n"&gt;rustc&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Zunstable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;pretty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;expanded&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command, however, is not only verbose, but it will also call for the nightly compiler. To avoid this and get the same result, you may install &lt;a href="https://github.com/dtolnay/cargo-expand"&gt;&lt;code&gt;cargo-expand&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;cargo-expand
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once it is installed, you just have to run the command &lt;code&gt;cargo expand&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Although you don't have to be using the nightly compiler, I guess (and you may call me on this) you got to have it installed. To do so, run the command &lt;code&gt;rustup instal nightly&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Look at how the macro &lt;code&gt;operations!&lt;/code&gt; is expanded.&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;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mi"&gt;10&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;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;_print&lt;/span&gt;&lt;span class="p"&gt;(::&lt;/span&gt;&lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Arguments&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_v1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Sum: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" | Product: "&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;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;product&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;span class="n"&gt;arg0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                        &lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ArgumentV1&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                        &lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ArgumentV1&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;fmt&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;span class="p"&gt;));&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;As you can see, even &lt;code&gt;println!&lt;/code&gt; was expanded.&lt;/p&gt;




&lt;h2&gt;
  
  
  Export and import
&lt;/h2&gt;

&lt;p&gt;To use a macro outside the scope it was defined, you got to export it by using &lt;code&gt;#[macro_export]&lt;/code&gt;.&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="nd"&gt;#[macro_export]&lt;/span&gt;
&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;etwas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;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;You may also export a module of macros with &lt;code&gt;#[macro_use]&lt;/code&gt;.&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="nd"&gt;#[macro_use]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&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;span class="nd"&gt;a!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nd"&gt;b!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use a macro that a crate exports, you also use &lt;code&gt;#[macro_use]&lt;/code&gt;.&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="nd"&gt;#[macro_use(lazy_static)]&lt;/span&gt; &lt;span class="c1"&gt;// Or #[macro_use] to import all macros.&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;lazy_static&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;lazy_static!&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example above is from &lt;a href="https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute"&gt;The Rust Reference&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;And that's all for today. There is certainly more to cover, but I will leave you with the readings I recommended earlier.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Cover image by &lt;a href="https://unsplash.com/photos/FTNGfpYCpGM"&gt;Thom Milkovic&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>beginners</category>
      <category>rust</category>
      <category>tutorial</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Smart Pointers in Rust: What, why and how?</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Mon, 19 Jul 2021 15:25:22 +0000</pubDate>
      <link>https://dev.to/rogertorres/smart-pointers-in-rust-what-why-and-how-oma</link>
      <guid>https://dev.to/rogertorres/smart-pointers-in-rust-what-why-and-how-oma</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I will cover some of Rust's smart pointers: &lt;code&gt;Box&lt;/code&gt;, &lt;code&gt;Cell&lt;/code&gt;, &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;Rc&lt;/code&gt;, &lt;code&gt;Arc&lt;/code&gt;, &lt;code&gt;RwLock&lt;/code&gt; and &lt;code&gt;Mutex&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It seems pretty obvious that smart pointers are pointers that are... &lt;em&gt;smart&lt;/em&gt;. But &lt;strong&gt;what&lt;/strong&gt; exactly does this "smart" means? &lt;strong&gt;When&lt;/strong&gt; should we use them? &lt;strong&gt;How&lt;/strong&gt; do they work? &lt;/p&gt;

&lt;p&gt;These are the questions I will begin to answer here. And that is it: &lt;em&gt;the beginning of an answer&lt;/em&gt;, nothing more. I expect that this article will give you a "background of understanding" (something like "familiarity" with the concept) that will help you accommodate a real understanding of the topic, which will come from reading the official documentation and, of course, practice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you are already familiar with it, you may use this text as a list of relevant reading. Look for the "useful links" at the beginning of each section.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Index:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Box&lt;/li&gt;
&lt;li&gt;Cell&lt;/li&gt;
&lt;li&gt;RefCell&lt;/li&gt;
&lt;li&gt;Rc&lt;/li&gt;
&lt;li&gt;Arc&lt;/li&gt;
&lt;li&gt;RwLock&lt;/li&gt;
&lt;li&gt;Mutex&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Smart points in general
&lt;/h2&gt;

&lt;p&gt;As explained in &lt;a href="https://doc.rust-lang.org/book/ch15-00-smart-pointers.html"&gt;&lt;em&gt;The Book&lt;/em&gt;&lt;/a&gt;, pointers are variables containing an address that "points at" some other data. The usual pointer in Rust is the reference (&lt;code&gt;&amp;amp;&lt;/code&gt;). Smart pointers are pointers that "have additional metadata and capabilities", e.g., they may count how many times the value was borrowed, provide methods to manage read and write locks, etc.&lt;/p&gt;

&lt;p&gt;Technically speaking, &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;Vec&lt;/code&gt; are also smart pointers, but I will not cover them here as they are quite common and are usually thought of as types rather than pointers.&lt;/p&gt;

&lt;p&gt;Also note that, from this list, only &lt;code&gt;Arc&lt;/code&gt;, &lt;code&gt;RwLock&lt;/code&gt;, and &lt;code&gt;Mutex&lt;/code&gt; are thread-safe.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Box&amp;lt;T&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Useful links: &lt;a href="https://doc.rust-lang.org/book/ch15-01-box.html"&gt;The Book&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/std/boxed/struct.Box.html"&gt;Documentation&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/rust-by-example/std/box.html"&gt;Box, stack and heap&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; allows you to store &lt;code&gt;T&lt;/code&gt; on the heap. So, if you have, say, a &lt;code&gt;u64&lt;/code&gt; that would be stored on the stack, &lt;code&gt;Box&amp;lt;u64&amp;gt;&lt;/code&gt; will store it on the heap.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are not comfortable with the concepts of stack and heap, read &lt;a href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html?highlight=stack#the-stack-and-the-heap"&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;Values stored on the stack cannot grow, as Rust needs to know its size at compile time. The best example of how this may affect your programming that I know is in &lt;a href="https://doc.rust-lang.org/book/ch15-01-box.html?highlight=recursion#enabling-recursive-types-with-boxes"&gt;&lt;em&gt;The Book&lt;/em&gt;&lt;/a&gt;: &lt;strong&gt;recursion&lt;/strong&gt;. Consider the code below (and its comments).&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="c1"&gt;// This does not compile. The List contains itself,  &lt;/span&gt;
&lt;span class="c1"&gt;// being recursive and therefore having an infinite size.&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
   &lt;span class="nf"&gt;Cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="nb"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// This does compile because the size of a pointer&lt;/span&gt;
&lt;span class="c1"&gt;// does not change according to the size of the pointed value.&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
   &lt;span class="nf"&gt;Cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="nb"&gt;Nil&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;Be sure to read &lt;a href="https://doc.rust-lang.org/book/ch15-01-box.html?highlight=recursion#enabling-recursive-types-with-boxes"&gt;this section on &lt;em&gt;The Book's&lt;/em&gt;&lt;/a&gt; to understand the details.&lt;/p&gt;

&lt;p&gt;On a more general note, &lt;code&gt;Box&lt;/code&gt; is useful when your value is too big to be kept on the stack or when you need to &lt;a href="https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html"&gt;own&lt;/a&gt; it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How?
&lt;/h3&gt;

&lt;p&gt;To get the value &lt;code&gt;T&lt;/code&gt; inside &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; you just have to deref it.&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="n"&gt;boxed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;boxed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Cell&amp;lt;T&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Useful links: &lt;a href="https://doc.rust-lang.org/std/cell/"&gt;Module documentation&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/std/boxed/struct.Box.html"&gt;Pointer documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Cell&amp;lt;T&amp;gt;&lt;/code&gt; gives a shared reference to &lt;code&gt;T&lt;/code&gt; while allowing you to change &lt;code&gt;T&lt;/code&gt;.  This is one of the  "shareable mutable containers" provided by the module &lt;a href="https://doc.rust-lang.org/std/cell/"&gt;&lt;code&gt;std::cell&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;In Rust, shared references are immutable. This guarantees that when you access the inner value you are not getting something different than expected, as well as assure that you are not trying to access the value after it was freed (which is a big chunk of those &lt;a href="https://www.zdnet.com/article/chrome-70-of-all-security-bugs-are-memory-safety-issues/"&gt;70% of security bugs that are memory safety issues&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  How?
&lt;/h3&gt;

&lt;p&gt;What &lt;code&gt;Cell&amp;lt;T&amp;gt;&lt;/code&gt; does is provide functions that control our access to &lt;code&gt;T&lt;/code&gt;. You can find them all &lt;a href="https://doc.rust-lang.org/std/cell/struct.Cell.html"&gt;here&lt;/a&gt;, but for our explanation we just need two: &lt;code&gt;get()&lt;/code&gt; and &lt;code&gt;set()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Basically, &lt;code&gt;Cell&amp;lt;T&amp;gt;&lt;/code&gt; allows you to freely change &lt;code&gt;T&lt;/code&gt; with &lt;code&gt;T.set()&lt;/code&gt; because when you use &lt;code&gt;T.get()&lt;/code&gt;, you retrieve &lt;a href="https://doc.rust-lang.org/std/marker/trait.Copy.html"&gt;&lt;code&gt;Copy&lt;/code&gt;&lt;/a&gt; of &lt;code&gt;T&lt;/code&gt;, not a reference. That way, even if you change &lt;code&gt;T&lt;/code&gt;, the copied value you got with &lt;code&gt;get()&lt;/code&gt; will remain the same, and if you destroy &lt;code&gt;T&lt;/code&gt;, no pointer will dangle.&lt;/p&gt;

&lt;p&gt;One last note is that &lt;code&gt;T&lt;/code&gt; has to implement &lt;code&gt;Copy&lt;/code&gt; as well.&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Cell&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;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&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;eleven&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&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;twelve&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eleven&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;twelve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;RefCell&amp;lt;T&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Useful links: &lt;a href="https://doc.rust-lang.org/book/ch15-05-interior-mutability.html"&gt;The Book&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/std/cell/struct.RefCell.html"&gt;Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;RefCell&amp;lt;T&amp;gt;&lt;/code&gt; also gives shared reference to &lt;code&gt;T&lt;/code&gt;, but while &lt;code&gt;Cell&lt;/code&gt; is statically checked (Rust checks it at compile time), &lt;code&gt;RefCell&amp;lt;T&amp;gt;&lt;/code&gt; is dynamically checked (Rust checks it at run time).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;Because &lt;code&gt;Cell&lt;/code&gt; operates with copies, you should restrict yourself to using small values with it, which means that you need references once again, which leads us back to the problem that &lt;code&gt;Cell&lt;/code&gt; solved. &lt;/p&gt;

&lt;p&gt;The way &lt;code&gt;RefCell&lt;/code&gt; deals with it is by keeping track of who is reading and who writing  &lt;code&gt;T&lt;/code&gt;. That's why &lt;code&gt;RefCell&amp;lt;T&amp;gt;&lt;/code&gt; is dynamically checked: because &lt;strong&gt;you&lt;/strong&gt; are going to code this check. But fear not, Rust will still make sure you don't mess up at compile time.&lt;/p&gt;

&lt;h3&gt;
  
  
  How?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;RefCell&amp;lt;T&amp;gt;&lt;/code&gt; has methods that borrow either a mutable or immutable reference to  &lt;code&gt;T&lt;/code&gt;; methods that will not allow you to do so if this action would be unsafe. As with &lt;code&gt;Cell&lt;/code&gt;, there are several methods in &lt;code&gt;RefCell&lt;/code&gt;, but these two are enough to illustrate the concept: &lt;code&gt;borrow()&lt;/code&gt;, which gets an immutable reference; and &lt;code&gt;borrow_mut()&lt;/code&gt;, which gets a mutable reference. The logic used by &lt;code&gt;RefCell&lt;/code&gt; goes something like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If there is &lt;strong&gt;no reference&lt;/strong&gt; (either mutable or immutable) to &lt;code&gt;T&lt;/code&gt;, you may get either a mutable or immutable reference to it;&lt;/li&gt;
&lt;li&gt;If there is already a &lt;strong&gt;mutable reference&lt;/strong&gt; to &lt;code&gt;T&lt;/code&gt;, you may get nothing and got to wait until this reference is dropped;&lt;/li&gt;
&lt;li&gt;If there are one or more &lt;strong&gt;immutable references&lt;/strong&gt; to &lt;code&gt;T&lt;/code&gt;, you may get an immutable reference to it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, there is no way to get both mutable and immutable references to &lt;code&gt;T&lt;/code&gt; at the same time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Remember:&lt;/strong&gt; this is &lt;strong&gt;not&lt;/strong&gt; thread-safe. When I say "no way", I am talking about a single thread.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another way to think about is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Immutable&lt;/strong&gt; references are &lt;strong&gt;shared&lt;/strong&gt; references;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutable&lt;/strong&gt; references are &lt;strong&gt;exclusive&lt;/strong&gt; references.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is worth to say that the functions mentioned above have variants that do not panic, but returns &lt;code&gt;Result&lt;/code&gt; instead: &lt;code&gt;try_borrow()&lt;/code&gt; and &lt;code&gt;try_borrow_mut()&lt;/code&gt;;&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RefCell&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;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;RefCell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&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;_c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.borrow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// You may borrow as immutable as many times as you want,...&lt;/span&gt;
    &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.try_borrow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.is_ok&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="c1"&gt;// ...but cannot borrow as mutable because &lt;/span&gt;
    &lt;span class="c1"&gt;// it is already borrowed as immutable.&lt;/span&gt;
    &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.try_borrow_mut&lt;/span&gt;&lt;span class="p"&gt;()&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="c1"&gt;// After the first borrow as mutable...&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.borrow_mut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...you cannot borrow in any way.&lt;/span&gt;
&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.try_borrow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="nf"&gt;.try_borrow_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Rc&amp;lt;T&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Useful links: &lt;a href="https://doc.rust-lang.org/book/ch15-04-rc.html"&gt;The Book&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/std/rc/index.html"&gt;Module documentation&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/std/rc/struct.Rc.html"&gt;Pointer documentation&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/rust-by-example/std/rc.html"&gt;Rust by example&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What?
&lt;/h3&gt;

&lt;p&gt;I will quote the documentation on this one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The type &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt; provides shared ownership of a value of type &lt;code&gt;T&lt;/code&gt;, allocated on the heap. Invoking &lt;a href="https://doc.rust-lang.org/std/clone/trait.Clone.html#tymethod.clone"&gt;&lt;code&gt;clone&lt;/code&gt;&lt;/a&gt; on &lt;code&gt;Rc&lt;/code&gt; produces a new pointer to the same allocation on the heap. When the last &lt;code&gt;Rc&lt;/code&gt; pointer to a given allocation is destroyed, the value stored in that allocation (often referred to as “inner value”) is also dropped.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, like a &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt; allocates &lt;code&gt;T&lt;/code&gt; on the heap. The difference is that cloning &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; will give you another &lt;code&gt;T&lt;/code&gt; inside another &lt;code&gt;Box&lt;/code&gt; while cloning &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt; gives you another &lt;code&gt;Rc&lt;/code&gt; to the &lt;strong&gt;same&lt;/strong&gt; &lt;code&gt;T&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another important remark is that we don't have interior mutability in &lt;code&gt;Rc&lt;/code&gt; as we had in &lt;code&gt;Cell&lt;/code&gt; or &lt;code&gt;RefCell&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;You want to have shared access to some value (without making copies of it), but you want to let it go once it is no longer used, i.e., when there is no reference to it.&lt;/p&gt;

&lt;p&gt;As there is no interior mutability in &lt;code&gt;Rc&lt;/code&gt;, it is common to use it alongside &lt;code&gt;Cell&lt;/code&gt; or &lt;code&gt;RefCell&lt;/code&gt;, for example, &lt;code&gt;Rc&amp;lt;Cell&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How?
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt;, you are using the &lt;code&gt;clone()&lt;/code&gt; method. Behind the scene, it will count the number of references you have and, when it goes to zero, it drops &lt;code&gt;T&lt;/code&gt;.&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// After borrwing as immutable...&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// ...you can no longer borrow as mutable,...&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_mut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// ...but can still borrow as immutable.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_second&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Here we have 3 pointer ("c", "_first" and "_second").&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;strong_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// After we drop the last two, we remain only with "c" itself.&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;strong_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// And now we can borrow it as mutable.&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_mut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Arc&amp;lt;T&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Useful links: &lt;a href="https://doc.rust-lang.org/std/sync/struct.Arc.html"&gt;Documentation&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/rust-by-example/std/arc.html"&gt;Rust by example&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Arc&lt;/code&gt; is the thread-safe version of &lt;code&gt;Rc&lt;/code&gt;, as its counter is managed through atomic operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;I think the reason why you would use &lt;code&gt;Arc&lt;/code&gt; instead of &lt;code&gt;Rc&lt;/code&gt; is clear (thread-safety), so the pertinent question becomes: why not just use &lt;code&gt;Arc&lt;/code&gt; &lt;em&gt;every&lt;/em&gt; time? The answer is that these extra controls provided by &lt;code&gt;Arc&lt;/code&gt; come with an overhead cost. &lt;/p&gt;

&lt;h3&gt;
  
  
  How?
&lt;/h3&gt;

&lt;p&gt;Just like &lt;code&gt;Rc&lt;/code&gt;,  with &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt; you will be using &lt;code&gt;clone()&lt;/code&gt; to get a pointer to the same value &lt;code&gt;T&lt;/code&gt;, which will be destroyed once the last pointer is dropped.&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;thread&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;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&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;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// You could not do this with "Rc"&lt;/span&gt;
    &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&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;"Value: {:?} / Active pointers: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;strong_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;val&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;RwLock&amp;lt;T&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Useful link: &lt;a href="https://doc.rust-lang.org/std/sync/struct.RwLock.html"&gt;Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;RwLock&lt;/code&gt; is also provided by the &lt;a href="https://docs.rs/parking_lot/0.10.2/parking_lot/type.RwLock.html"&gt;&lt;code&gt;parking_lot&lt;/code&gt;&lt;/a&gt; crate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What?
&lt;/h3&gt;

&lt;p&gt;As a reader-writer lock, &lt;code&gt;RwLock&amp;lt;T&amp;gt;&lt;/code&gt; will only give access to &lt;code&gt;T&lt;/code&gt; once you are holding one of the locks: &lt;code&gt;read&lt;/code&gt; or &lt;code&gt;write&lt;/code&gt;, which are given following these rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;To read&lt;/strong&gt;: If you want a lock to read, you may get it as long as &lt;em&gt;no writer&lt;/em&gt; is holding the lock; otherwise, you have to wait until it is dropped;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To write&lt;/strong&gt;: If you want a lock to write, you may get as long as &lt;em&gt;no one&lt;/em&gt;, reader or writer, is holding the lock; otherwise, you have to wait until they are dropped;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;RwLock&lt;/code&gt; allows you to read and write the same data from multiple threads. Different from &lt;code&gt;Mutex&lt;/code&gt; (see below), it distinguishes the kind of lock, so you may have several &lt;code&gt;read&lt;/code&gt; locks as far as you do not have any &lt;code&gt;write&lt;/code&gt; lock.&lt;/p&gt;

&lt;h3&gt;
  
  
  How?
&lt;/h3&gt;

&lt;p&gt;When you want to read a &lt;code&gt;RwLock&lt;/code&gt;, you got to use the function &lt;code&gt;read()&lt;/code&gt;—or &lt;code&gt;try_read()&lt;/code&gt;—that will return a &lt;code&gt;LockResult&lt;/code&gt; that contains a &lt;code&gt;RwLockReadGuard&lt;/code&gt;. If it is successful, you will be able to access the value inside &lt;code&gt;RwLockReadGuard&lt;/code&gt; by using deref. If a writer is holding the lock, the thread will be blocked until it can take hold of the lock. &lt;/p&gt;

&lt;p&gt;Something similar happens when you try to use &lt;code&gt;write()&lt;/code&gt;—or &lt;code&gt;try_write()&lt;/code&gt;. The difference is that it will not only wait for a writer holding the lock, but for any reader holding the lock as well.&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RwLock&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;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;RwLock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&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;_r1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// You may pile as many read locks as you want.&lt;/span&gt;
    &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.try_read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.is_ok&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="c1"&gt;// But you cannot write.&lt;/span&gt;
    &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.try_write&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="c1"&gt;// Note that if you use "write()" instead of "try_write()"&lt;/span&gt;
    &lt;span class="c1"&gt;// it will wait until all the other locks are released&lt;/span&gt;
    &lt;span class="c1"&gt;// (in this case, never).&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="c1"&gt;// If you grab the write lock, you may easily change it&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If some thread holding the lock panics, further attempts to get the lock will return a &lt;a href="https://doc.rust-lang.org/std/sync/struct.PoisonError.html"&gt;&lt;code&gt;PoisonError&lt;/code&gt;&lt;/a&gt;, which means that from then on every attempt to read &lt;code&gt;RwLock&lt;/code&gt; will return the same &lt;code&gt;PoisonError&lt;/code&gt;. You may recover from a poisoned &lt;code&gt;RwLock&lt;/code&gt; using &lt;code&gt;into_inner()&lt;/code&gt;.&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RwLock&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;thread&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;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;RwLock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&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;c_lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lock&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;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&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;_lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c_lock&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// the lock gets poisoned&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="nf"&gt;.join&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;read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.read&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poisoned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;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;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;poisoned&lt;/span&gt;&lt;span class="nf"&gt;.into_inner&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// It will be 12 because it was recovered from the poisoned lock&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Mutex&amp;lt;T&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Useful links: &lt;a href="https://doc.rust-lang.org/book/ch16-03-shared-state.html"&gt;The Book&lt;/a&gt;; &lt;a href="https://doc.rust-lang.org/std/sync/struct.Mutex.html"&gt;Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Mutex&lt;/code&gt; is also provided by the &lt;a href="https://docs.rs/parking_lot/0.10.0/parking_lot/type.Mutex.html"&gt;&lt;code&gt;parking_lot&lt;/code&gt;&lt;/a&gt; crate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Mutex&lt;/code&gt; is similar to &lt;code&gt;RwLock&lt;/code&gt;, but it only allows one lock-holder, no matter if it is a reader or a writer. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;One reason to prefer &lt;code&gt;Mutex&lt;/code&gt; over &lt;code&gt;RwLock&lt;/code&gt; is that &lt;code&gt;RwLock&lt;/code&gt;  may lead to writer starvation (when the readers pile on and the writer never gets a chance to take the lock, waiting forever), something the does not happen with &lt;code&gt;Mutex&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Of course, we are diving into deeper seas here, so the real-life choice falls on more advanced considerations, such as how many readers you expect at the same time, how the operating system implements the locks, and so on...&lt;/p&gt;

&lt;h3&gt;
  
  
  How?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Mutex&lt;/code&gt; and &lt;code&gt;RwLock&lt;/code&gt; work in a similar fashion, the difference is that, because &lt;code&gt;Mutex&lt;/code&gt; does not differentiate between readers and writers, you just use &lt;code&gt;lock()&lt;/code&gt; or &lt;code&gt;try_lock&lt;/code&gt; to get the &lt;code&gt;MutexGuard&lt;/code&gt;. The poisoning logic also happens here.&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Mutex&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;guard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Mutex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;guard&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// It does not matter if you are locking the Mutex to read or write,&lt;/span&gt;
&lt;span class="c1"&gt;// you can only lock it once.&lt;/span&gt;
&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;guard&lt;/span&gt;&lt;span class="nf"&gt;.try_lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// You may change it just like you did with RwLock&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can deal with poisoned &lt;code&gt;Mutex&lt;/code&gt; in the same way as you deal with poisoned &lt;code&gt;RwLock&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>First steps with Docker + Rust</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Mon, 12 Jul 2021 11:34:12 +0000</pubDate>
      <link>https://dev.to/rogertorres/first-steps-with-docker-rust-30oi</link>
      <guid>https://dev.to/rogertorres/first-steps-with-docker-rust-30oi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR: We are going to install Docker and create five different containers for a Rust program, each one a little more complex than the other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hi! In this post, I will show you how to &lt;em&gt;dockerize&lt;/em&gt; your Rust program. We will begin with a very simple container and will build from that to more sophisticated ones, where we take care of compile-time and image size.&lt;/p&gt;

&lt;p&gt;I thought about just jumping to the last one instead of granularizing so much, but I prefer to be clear rather than concise with these &lt;a href="https://dev.to/t/beginners"&gt;#beginners&lt;/a&gt; posts. Feel free to jump whatever is too obvious for you and ask me what remained too obscure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Install Docker
&lt;/h2&gt;

&lt;p&gt;First of all, install &lt;strong&gt;Docker&lt;/strong&gt;. The &lt;em&gt;getting started&lt;/em&gt; guide has instructions for &lt;a href="https://docs.docker.com/docker-for-mac/install" rel="noopener noreferrer"&gt;Mac OS&lt;/a&gt;, &lt;a href="https://docs.docker.com/install/linux/docker-ce/ubuntu" rel="noopener noreferrer"&gt;Linux&lt;/a&gt; and &lt;a href="https://docs.docker.com/docker-for-windows/install" rel="noopener noreferrer"&gt;Windows&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once installed, run and test it by issuing this command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ docker run hello-world


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It should pull the &lt;code&gt;hello-world&lt;/code&gt; image from the &lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt; and return a text block explaining in detail what happened behind the scene.&lt;/p&gt;




&lt;h2&gt;
  
  
  Glossary
&lt;/h2&gt;

&lt;p&gt;If you are completely new to Docker, it will help to have a clear understanding of what I mean when I use the following terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt;: The application we just installed (or, to be more precise, the Docker daemon we use to deal with our images and containers);&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dockerfile&lt;/strong&gt;: A file named &lt;code&gt;Dockerfile&lt;/code&gt; that contains the commands that Docker will run to build the image. In a Rust project, it lies alongside the &lt;em&gt;manifest&lt;/em&gt;, that is, the &lt;code&gt;Cargo.toml&lt;/code&gt; file;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt;: When we run a command &lt;code&gt;build&lt;/code&gt; we create an image that contains everything we specified in the &lt;code&gt;Dockerfile&lt;/code&gt;. Running an image result in a container. E.g., if our &lt;code&gt;Dockerfile&lt;/code&gt; has instructions to build and run a Web Server, the image will contain the program (that is, the Web Server itself) which will be accessible when we &lt;em&gt;run&lt;/em&gt; the image, thus creating the container;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Base image&lt;/strong&gt;: It is an image that we use to base ours. E.g., for us, Rust will be a base image (which we don't build manually; we download it ready to use); &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container&lt;/strong&gt;: The result of running an image. The container is a process running on your computer that contains everything that is needed to run the application. For a better understanding, I recommend &lt;a href="https://youtu.be/8fi7uSYlOdc" rel="noopener noreferrer"&gt;this presentation by Liz Rice&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The sample project
&lt;/h2&gt;

&lt;p&gt;I am going to use a REST API that I built using &lt;a href="https://docs.rs/warp/0.3.1/warp/" rel="noopener noreferrer"&gt;warp&lt;/a&gt;. If you want to build it yourself, you may check &lt;a href="https://dev.to/rogertorres/rest-api-with-rust-warp-1-introduction-342e"&gt;this guide&lt;/a&gt;; if not, feel free download it &lt;a href="https://github.com/rogertorres/dev.to/tree/main/docker/holodeck"&gt;here&lt;/a&gt; or even use your own project; I believe you will have no problem mapping the commands.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are a few differences between the code you'll find in the guide and the one I am using here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I am now using IP 0.0.0.0 instead of 127.0.0.1. I changed this so I don't have to tell Docker which IP to bind;&lt;/li&gt;
&lt;li&gt;The old version has two crates: binary (&lt;code&gt;main.rs&lt;/code&gt;) and library (&lt;code&gt;lib.rs&lt;/code&gt;). That made things harder for Docker (and would make my explanations here too complex) so I just maintained the binary crate and moved the library crate content to a module.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The first &lt;code&gt;Dockerfile&lt;/code&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;This and all other files are available &lt;a href="https://github.com/rogertorres/dev.to/tree/main/docker/holodeck"&gt;here&lt;/a&gt;. You will identify them by their numbers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I will start with a very simple version and improve upon it a few times. Here I am working with the project I mentioned above, named &lt;code&gt;holodeck&lt;/code&gt; (so that is the name you will have to change if you're using your project):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="c"&gt;# 1. This tells docker to use the Rust official image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; rust:1.49&lt;/span&gt;

&lt;span class="c"&gt;# 2. Copy the files in your machine to the Docker image&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./ ./&lt;/span&gt;

&lt;span class="c"&gt;# Build your program for release&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;

&lt;span class="c"&gt;# Run the binary&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["./target/release/holodeck"]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With this, I just run the command below where the &lt;code&gt;Dockerfile&lt;/code&gt; is.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ docker build -t holodeck .


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will create the image. To see that, you may either look at your Docker app or use the command &lt;code&gt;docker images&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ docker images
REPOSITORY  TAG       IMAGE ID       CREATED          SIZE
holodeck    latest    aad6ff7c3b4d   47 seconds ago   2.42GB


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To run it, all we have to do is to issue a command like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ docker run -p 8080:3030 --rm --name holodeck1 holodeck
Warp 6, Engage!


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let me expand on the parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt; maps the port, so what is 3030 &lt;em&gt;inside&lt;/em&gt; Docker (the port our warp server is using) will be accessible through 8080 &lt;em&gt;outside&lt;/em&gt;, i.e., your machine (if you don't do this, Docker will map a random port);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--rm&lt;/code&gt; is here to remove the container after we close it (to visualize this, you may run without &lt;code&gt;--rm&lt;/code&gt; and then run &lt;code&gt;docker ps -a&lt;/code&gt; to list all the containers and then use &lt;code&gt;docker rm containername&lt;/code&gt; to remove it).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now it is possible to test it in &lt;code&gt;localhost:8080&lt;/code&gt;. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ curl --location --request POST 'localhost:8080/holodeck' \
--header 'Content-Type: application/json' \
--header 'Content-Type: text/plain' \
--data-raw '{
    "id": 2,
    "name": "Bride Of Chaotica!"
}'

Simulation #1 created.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To stop the container:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ docker stop holodeck1
holodeck1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you ran your image like me, your terminal will be frozen. To avoid this, run in detached mode, by just adding the parameter &lt;code&gt;-d&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ docker run -dp 8080:3030 --rm --name holodeck1 holodeck


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Great! This is fine... Until you have to build again and again (and maybe even again because you're writing a guide like this and have to tweak things often). Why is this a problem? &lt;strong&gt;Compile time&lt;/strong&gt;. Every time we run &lt;code&gt;docker build&lt;/code&gt;, Rust does the entire building process all over again; and the fact we're building for release just makes it worse.&lt;/p&gt;

&lt;p&gt;Let's fix it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The second &lt;code&gt;Dockerfile&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This is a more elaborated alternative:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Rust as the base image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; rust:1.49&lt;/span&gt;

&lt;span class="c"&gt;# 1. Create a new empty shell project&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;root cargo new &lt;span class="nt"&gt;--bin&lt;/span&gt; holodeck
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /holodeck&lt;/span&gt;

&lt;span class="c"&gt;# 2. Copy our manifests&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./Cargo.lock ./Cargo.lock&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./Cargo.toml ./Cargo.toml&lt;/span&gt;

&lt;span class="c"&gt;# 3. Build only the dependencies to cache them&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;src/&lt;span class="k"&gt;*&lt;/span&gt;.rs

&lt;span class="c"&gt;# 4. Now that the dependency is built, copy your source code&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./src ./src&lt;/span&gt;

&lt;span class="c"&gt;# 5. Build for release.&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; ./target/release/deps/holodeck&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;cargo &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--path&lt;/span&gt; .

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["holodeck"]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;I am using &lt;code&gt;install&lt;/code&gt;, but this is the same as &lt;code&gt;build&lt;/code&gt;, except that it places the binary on the indicated path, in this case, the &lt;code&gt;WORKDIR&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is how we avoid the compiler &lt;em&gt;aeon&lt;/em&gt;. By building only the dependencies attached to a new program (steps 1 through 3) and then, with a new command inside the &lt;code&gt;Dockerfile&lt;/code&gt;, build our program (commands 4 and 5), we stop Docker from ignoring the cache. Why does it work? Because every command in our &lt;code&gt;Dockerfile&lt;/code&gt; creates a new &lt;a href="https://docs.docker.com/glossary/#layer" rel="noopener noreferrer"&gt;layer&lt;/a&gt;, which is a modification to the image. When we run &lt;code&gt;docker build&lt;/code&gt;, only the modified layers are updated, the rest is retrieved from the local cache. To put it in practical terms, as long as we don't change the manifest, the dependencies will not have to be rebuilt.&lt;/p&gt;

&lt;p&gt;In my case, after a first build that took 323.6 seconds, the second one (where I just changed the &lt;code&gt;main.rs&lt;/code&gt;) took only 33.9 seconds. Great!&lt;/p&gt;

&lt;p&gt;However... there is another problem: &lt;strong&gt;image size&lt;/strong&gt;. For example, mine has &lt;strong&gt;1.65 GB&lt;/strong&gt;, which better than the very first one, which had &lt;strong&gt;2.42 GB&lt;/strong&gt;, but still too large. &lt;a href="https://youtu.be/PdF1Rqet9E8" rel="noopener noreferrer"&gt;Let's put a little fixin' on it&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The third &lt;code&gt;Dockerfile&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;If you visited Isaac's post, you'll see he managed this by "chaining" builds by using two base images. He did everything after a first &lt;code&gt;FROM rust&lt;/code&gt;, which is the build where everything is built, and then called another &lt;code&gt;FROM rust&lt;/code&gt;, copying only the required files from the first build. That allows the final image to retain only these last copied files, therefore decreasing the image size.&lt;/p&gt;

&lt;p&gt;This is how we do it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;rust:1.49&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;

&lt;span class="c"&gt;# create a new empty shell project&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;root cargo new &lt;span class="nt"&gt;--bin&lt;/span&gt; holodeck
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /holodeck&lt;/span&gt;

&lt;span class="c"&gt;# copy over your manifests&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./Cargo.lock ./Cargo.lock&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./Cargo.toml ./Cargo.toml&lt;/span&gt;

&lt;span class="c"&gt;# this build step will cache your dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;src/&lt;span class="k"&gt;*&lt;/span&gt;.rs

&lt;span class="c"&gt;# copy your source tree&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./src ./src&lt;/span&gt;

&lt;span class="c"&gt;# build for release&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; ./target/release/deps/holodeck&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;

&lt;span class="c"&gt;# our final base&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; rust:1.49&lt;/span&gt;

&lt;span class="c"&gt;# copy the build artifact from the build stage&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /holodeck/target/release/holodeck .&lt;/span&gt;

&lt;span class="c"&gt;# set the startup command to run your binary&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["./holodeck"]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That reduced the image size from &lt;strong&gt;1.66 GB&lt;/strong&gt; to &lt;strong&gt;1.26 GB&lt;/strong&gt;. But I promised five versions of the &lt;code&gt;Dockerfile&lt;/code&gt;, so you already know we can do better.&lt;/p&gt;




&lt;h2&gt;
  
  
  The fourth &lt;code&gt;Dockerfile&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;What we'll now do is to change the Rust image tag we are using. A tag is another way to say an "image variant", that is, an alternative image designed to meet certain goals. So, if we want a space-saving image, &lt;a href="https://hub.docker.com/_/rust?tab=tags&amp;amp;page=1&amp;amp;ordering=last_updated" rel="noopener noreferrer"&gt;it is a tag that we're looking for&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And all that means just replacing the second &lt;code&gt;FROM&lt;/code&gt; with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; rust:1.49-slim-buster&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This image tag uses Rust built upon Debian tag called &lt;a href="https://hub.docker.com/_/debian" rel="noopener noreferrer"&gt;buster slim&lt;/a&gt; to create a more compact image. Now, instead of &lt;strong&gt;1.26 GB&lt;/strong&gt;, we have &lt;strong&gt;642.3 MB&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some people might wonder why I didn't use Alpine. Well, I did, and buster-slim was 10MB smaller. But the real reason why I avoided Alpine will be clear in the next step.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The fifth (and final) &lt;code&gt;Dockerfile&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;I don't think this hunt for the minimal image size is always needed; you got to have a reason. &lt;/p&gt;

&lt;p&gt;As I &lt;em&gt;do&lt;/em&gt; have reason (show it to you), I will do one final change that will give a really small Docker image. For this, we need an image that has no Rust whatsoever, only the binary that will be executed (that's one of the beauties of a compiled language after all). &lt;/p&gt;

&lt;p&gt;To achieve such a thing, we use a Rust base image to build our binary and just move the binary to a Linux image without Rust. And to do that, we will use &lt;a href="https://hub.docker.com/_/debian" rel="noopener noreferrer"&gt;debian:buster-slim&lt;/a&gt; itself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Again, regarding Alpine. I didn't use it here either for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To run a Rust code in Alpine it has to be &lt;a href="https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/musl-support-for-fully-static-binaries.html" rel="noopener noreferrer"&gt;compiled with MUSL&lt;/a&gt;, which adds an extra layer of complexity to this beginner-intended post;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://andygrove.io/2020/05/why-musl-extremely-slow" rel="noopener noreferrer"&gt;I am not sure that MUSL is a good option&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;The result: &lt;strong&gt;75.39 MB&lt;/strong&gt;. That's a long way from &lt;strong&gt;2.42 GB&lt;/strong&gt;. &lt;br&gt;
Let's make an overall comparison:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F75hj6rfqxhwtvocx0rbl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F75hj6rfqxhwtvocx0rbl.png" alt="Final comparison"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;That's it! Thank you for reading so far. Bye!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image by &lt;a href="https://unsplash.com/photos/sNY6B9NsPP8" rel="noopener noreferrer"&gt;Aron Yigin&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>rust</category>
      <category>docker</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting started with GitHub Actions for Rust</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Wed, 07 Jul 2021 14:14:45 +0000</pubDate>
      <link>https://dev.to/rogertorres/getting-started-with-github-actions-for-rust-1o6g</link>
      <guid>https://dev.to/rogertorres/getting-started-with-github-actions-for-rust-1o6g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR: Create an Action on GitHub so your code gets built and tested after every push, and do all this with nothing more than a "next-next-finish".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You &lt;em&gt;never&lt;/em&gt; used GitHub Actions and you want do do it with your Rust project; if that's the case, this might help you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is and Why GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; automatize software workflow, which &lt;em&gt;per se&lt;/em&gt; is &lt;strong&gt;not&lt;/strong&gt; CI/CD (Continuous Integration/Continuous Delivery), but is used in this method.&lt;/p&gt;

&lt;p&gt;So, which workflow are we going to automatize? Test and build. In other words, this:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="k"&gt;cargo&lt;/span&gt; test&lt;br&gt;
&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="k"&gt;cargo&lt;/span&gt; build&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  How to do it&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;First, open your GitHub repository and go to &lt;strong&gt;Actions&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media.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%2F756h5zscio1kj5ksu6ig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F756h5zscio1kj5ksu6ig.png" alt="GitHub Actions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The example is from &lt;a href="https://github.com/rogertorres/mtgsdk" rel="noopener noreferrer"&gt;this repository&lt;/a&gt; that I wrote about &lt;a href="https://dev.to/rogertorres/rest-api-wrapper-with-rust-mk4"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This will lead you to this GitHub proposal, which will do exactly what we're set to do here, i.e., build and test:&lt;br&gt;
&lt;a href="https://media.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%2Fqawjl7h9op3bi27fjatc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqawjl7h9op3bi27fjatc.png" alt="Workflow proposal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub will preview the &lt;code&gt;.yml&lt;/code&gt; file it will create. For this scope, you don't have to change anything (except  maybe the &lt;code&gt;name&lt;/code&gt; from "Rust" to something else — I used "test").&lt;br&gt;
&lt;a href="https://media.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%2Fijt85753h6odw1vk9eqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fijt85753h6odw1vk9eqj.png" alt="yml preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit the change clicking on the button that will appear on the right and the file will be created:&lt;br&gt;
&lt;a href="https://media.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%2F4lncchmvn2svx6068rmn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4lncchmvn2svx6068rmn.png" alt="After commit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if you go to &lt;strong&gt;Actions&lt;/strong&gt; again, you will see GitHub creating your &lt;strong&gt;.yml&lt;/strong&gt; file. For me, it took around 2 minutes.&lt;br&gt;
&lt;a href="https://media.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%2Fi12lw4b8lyl7tr58xdok.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fi12lw4b8lyl7tr58xdok.png" alt="Building yml"&gt;&lt;/a&gt;&lt;a href="https://media.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%2Fk7ke1u2hymkr3f00exc1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fk7ke1u2hymkr3f00exc1.png" alt="yml built"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it. From now on, every time you &lt;code&gt;push&lt;/code&gt; against the repository, GitHub will run the tests for you.&lt;br&gt;
&lt;a href="https://media.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%2Flzgxpvgmedft7zexpacb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flzgxpvgmedft7zexpacb.png" alt="After push"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see the result of the commit above, see the &lt;strong&gt;Build&lt;/strong&gt; log &lt;a href="https://github.com/rogertorres/mtgsdk/runs/2993657655?check_suite_focus=true" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;And that's all for today.&lt;/p&gt;

&lt;p&gt;See ya 🙃&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image by &lt;a href="https://unsplash.com/photos/BiWM-utpVVc" rel="noopener noreferrer"&gt;Susan Q Yin&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>rust</category>
      <category>github</category>
      <category>actions</category>
    </item>
    <item>
      <title>REST API Wrapper with Rust</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Mon, 05 Jul 2021 16:38:25 +0000</pubDate>
      <link>https://dev.to/rogertorres/rest-api-wrapper-with-rust-mk4</link>
      <guid>https://dev.to/rogertorres/rest-api-wrapper-with-rust-mk4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR: This is a post for beginners where I show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How I structured the files in the project for better documentation: &lt;strong&gt;every file in the same folder&lt;/strong&gt;; &lt;/li&gt;
&lt;li&gt;How I coded a "query builder" to handle different calls without repeating code: &lt;strong&gt;using a generic parameter&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;How I coded test cases within the documentation: &lt;strong&gt;nothing special, just remarks on &lt;em&gt;async&lt;/em&gt; tests&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;How I created High Order Functions (HOF) to emulate that behaviour we have in Rust's Option and Iterator, for example: &lt;strong&gt;created a struct with functions that return the struct itself&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;How I used &lt;em&gt;serde&lt;/em&gt; to deserialize the Json: &lt;strong&gt;nothing special, just some extra remarks&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;How I tested it as if it were a crate without exporting it to crates.io: &lt;strong&gt;just add the lib.rs in the dependencies of the new project&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I build a wrapper for the &lt;a href="https://docs.magicthegathering.io/" rel="noopener noreferrer"&gt;Magic: The Gathering API&lt;/a&gt; (an SDK, by their own terms). And I did so because I wanted a personal project that offered the following possibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the &lt;em&gt;&lt;strong&gt;reqwest&lt;/strong&gt;&lt;/em&gt; crate;&lt;/li&gt;
&lt;li&gt;Code something for other coders (e.g.: allowing them to use &lt;a href="https://doc.rust-lang.org/rust-by-example/fn/hof.html" rel="noopener noreferrer"&gt;HOFs&lt;/a&gt;, such as &lt;code&gt;cards.filter().types("creature").colors("red").name("dragon")&lt;/code&gt;...);&lt;/li&gt;
&lt;li&gt;To document it as a crate, including tests in the documentation;&lt;/li&gt;
&lt;li&gt;Implement Github Actions (&lt;em&gt;Edit&lt;/em&gt;: I did this later, you can find it &lt;a href="https://dev.to/rogertorres/getting-started-with-github-actions-for-rust-1o6g"&gt;here&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason why I chose the Magic: The Gathering (MTG) API (besides being a MTG nerd) is because it is a very simple API (it has only &lt;code&gt;GET&lt;/code&gt; methods). &lt;/p&gt;

&lt;p&gt;This is not a tutorial, I will just highlight the interesting choices this endeavour led me to. Also, this is for beginners; I highly doubt I will say anything new to someone who had carefully read &lt;a href="https://doc.rust-lang.org/book/title-page.html" rel="noopener noreferrer"&gt;The Book&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/rust-by-example/" rel="noopener noreferrer"&gt;Rust by example&lt;/a&gt; and toyed with &lt;em&gt;async&lt;/em&gt; a little bit (although we never know).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The result can be found &lt;a href="https://github.com/rogertorres/mtgsdk" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The project structure
&lt;/h2&gt;

&lt;p&gt;I had two choices: &lt;br&gt;
&lt;a href="https://media.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%2F6ws392kayt5mk60xuisp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6ws392kayt5mk60xuisp.png" alt="Project structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I chose the left one for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It allows the person using the crate to type &lt;code&gt;use mtgsdk&lt;/code&gt; instead of &lt;code&gt;use mtgsdk::mtgsdk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This way the documentation shows everything on the first page. Had I went for the option on the right, the docs would only show the module &lt;code&gt;mtgsdk&lt;/code&gt;, which I found is not how the cool kids do it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it is (left option):&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.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%2Fmdgirxnt48mmfd9fmrpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fmdgirxnt48mmfd9fmrpc.png" alt="Option on the left"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to see for yourself, fork/download the repository and type &lt;code&gt;cargo doc --open&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;How it would be (right option):&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.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%2Fc5r7jb2wrr653tm50a4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fc5r7jb2wrr653tm50a4z.png" alt="Option on the right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe the first image and &lt;a href="https://doc.rust-lang.org/rust-by-example/mod/split.html?highlight=mod.rs#file-hierarchy" rel="noopener noreferrer"&gt;Rust by example&lt;/a&gt; is enough to show how each way of doing this is carried out; however, for the sake of clarity, I will say this: If you want the left one, all you have to do is to declare the &lt;em&gt;mods&lt;/em&gt; in your &lt;code&gt;lib.rs&lt;/code&gt;. Otherwise, you have to create a folder with your single module name, create a &lt;code&gt;mod.rs&lt;/code&gt; file in it and use the &lt;code&gt;mod&lt;/code&gt; and &lt;code&gt;pub mod&lt;/code&gt; inside it, declaring only the folder name within &lt;code&gt;lib.rs&lt;/code&gt; (in this case, &lt;code&gt;lib.rs&lt;/code&gt; would only have &lt;code&gt;pub mod mtgsdk;&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Query builder
&lt;/h2&gt;

&lt;p&gt;As I said, this API only has &lt;code&gt;GET&lt;/code&gt; methods, and there's not much to talk about how &lt;em&gt;&lt;strong&gt;&lt;a href="https://docs.rs/reqwest/0.11.4/reqwest/fn.get.html" rel="noopener noreferrer"&gt;reqwest&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt; handles it, for it is pretty much just passing a URL as you would do in a &lt;code&gt;curl&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am not saying that this is all that &lt;em&gt;&lt;strong&gt;reqwest&lt;/strong&gt;&lt;/em&gt; does; it is not. I am saying that for this API we don't actually need anything else that accessing the URL and parsing the Json (more on this later).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, instead of repeating the &lt;code&gt;reqwest::get(url)&lt;/code&gt; inside every module, I created a &lt;em&gt;query builder&lt;/em&gt; that receives an &lt;code&gt;url&lt;/code&gt; and returns a &lt;code&gt;Result&amp;lt;T, StatusCode&amp;gt;&lt;/code&gt; where T is a struct containing the data for the various calls (cards, formats, etc.). &lt;/p&gt;

&lt;p&gt;Besides allowing me to maintain the usage of &lt;em&gt;&lt;strong&gt;reqwest&lt;/strong&gt;&lt;/em&gt; in a single spot, it also allowed me to handle the errors and just send &lt;code&gt;StatusCode&lt;/code&gt;, so the developer using this crate would easily handle the errors. Here is the code with some additional comments.&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;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;
    &lt;span class="c1"&gt;//This is a requirement for Serde; I will talk about it below.&lt;/span&gt;
    &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DeserializeOwned&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// I am using match instead of "if let" or "?" &lt;/span&gt;
    &lt;span class="c1"&gt;// to make what's happening here crystal clear&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.status&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;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="nf"&gt;.is_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;()&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;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BAD_REQUEST&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;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// This is where de magic (and most problems) occur.&lt;/span&gt;
    &lt;span class="c1"&gt;// Again, more on this later.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BAD_REQUEST&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty straightforward: the functions calling the &lt;code&gt;build()&lt;/code&gt; function will tell which type &lt;code&gt;T&lt;/code&gt; corresponds to, a type that will be a struct with the &lt;code&gt;Deserialize&lt;/code&gt; trait so that &lt;em&gt;&lt;strong&gt;reqwest's&lt;/strong&gt;&lt;/em&gt; &lt;code&gt;json()&lt;/code&gt; can do the heavy lifting for us.&lt;/p&gt;




&lt;h2&gt;
  
  
  Documentation tests
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html?highlight=docu#making-useful-documentation-comments" rel="noopener noreferrer"&gt;documentation section&lt;/a&gt; in the Rust Book is pretty good. Besides reading that, I only checked some examples of how documentation is managed in the crates I use. &lt;/p&gt;

&lt;p&gt;What I want to highlight is the insertion of tests within the docs:&lt;br&gt;
&lt;a href="https://media.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%2F5rmp0ezau9lipcr6k7jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5rmp0ezau9lipcr6k7jt.png" alt="Documentation test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That this test will be executed is something that The Book talks about, so I will not stress about it. What was specific for me is that I was testing &lt;code&gt;async&lt;/code&gt; calls, which required two minor tweaks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It has to be in an async block;&lt;/li&gt;
&lt;li&gt;I could not return anything (so no &lt;code&gt;await?&lt;/code&gt;, &lt;a href="https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.html" rel="noopener noreferrer"&gt;because it returns the error&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  High Order Functions
&lt;/h2&gt;

&lt;p&gt;I will not lecture about &lt;a href="https://doc.rust-lang.org/rust-by-example/fn/hof.html" rel="noopener noreferrer"&gt;HOF&lt;/a&gt;, let alone explain anything about functional programming. The reason I ended up with this is because, instead of something like this Builder Pattern (this is from another wrapper for the same API)...&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;get_cards_request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="nf"&gt;.cards&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.all_filtered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nn"&gt;CardFilter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.game_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;GameFormat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Standard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.cardtypes_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nn"&gt;CardType&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;CardType&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sorcery&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="nf"&gt;.converted_mana_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.rarities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nn"&gt;CardRarity&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;CardRarity&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MythicRare&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="nf"&gt;.build&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="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CardDetail&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;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;loop&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_cards_request&lt;/span&gt;&lt;span class="nf"&gt;.next_page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="py"&gt;.content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cards&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;filtered_cards&lt;/span&gt;&lt;span class="nf"&gt;.extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cards&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;"Filtered Cards: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filtered_cards&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...I wanted something like this:&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="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.game_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"standard"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.type_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"instant|sorcery"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.cmc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.rarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rare|mythic"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;.await&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;"Filtered cards: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&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? Because as a developer I love how &lt;code&gt;Option&lt;/code&gt; and &lt;code&gt;Iterator&lt;/code&gt;, as well as crates such as &lt;code&gt;warp&lt;/code&gt;, implement this, giving Rust its "&lt;a href="https://doc.rust-lang.org/rust-by-example/fn/hof.html" rel="noopener noreferrer"&gt;functional flavour&lt;/a&gt;".&lt;/p&gt;

&lt;h3&gt;
  
  
  How to do it
&lt;/h3&gt;

&lt;p&gt;The function &lt;code&gt;filter()&lt;/code&gt; returns a struct called &lt;code&gt;Where&lt;/code&gt; that has a vector where I keep all the filters that are going to be added.&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;struct&lt;/span&gt; &lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Where&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&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;So, when I do something like &lt;code&gt;response = mtgsdk::card::filter()&lt;/code&gt;, the variable &lt;code&gt;response&lt;/code&gt; is a Where &lt;code&gt;struct&lt;/code&gt;, and that allows me to call any function implemented inside &lt;code&gt;Where&lt;/code&gt;, e.g.:&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;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;game_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.query&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;"gameFormat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
        &lt;span class="k"&gt;self&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;So basically, when I called &lt;code&gt;filter()&lt;/code&gt; and then added the functions &lt;code&gt;game_format()&lt;/code&gt;, &lt;code&gt;type_field()&lt;/code&gt;, &lt;code&gt;cmc()&lt;/code&gt; and &lt;code&gt;rarity()&lt;/code&gt; I was doing this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a &lt;code&gt;Where&lt;/code&gt; struct with &lt;code&gt;filter()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Called &lt;code&gt;game_format()&lt;/code&gt; implemented inside &lt;code&gt;Where&lt;/code&gt;, which returned the same &lt;code&gt;Where&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Called &lt;code&gt;type_field()&lt;/code&gt; from the &lt;code&gt;Where&lt;/code&gt; returned by &lt;code&gt;game_format()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Called &lt;code&gt;cmc()&lt;/code&gt; from the &lt;code&gt;Where&lt;/code&gt; returned by &lt;code&gt;type_field()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Called &lt;code&gt;rarity()&lt;/code&gt; from the &lt;code&gt;Where&lt;/code&gt; returned by &lt;code&gt;cmc()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Called &lt;code&gt;all()&lt;/code&gt; from the &lt;code&gt;Where&lt;/code&gt; returned by &lt;code&gt;rarity()&lt;/code&gt; which &lt;strong&gt;finally&lt;/strong&gt; returned the vector of cards:
&lt;/li&gt;
&lt;/ul&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;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="o"&gt;&amp;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;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.query&lt;/span&gt;&lt;span class="nf"&gt;.remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"?{}={}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.query&lt;/span&gt;&lt;span class="nf"&gt;.into_iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}&amp;amp;{}={}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&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;cards&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="n"&gt;RootAll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StatusCode&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;query_builder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cards"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;cards&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="py"&gt;.cards&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&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;And that's it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deserialize Json
&lt;/h2&gt;

&lt;p&gt;As promised.&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="nd"&gt;#[derive(Default,&lt;/span&gt; &lt;span class="nd"&gt;Debug,&lt;/span&gt; &lt;span class="nd"&gt;Clone,&lt;/span&gt; &lt;span class="nd"&gt;PartialEq,&lt;/span&gt; &lt;span class="nd"&gt;Serialize,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize)]&lt;/span&gt;
&lt;span class="nd"&gt;#[serde(rename_all&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"camelCase"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[serde(rename&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;type_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[serde(default)]&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;booster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Booster&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;release_date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;online_only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;gatherer_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;old_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;magic_cards_info_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;expansion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;mkm_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;mkm_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="o"&gt;&amp;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;Few things I want to mention:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;a href="https://transform.tools/json-to-rust-serde" rel="noopener noreferrer"&gt;transform&lt;/a&gt; tool helps quite a bit;&lt;/li&gt;
&lt;li&gt;In case &lt;code&gt;#[serde(rename_all = "camelCase")]&lt;/code&gt; is not sufficiently self-explanatory, it will allow a struct field like &lt;code&gt;release_date&lt;/code&gt; to receive data from a field that the API calls &lt;code&gt;releaseDate&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;There are two ways to handle optional fields:

&lt;ul&gt;
&lt;li&gt;Using &lt;a href="https://doc.rust-lang.org/core/option/enum.Option.html" rel="noopener noreferrer"&gt;Option&lt;/a&gt;, which I preferred because in this case the developer using the crate will have absolute certainty if the field wasn't (the Option will be &lt;code&gt;None&lt;/code&gt;) sent or if it was just empty (it will me &lt;code&gt;Some&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;#[serde(default)]&lt;/code&gt;, which I used for the mandatory fields because in these cases there's no doubt that the API sent them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Testing "as if" it was a crate
&lt;/h2&gt;

&lt;p&gt;I wanted to import it in a new project, but I didn't wanted to send it to crates.io. How to do it? Like this:&lt;/p&gt;

&lt;p&gt;In the new project's &lt;code&gt;Cargo.toml&lt;/code&gt; I added this:&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;mtgsdk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../mtgsdk"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;tokio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"full"&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;And that's all. In my &lt;code&gt;main.rs&lt;/code&gt; I just used it as if it was a crate.&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;use&lt;/span&gt; &lt;span class="nn"&gt;mtgsdk&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;46012&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="py"&gt;.name&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;This might be helpful if you want to be truthful to what The Book calls &lt;a href="https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html" rel="noopener noreferrer"&gt;integration testing&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;See ya 🙃&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image by &lt;a href="https://unsplash.com/photos/OvN4OkhkTLo" rel="noopener noreferrer"&gt;Wayne Low&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>reqwest</category>
      <category>api</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Teaching as a learning method</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Wed, 28 Apr 2021 12:19:09 +0000</pubDate>
      <link>https://dev.to/rogertorres/teaching-to-learn-3487</link>
      <guid>https://dev.to/rogertorres/teaching-to-learn-3487</guid>
      <description>&lt;p&gt;Hello everyone!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I am sharing the experience of using "teaching" as a "learning" method that can complement the usual approaches of "reading stuff" and "building projects".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A few weeks ago I wrote a &lt;a href="https://dev.to/rogertorres/rest-api-with-rust-warp-1-introduction-342e"&gt;5-part series about using &lt;strong&gt;Rust + Warp&lt;/strong&gt; to create a REST API&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;During the process of writing it, I made this comment in a post about &lt;a href="https://dev.to/salarc123/the-benefits-of-project-based-learning-3c14"&gt;The Benefits of Project-Base Learning&lt;/a&gt;:&lt;/p&gt;


&lt;div class="liquid-comment"&gt;
    &lt;div class="details"&gt;
      &lt;a href="/rogertorres"&gt;
        &lt;img class="profile-pic" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F558604%2F06edfb61-a122-472e-9c0d-c73d9eaf31f6.png" alt="rogertorres profile image"&gt;
      &lt;/a&gt;
      &lt;a href="/rogertorres"&gt;
        &lt;span class="comment-username"&gt;Roger Torres (he/him/ele)&lt;/span&gt;
      &lt;/a&gt;
      &lt;span class="color-base-30 px-2 m:pl-0"&gt;•&lt;/span&gt;

&lt;a href="https://dev.to/rogertorres/comment/1db2m" class="comment-date crayons-link crayons-link--secondary fs-s"&gt;
  &lt;time class="date-short-year"&gt;
    Apr 11 '21
  &lt;/time&gt;

&lt;/a&gt;

    &lt;/div&gt;
    &lt;div class="body"&gt;
      &lt;p&gt;I think the decision is heavily dependent on what you already know. Someone new to programming or new to a language/technology that is wildly different from their previous experiences will have a hard time navigating through the sources required to build a project. There's a minimum required to pull that off, and I think the books, tutorials, streams, and so on are more helpful to reach this threshold. That being said, once you are past this point, I totally agree that building projects is a magnificent approach. And I would also add something else: &lt;strong&gt;teaching is an astonishing way to learn things&lt;/strong&gt;, especially if you wanna go deep.&lt;/p&gt;


    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The comment was a summary of what was going on in my head during the writing of the series. Today, I decided to expand on that.&lt;/p&gt;




&lt;p&gt;In my previous experience as an SAP Analyst, I realized there were some complicated things (like Brazilian Taxes—they're a nightmare) that I would not fully understand even after delivering several successful projects in the subject matter. Nothing strange so far. However, things became weird when clients hired me to teach it to their internal team (correctly assuming I knew about it since I was actually &lt;em&gt;doing&lt;/em&gt; it). After going through a quick impostor syndrome crisis, I would study the topic for a few nights (because these calls were usually from one week to another) and then something magical happened: things that I used to do without knowing why I was doing them became crystal clear. Surely the previous experience helped. More than that, they were crucial because not only I had fun examples to give (always necessary to break the ice) but also because I knew that what I was saying tied to reality. In short, although I just had learned the &lt;em&gt;"whys"&lt;/em&gt;, I was already confident regarding the &lt;em&gt;"hows"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Nonetheless, there was something certainly going on regarding the &lt;em&gt;way&lt;/em&gt; I studied while preparing for these courses and I kept curious about it, wondering if I could isolate the method.&lt;/p&gt;

&lt;p&gt;I kept this in the back of my head but wasn't until I wrote the series of posts I mentioned earlier that I was able to engage in this process of explaining something to someone while also engaging in this self-reflexive effort of paying attention to the process itself, so I could identify &lt;strong&gt;&lt;em&gt;why&lt;/em&gt;&lt;/strong&gt; it worked.&lt;/p&gt;

&lt;p&gt;Here's what I found out.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;First.&lt;/strong&gt; I wasn't a good note-taker. I'm still not &lt;em&gt;very good&lt;/em&gt;, but my MA in Philosophy (don't ask me why an IT guy is doing such a thing) is forcing me to get better. However, when I have to teach/post, I am &lt;em&gt;forced&lt;/em&gt; to perform one of the most crucial steps when it comes to taking notes the right way: &lt;em&gt;writing the concepts with my own words in a way it would be intelligible to someone else if I explained it to them&lt;/em&gt;. In other words:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It is not enough to just read, you have to write what you read;&lt;/li&gt;
&lt;li&gt;It is not enough to just write, you must use your own words;&lt;/li&gt;
&lt;li&gt;It is not enough to just write using your own words, it must be intelligible to other people.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Related tip: If you want to get better at taking notes, google the &lt;em&gt;zettelkasten&lt;/em&gt; method. Even if it is not for you, it might give you some ideas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Second.&lt;/strong&gt; Many times while writing down what I would say in the classroom (or writing a blog post here or somewhere else), I realized I would anticipate questions that someone &lt;em&gt;could&lt;/em&gt; ask me, even though I knew they probably wouldn't; and by doing so I was pushing myself to go deeper while looking for these answers. &lt;/p&gt;

&lt;p&gt;It's just like that old anecdote: when you are searching for something, you stop looking as soon as you find it. And that's what I did in the projects I worked on: fixed the problem and moved on. In this scenario, however, by not knowing which specific question would be asked, I dove deeper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third.&lt;/strong&gt; The ideal scenario is having all the opportunities: time to read or watch good content, real projects to work on, and a way to share it with someone; but this is not always feasible. If you don't have a project that allows you to push yourself to learn (either because you lack ideas, enthusiasm, whatever) teaching may be a good alternative. Don't get me wrong, this is &lt;strong&gt;not&lt;/strong&gt; a replacement, it is an &lt;em&gt;option&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fourth.&lt;/strong&gt; This one might be counterintuitive, especially for the workaholic folks: sometimes not having a deadline might help. If you are already motivated, the opportunity to stretch some goals, to ask one more question, to try one more thing while everything is still fresh in your head allows you to boldly go where no one has gone before.&lt;/p&gt;




&lt;p&gt;I don't think that any teaching experience (whatever it may be, writing a blog post, showing a friend how to do something, taking notes for your future self...) can &lt;em&gt;replace&lt;/em&gt; other methods, but it is for sure a method worth considering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just be careful&lt;/strong&gt;: when you tell someone you will show them how to do something, people will trust that your content is valid, that what you're saying comes from good sources and/or experience, that your code actually works, and that you spent the time doublechecking the details and so on. That being said, if you are into this to learn (I am obviously not considering those who master what they're sharing in every way, that is, both the &lt;em&gt;whys&lt;/em&gt; and the &lt;em&gt;hows&lt;/em&gt;), you are not likely to ignore these steps, since you are not only the one teaching but also the first one learning.&lt;/p&gt;

&lt;p&gt;But what about you? What do &lt;em&gt;you&lt;/em&gt; think?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Cover image by &lt;strong&gt;&lt;a href="https://unsplash.com/photos/IgUR1iX0mqM" rel="noopener noreferrer"&gt;heylagostechie&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>rust</category>
      <category>learning</category>
    </item>
    <item>
      <title>REST API with Rust + Warp 5: Beyond test utilities</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Wed, 14 Apr 2021 12:21:44 +0000</pubDate>
      <link>https://dev.to/rogertorres/rest-api-with-rust-warp-5-beyond-test-utilities-15jo</link>
      <guid>https://dev.to/rogertorres/rest-api-with-rust-warp-5-beyond-test-utilities-15jo</guid>
      <description>&lt;p&gt;Last part, folks!&lt;/p&gt;




&lt;h2&gt;
  
  
  Time to say goodbye. Warp 5.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The code for this part is available &lt;a href="https://github.com/rogertorres/dev.to/tree/main/warp/warp5"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Warp's test utilities are great, but I didn't want to end this series without actually being able to serve what has been built and to &lt;code&gt;curl&lt;/code&gt; against it.&lt;/p&gt;

&lt;p&gt;To do so, I first created a &lt;code&gt;/src/bin/main.rs&lt;/code&gt; file. Then, I changed &lt;code&gt;Cargo.toml&lt;/code&gt; to add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[[bin]]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"holodeck"&lt;/span&gt;
&lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"src/bin/main.rs"&lt;/span&gt;

&lt;span class="nn"&gt;[lib]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"holodeck"&lt;/span&gt;
&lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"src/lib.rs"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I mentioned at the beginning, it is easier to find examples of code serving and consuming the API than testing it using the test utilities; so I'm gonna fly over it.&lt;/p&gt;

&lt;p&gt;My &lt;code&gt;main.rs&lt;/code&gt; ended up like this:&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="c1"&gt;// I made "models" and "filters" public in lib.rs&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;holodeck&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_db&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;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;list_sims&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post_sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
        &lt;span class="nf"&gt;.or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;update_sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
        &lt;span class="nf"&gt;.or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;delete_sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.run&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="mi"&gt;127&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3030&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&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;And that's all! I just had to put the filters together using &lt;code&gt;or&lt;/code&gt; and serve. The clones work because we're cloning an &lt;code&gt;Arc&lt;/code&gt;, which doesn't create a new copy, just a new reference to our &lt;code&gt;Mutex&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Below you will find some some &lt;code&gt;curl&lt;/code&gt;s I made.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --location --request POST 'localhost:3030/holodeck' \
--header 'Content-Type: application/json' \
--header 'Content-Type: text/plain' \
--data-raw '{
    "id": 1,
    "name": "The Big Goodbye"
}'

curl --location --request POST 'localhost:3030/holodeck' \
--header 'Content-Type: application/json' \
--header 'Content-Type: text/plain' \
--data-raw '{
    "id": 2,
    "name": "Bride Of Chaotica!"
}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PUT&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --location --request PUT 'localhost:3030/holodeck/3' \
--header 'Content-Type: application/json' \
--header 'Content-Type: text/plain' \
--data-raw '{
    "name": "A Fistful Of Datas"
}'

curl --location --request PUT 'localhost:3030/holodeck/3' \
--header 'Content-Type: application/json' \
--header 'Content-Type: text/plain' \
--data-raw '{
    "name": "A Fistful Of La Forges"
}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;GET&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --location --request GET 'localhost:3030/holodeck'

curl --location --request GET 'localhost:3030/holodeck/2'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --location --request DELETE 'localhost:3030/holodeck/1' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The good thing about using warp's test utilities is that when the time comes to serve what you built, there's no extra effort; no refactoring. So if you are using the tests, I strongly advise you to try some &lt;code&gt;curl&lt;/code&gt;s as well. Here are some problems that I just found when doing it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At some point, I deleted the &lt;code&gt;warp::get()&lt;/code&gt; from my &lt;code&gt;list_sims()&lt;/code&gt; and as a result answering every request I made;&lt;/li&gt;
&lt;li&gt;The serialization/deserialization in &lt;code&gt;PUT&lt;/code&gt; wasn't working properly. As this didn't appear in the tests, I assumed &lt;code&gt;serde&lt;/code&gt; was being so good at its job the ended up hiding a mistake I made in the code.&lt;/li&gt;
&lt;li&gt;Delete reply had the right Status, but the wrong written message.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The End
&lt;/h2&gt;

&lt;p&gt;What a journey! I really hope it ends up being useful to someone else.&lt;/p&gt;

&lt;p&gt;Before letting you go, I would like to write a small &lt;em&gt;mea culpa&lt;/em&gt;, to warn you about the things that are not ok regarding what was built here.&lt;/p&gt;

&lt;p&gt;My main goal was to show the &lt;strong&gt;process&lt;/strong&gt;, not the result; I didn't want to post a finished code and write a text explaining it. Although I am happy with this choice, it has some drawbacks. To make things clearer, I avoided creating and using too many functions that would compel the reader to check the previous code to make sense of it. So be aware that these things are not ok:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code repetition is problem number one. Tests are creating the same Simulations, there are repeated &lt;code&gt;use&lt;/code&gt; keywords everywhere and so on;&lt;/li&gt;
&lt;li&gt;I forced the HashMap, so it never felt "natural". I don't regret it because it gave me a chance to show you the trait implementation, but oftentimes it was a bit of a hassle;&lt;/li&gt;
&lt;li&gt;Warp provides building blocks, which means that there is more than one way of doing the same things, and naturally, some are better than others. I didn't stress this much, often going with the easiest way;&lt;/li&gt;
&lt;li&gt;The tests are &lt;em&gt;far away&lt;/em&gt; from actually checking everything that should be checked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I think that's enough. Really! Thank you for spending the time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Live long and prosper!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🖖&lt;/p&gt;

</description>
      <category>rust</category>
      <category>warp</category>
      <category>rest</category>
      <category>api</category>
    </item>
    <item>
      <title>REST API with Rust + Warp 4: PUT &amp; DELETE</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Wed, 14 Apr 2021 12:21:26 +0000</pubDate>
      <link>https://dev.to/rogertorres/rest-api-with-rust-warp-4-put-delete-3905</link>
      <guid>https://dev.to/rogertorres/rest-api-with-rust-warp-4-put-delete-3905</guid>
      <description>&lt;p&gt;That's it, the last methods. In the beginning, I thought it would be the end of the series, but then I realized it needed an additional post, regarding how to manually test it using &lt;code&gt;curl&lt;/code&gt;. However, before that, there are still two more methods to be coded. But don't worry, both combined are probably easier than the single ones we handled so far.&lt;/p&gt;




&lt;h2&gt;
  
  
  Warp 4, Mr. Sulu.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The code for this part is available &lt;a href="https://github.com/rogertorres/dev.to/tree/main/warp/warp4"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;PUT&lt;/code&gt; method is a mix between insert and change: it creates an entry when the data is not there and updates it when it is.&lt;/p&gt;

&lt;p&gt;This behavior is already met by our HashSet; this is exactly how the &lt;code&gt;insert()&lt;/code&gt; function works. However, we got to know if we are inserting or changing because the status that is returned got to be different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code 201 when it is created&lt;/li&gt;
&lt;li&gt;Code 200 when it is updated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where did I get this from? It is written &lt;a href="https://tools.ietf.org/html/rfc7231#section-4.3.4"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With that in mind, I wrote this code:&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="nd"&gt;#[tokio::test]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;try_update&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_db&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;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;update_sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PUT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/holodeck/1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The Big Goodbye"&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
        &lt;span class="nf"&gt;.reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CREATED&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PUT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/holodeck/1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The Short Hello"&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
        &lt;span class="nf"&gt;.reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&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;How did I knew that 201 was &lt;code&gt;StatusCode::CREATED&lt;/code&gt; and 200 was &lt;code&gt;StatusCode::OK&lt;/code&gt;? &lt;a href="https://tools.ietf.org/html/rfc7231#section-8.2.3"&gt;Here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As you can see, the &lt;code&gt;request&lt;/code&gt; is made by sending the parameter &lt;code&gt;id&lt;/code&gt; ("1", in this case). Different from &lt;code&gt;GET&lt;/code&gt;, this parameter is mandatory. And because the &lt;code&gt;id&lt;/code&gt; is already being sent in the URI, the body only contains the &lt;code&gt;name&lt;/code&gt;. The reasoning behind this is also in the aforementioned &lt;a href="https://tools.ietf.org/html/rfc7231#section-4.3.4"&gt;rfc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Because of this, I implemented a new struct and a new function to get the JSON body.&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="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;NewName&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This code is inside the mod "filters"&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;json_body_put&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Extract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NewName&lt;/span&gt;&lt;span class="p"&gt;,),&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rejection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Clone&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;content_length_limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;json&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 certainly a suboptimal way of doing this. But let's move on anyway; I am saving the excuses about the poor execution of things to the last part.&lt;/p&gt;

&lt;p&gt;Now, the filter and the handler.&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="c1"&gt;// This is inside the mod "filters"&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;update_sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Extract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rejection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Clone&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;db_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;path!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"holodeck"&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;json_body_put&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.and_then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;handle_update_sim&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;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;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle_update_sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NewName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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="k"&gt;impl&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Replaced entry&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;}){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Simulation #{} was updated.&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="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
            &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&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;span class="c1"&gt;// Create entry&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Simulation #{} was inserted.&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="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CREATED&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;And that's it!&lt;/p&gt;




&lt;h2&gt;
  
  
  Red alert
&lt;/h2&gt;

&lt;p&gt;To &lt;del&gt;warp&lt;/del&gt; wrap things up, the &lt;code&gt;DELETE&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;As usual, the request is quite simple: it sends the &lt;code&gt;id&lt;/code&gt; as a parameter and no body. As a response, we expect code 200 (OK) including a &lt;a href="https://tools.ietf.org/html/rfc7231#section-4.3.5"&gt;"representation describing the status"&lt;/a&gt;.&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="nd"&gt;#[tokio::test]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;try_delete&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;simulation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The Big Goodbye!"&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_db&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simulation&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;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;delete_sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DELETE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/holodeck/1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&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;Hopefully, nothing about the filter implementation seems strange to you:&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;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Extract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rejection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Clone&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;db_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;path!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"holodeck"&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.and_then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;handle_delete_sim&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;Since it is the first time we're deleting data, the handler has a unique behavior, but also nothing very different from what has been done so far.&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;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle_delete_sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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="k"&gt;impl&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),}){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Simulation #{} was deleted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
            &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&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;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No data was deleted."&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&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;That should do...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cargo test

running 5 tests
test tests::try_delete ... ok
test tests::try_create ... ok
test tests::try_list ... ok
test tests::try_create_duplicates ... ok
test tests::try_update ... ok

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it did!&lt;/p&gt;




&lt;h2&gt;
  
  
  In the next episode of &lt;em&gt;&lt;strong&gt;Engaging Warp&lt;/strong&gt;&lt;/em&gt;...
&lt;/h2&gt;

&lt;p&gt;Finally, the last part. We will serve what has been built and &lt;code&gt;curl&lt;/code&gt; against it.&lt;/p&gt;

&lt;p&gt;🖖&lt;/p&gt;

</description>
      <category>rust</category>
      <category>warp</category>
      <category>rest</category>
      <category>api</category>
    </item>
    <item>
      <title>REST API with Rust + Warp 3: GET</title>
      <dc:creator>Roger Torres (he/him/ele)</dc:creator>
      <pubDate>Wed, 14 Apr 2021 12:21:15 +0000</pubDate>
      <link>https://dev.to/rogertorres/rest-api-with-rust-warp-3-get-4nll</link>
      <guid>https://dev.to/rogertorres/rest-api-with-rust-warp-3-get-4nll</guid>
      <description>&lt;p&gt;Welcome back! Last time we saw each other I wrote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next in line is the &lt;code&gt;GET&lt;/code&gt; method, which means we'll see parameter handling and (finally) deal with this HashSet thing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, &lt;em&gt;"let us not waste our time in idle discourse!"&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Warp 3, make it so!
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The code for this part is available &lt;a href="https://github.com/rogertorres/dev.to/tree/main/warp/warp3"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, I needed another dependency to help me deserialize the &lt;code&gt;GET&lt;/code&gt; return, so I changed the &lt;code&gt;Cargo.toml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;serde_json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the time came to change &lt;code&gt;try_list()&lt;/code&gt;. As of our last encounter, this test had only a &lt;code&gt;request()&lt;/code&gt; and the &lt;code&gt;assert_eq!&lt;/code&gt;. I added two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before the request, I manually inserted two entries into the HashSet (I could've called &lt;code&gt;POST&lt;/code&gt;, but since it is already being tested elsewhere, it is ok to take this shortcut);&lt;/li&gt;
&lt;li&gt;After the request, I deserialized the HTML body and compared its content to the data I had previously inserted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's a chance that a few things will appear weird, but don't worry, I will go through each one of them.&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::test]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;try_list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;serde_json&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;simulation1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The Big Goodbye"&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;simulation2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bride Of Chaotica!"&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_db&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simulation1&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simulation2&lt;/span&gt;&lt;span class="nf"&gt;.clone&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;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;list_sims&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/holodeck"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&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;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.into_body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.into_iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;str&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&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;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Simulation&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;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_simulation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;simulation1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_simulation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;simulation2&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/holodeck/2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&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;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.into_body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.into_iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;str&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&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;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Simulation&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;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_simulation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;simulation2&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;The first thing I take as deserving an explanation is the &lt;code&gt;db.lock().await.insert()&lt;/code&gt;. The &lt;code&gt;lock()&lt;/code&gt; gives you what's inside the Arc, and in this case, it returns a &lt;a href="https://cfsamson.github.io/books-futures-explained/1_futures_in_rust.html"&gt;Future&lt;/a&gt;. Why? Because we are not using &lt;code&gt;std::sync::Mutex&lt;/code&gt;, but &lt;code&gt;tokio::sync::Mutex&lt;/code&gt;, which is an Async implementation of the former. That's why we don't &lt;code&gt;unwrap()&lt;/code&gt;, but instead &lt;code&gt;await&lt;/code&gt;, as we need to &lt;a href="https://doc.rust-lang.org/std/keyword.await.html"&gt;suspend execution until the result of the Future is ready&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Moving on, &lt;code&gt;filters::list_sims()&lt;/code&gt; is now getting a parameter, which is the data it will return (which, in a real execution, would come from the HTTP body).&lt;/p&gt;

&lt;p&gt;After the request—that remains the same—there are three lines of Bytes-handling-jibber-jabber.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.rs/bytes/1.0.1/bytes/struct.Bytes.html"&gt;Bytes&lt;/a&gt; is the format with which &lt;em&gt;warp&lt;/em&gt;'s &lt;a href="https://docs.rs/warp/0.3.1/warp/test/struct.RequestBuilder.html"&gt;RequestBuilder&lt;/a&gt; handles the HTML body content. It &lt;em&gt;looks like&lt;/em&gt; a [u8] (that is, an array of the primitive u8], but it is a little bit more painful to handle. What I did with it, however, is simple. I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mapped its content to a Vector of u8&lt;/li&gt;
&lt;li&gt;Moved the Vector's content to the slice&lt;/li&gt;
&lt;li&gt;Used &lt;code&gt;serde_json::from_str()&lt;/code&gt; function to map it to the Simulation struct inside the HashSet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is one of the reasons I wanted a HashSet. As far as I know, standard Rust doesn't allow you to create a HashMap referring to a struct of two fields; that is, you cannot do that:&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="err"&gt;\\&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="nd"&gt;project!&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;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;type&lt;/span&gt; &lt;span class="n"&gt;Impossible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And without using a struct as I did with the HashMap (as well as the cool kids did with Vector &lt;a href=""&gt;here&lt;/a&gt; at line 205), using &lt;code&gt;serde&lt;/code&gt; gets... &lt;em&gt;complicated&lt;/em&gt; (which means I have no idea how to do it).&lt;/p&gt;

&lt;p&gt;Nonetheless, there is another reason why I wanted to stick the struct within the HashSet: it gave me the chance to implement some traits for my type.&lt;/p&gt;

&lt;p&gt;Before diving into the traits, I would like to explain the last part of the test (which should be a different test, but the example is already too big). &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GET&lt;/code&gt; method can be used in three different ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fetch all the entries: &lt;code&gt;/holodeck&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Fetch a single entry: &lt;code&gt;/holodeck/:id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Fetch filtered entries: &lt;code&gt;/holodeck/?search=query&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This last &lt;code&gt;request()&lt;/code&gt; using path &lt;code&gt;/holodeck/2&lt;/code&gt; was written to cover the second case. I did not (and will not) develop the third one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Boldly implementing traits
&lt;/h2&gt;

&lt;p&gt;If you compare the HashSet element with another, it will compare everything. That's no good if you have a key-value-pair struct. As I didn't want to use HashMap because of the aforementioned reasons, the way to go is to change this behavior, making comparisons only care about the id.&lt;/p&gt;

&lt;p&gt;First, I brought &lt;code&gt;Hash&lt;/code&gt; and &lt;code&gt;Hasher&lt;/code&gt;, then I removed the &lt;code&gt;Eq&lt;/code&gt;, &lt;code&gt;PartialEq&lt;/code&gt; and &lt;code&gt;Hash&lt;/code&gt;, so I could implement them myself. And the implementation was this:&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;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Hasher&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Simulation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;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;impl&lt;/span&gt; &lt;span class="nb"&gt;PartialEq&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;Eq&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Simulation&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Hash&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Hasher&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="nf"&gt;.hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&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;How did I know how to do it? I just followed the documentation where it says &lt;a href="https://doc.rust-lang.org/std/cmp/trait.Eq.html#how-can-i-implement-eq"&gt;"How can I implement Eq?"&lt;/a&gt;. Yes, Rust docs are that good.&lt;/p&gt;

&lt;p&gt;And what about Hash? Same thing. But it is interesting to note why I did it. HashSet requires the &lt;a href="https://doc.rust-lang.org/std/hash/trait.Hash.html"&gt;Hash&lt;/a&gt; trait, and the Hash trait demands this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;k1 == k2 -&amp;gt; hash(k1) == hash(k2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means, if the values you're comparing are equal, their hashes also have to be equal, which would not hold after the implementation of &lt;code&gt;PartialEq&lt;/code&gt; and &lt;code&gt;Eq&lt;/code&gt; because both values were being hashed and compared, while the direct comparison only cared about &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;99% chance that I am wrong, but I think it should not be an implication (→), but a biconditional (↔), because the way it stands if &lt;code&gt;k1 == k2&lt;/code&gt; is false and &lt;code&gt;hash(k1) == hash(k2)&lt;/code&gt; is true, the implication's result is still true. But I am not a trained computer scientist and I am not sure this uses first-order logic notation. Let me know in the comments if you do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One last addition I made below the Hash implementation was this:&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="n"&gt;get_simulation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sims&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sims&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&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;Even though the only relevant field for comparisons is &lt;code&gt;id&lt;/code&gt; when using methods such as &lt;code&gt;get()&lt;/code&gt; we have to pass the entire struct, so I created &lt;code&gt;get_simulation()&lt;/code&gt; to replace it.&lt;/p&gt;

&lt;p&gt;Ok, back to the &lt;code&gt;GET&lt;/code&gt; method.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting away with it
&lt;/h2&gt;

&lt;p&gt;The functions dealing with the &lt;code&gt;GET&lt;/code&gt; method now have to deal with two additional information, the HashSet from where it will fetch the result and the parameter that might be used.&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;list_sims&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Extract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rejection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Clone&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;db_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.clone&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;opt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;param&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.or_else&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
            &lt;span class="c1"&gt;// Ok(None) &lt;/span&gt;
            &lt;span class="nn"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,),&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;path!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"holodeck"&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.and_then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;handle_list_sims&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;The &lt;code&gt;opt&lt;/code&gt; represents the optional parameter that can be sent. It gets a param, map it as an &lt;code&gt;Option&lt;/code&gt; (i.e., &lt;code&gt;Some&lt;/code&gt;). If it was not provided, the &lt;code&gt;or_else()&lt;/code&gt; returns a &lt;code&gt;None&lt;/code&gt;. The reason why there's and &lt;code&gt;async&lt;/code&gt; there is because &lt;code&gt;or_else()&lt;/code&gt; &lt;a href="https://docs.rs/warp/0.3.1/warp/trait.Filter.html#method.or_else"&gt;returns a TryFuture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;path&lt;/code&gt; we are actually returning includes this &lt;code&gt;opt&lt;/code&gt; the same way we included the &lt;code&gt;db_bap&lt;/code&gt;. the &lt;code&gt;/ ..&lt;/code&gt; at the and of &lt;code&gt;path!&lt;/code&gt; is there to tell the macro to not add the &lt;code&gt;end()&lt;/code&gt; so I could add the &lt;code&gt;opt&lt;/code&gt;. That's why there's a manual &lt;code&gt;end()&lt;/code&gt; there soon after.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I didn't found this solution in the docs or in the examples. Actually, for some reason, most tutorials omit &lt;code&gt;GET&lt;/code&gt; parameters. They either just list everything or use query. I found one tutorial that implemented this, but they did so by creating two filters and two handlers. It didn't felt ok, and I knew there should be a solution and that the problem was probably my searching skills; so I asked for help in warp's discord channel, and the nice gentleman &lt;strong&gt;jxs&lt;/strong&gt; &lt;a href="https://github.com/seanmonstar/warp/issues/586"&gt;pointed me to the solution you saw above&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The next step was to fix the handler:&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;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle_list_sims&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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="k"&gt;impl&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.retain&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&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;It is no longer a &lt;em&gt;Matthew McConaughey handler&lt;/em&gt;, but still very simple. I am using &lt;code&gt;retain&lt;/code&gt; instead of a &lt;code&gt;get_simulation()&lt;/code&gt; because it returns a HashSet (and get would give me a &lt;code&gt;models::Simulation&lt;/code&gt;), which is exactly what the handler must return.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cargo test

running 3 tests
test tests::try_create ... ok
test tests::try_create_duplicates ... ok
test tests::try_list ... ok

test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  In the next episode of &lt;em&gt;&lt;strong&gt;Engaging Warp&lt;/strong&gt;&lt;/em&gt;...
&lt;/h2&gt;

&lt;p&gt;We will finish the implementation by implementing the &lt;code&gt;PUT&lt;/code&gt; and &lt;code&gt;DELETE&lt;/code&gt; methods. &lt;/p&gt;

&lt;p&gt;🖖&lt;/p&gt;

</description>
      <category>rust</category>
      <category>warp</category>
      <category>rest</category>
      <category>api</category>
    </item>
  </channel>
</rss>
