<?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: Sven Kanoldt</title>
    <description>The latest articles on DEV Community by Sven Kanoldt (@5422m4n).</description>
    <link>https://dev.to/5422m4n</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%2F34033%2F965f9371-0f1d-4720-8400-0f190b653b35.png</url>
      <title>DEV Community: Sven Kanoldt</title>
      <link>https://dev.to/5422m4n</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/5422m4n"/>
    <language>en</language>
    <item>
      <title>What is a CIDR trie and how can it help you?</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Tue, 28 May 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/5422m4n/what-is-a-cidr-trie-and-how-can-it-help-you-2chc</link>
      <guid>https://dev.to/5422m4n/what-is-a-cidr-trie-and-how-can-it-help-you-2chc</guid>
      <description>&lt;p&gt;In this post, we will explore the CIDR trie data structure and how it can help you manage IP addresses and subnets in your Rust project.&lt;/p&gt;

&lt;p&gt;As usual in this series, we will take a tiny piece of Rust out of a real project and explain it in a very practical way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Imagine that your Rust service should only be available from specific IP addresses. This may be desirable for limiting access to certain geographical regions (similar to geo-fencing) or other services you control.&lt;/p&gt;

&lt;p&gt;This service should not be slowed down by the need to check every incoming request's IP address against a list of allowed IP addresses.&lt;/p&gt;

&lt;p&gt;Let's have a look at the size of the &lt;a href="https://github.com/sapics/ip-location-db/blob/main/geo-whois-asn-country/geo-whois-asn-country-ipv4.csv"&gt;geo-whois-asn-country-ipv4.csv&lt;/a&gt; file that only contains ipv4 addresses: it contains 243K entries and is about 7.13 MB in size. Simply checking every incoming request against this list with &lt;code&gt;Vec::contains&lt;/code&gt; is obviously too inefficient.&lt;/p&gt;

&lt;p&gt;Furthermore, the problem is that we don't have the list of all single IP addresses that we can search, but we have a list of IP ranges, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;from &lt;code&gt;1.10.10.0&lt;/code&gt; to &lt;code&gt;1.10.10.255&lt;/code&gt; belongs to &lt;code&gt;IN&lt;/code&gt;/India&lt;/li&gt;
&lt;li&gt;from &lt;code&gt;1.5.0.0&lt;/code&gt; to &lt;code&gt;1.5.255.255&lt;/code&gt; belongs to &lt;code&gt;JP&lt;/code&gt;/Japan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and so on.&lt;/p&gt;

&lt;p&gt;Now when a client connects to our service we have to check a single IP to those given ranges and decide if the client is allowed to connect or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Let's first introduce a slightly different format for those IP ranges, the  CIDR notation. &lt;a href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation"&gt;CIDR stands for Classless Inter-Domain Routing&lt;/a&gt;, and it is a compact way to represent an IP address range. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1.10.10.0&lt;/code&gt; to &lt;code&gt;1.10.10.255&lt;/code&gt; will be represented as &lt;code&gt;1.10.10.0/24&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1.5.0.0&lt;/code&gt; to &lt;code&gt;1.5.255.255&lt;/code&gt; will be represented as &lt;code&gt;1.5.0.0/16&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the suffix &lt;code&gt;/24&lt;/code&gt; or &lt;code&gt;/16&lt;/code&gt; tells us how many leading bits of the IP address are fixed. Keep in mind that a full ipv4 address has 32 bits. That means if &lt;code&gt;24&lt;/code&gt; bits are fixed, the remaining &lt;code&gt;8&lt;/code&gt; bits are variable, and as we will see later, not important to us.&lt;/p&gt;

&lt;p&gt;For the post we will assume we already have an efficient way of converting the range format above to the CIDR notation. We now want to find a data structure that is well-suited to searching for the country of a given IP address.&lt;/p&gt;

&lt;p&gt;We ultimately want to use the data structure in our service 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;// usage example&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;country_ip_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CidrCountryMap&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;country_ip_list&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;"1.10.10.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"IN"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;country_ip_list&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;"1.5.0.0/16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"JP"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// search for the country of the given IP address&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;country_ip_list&lt;/span&gt;&lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.10.10.1"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IN"&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;country_ip_list&lt;/span&gt;&lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.10.10.22"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IN"&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;country_ip_list&lt;/span&gt;&lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.5.0.1"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JP"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// not in the list&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;country_ip_list&lt;/span&gt;&lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"10.1.1.1"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: this code is pseudo code. In production we would likely not use strings for the IP addresses, but the &lt;code&gt;std::net::Ipv4Addr&lt;/code&gt; &lt;a href="https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html"&gt;type of the std lib&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;CidrCountryMap&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One data structure we could base the &lt;code&gt;CidrCountryMap&lt;/code&gt; on is a specialized trie. In it's most generic form, it can be used to search based on the prefix of an element (e.g. the first few letters of a string).&lt;/p&gt;

&lt;p&gt;But let's first look at what a trie is and it's use case. &lt;a href="https://en.wikipedia.org/wiki/Trie"&gt;According to wikipedia&lt;/a&gt;, a trie is also called &lt;em&gt;digital tree&lt;/em&gt; or &lt;em&gt;prefix tree&lt;/em&gt;. To quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unlike a binary search tree, nodes in the trie do not store their associated key. Instead, a node's position in the trie defines the key with which it is associated. This distributes the value of each key across the data structure, and means that not every node necessarily has an associated value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the gist is, we would not store full values on nodes, but the data (that we want to store) will distribute on several nodes in the tree on a path. A path starting at the root (usally visualized on the top) leading down to a leaf (last not in the tree) or a &lt;em&gt;terminal&lt;/em&gt; node.&lt;/p&gt;

&lt;p&gt;This data distribution on paths comes with some very neat properties: the time it takes to search for an item, depends only on the key length, not on the amount of stored items. The same is true for inserting items.&lt;/p&gt;

&lt;h3&gt;
  
  
  The CIDR trie specifics
&lt;/h3&gt;

&lt;p&gt;In the CIDR trie we represent a bit of the IP address as a node on the path. The complete path from the root to a (terminal) leaf node therefore represents the fixed bits of the IP address (without the trailing masked bits). The leaf node furthermore stores the country code associated with the IP address range.&lt;/p&gt;

&lt;p&gt;For example let's look at the IP range &lt;code&gt;1.10.10.0/24&lt;/code&gt; and their single bytes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1  -&amp;gt; 00000001
10 -&amp;gt; 00001010
10 -&amp;gt; 00001010
0  -&amp;gt; 00000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the &lt;code&gt;/24&lt;/code&gt; suffix tells us that the first 24 bits are the ones we are taking into account. That means we don't store the last 8 bits of the IP range.&lt;/p&gt;

&lt;p&gt;So we can build a trie just as we would read those binary numbers, that looks like this (showing only the first 2 bytes):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---9KPleOY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://d34dl0ck.me/cidr-trie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---9KPleOY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://d34dl0ck.me/cidr-trie.png" width="800" height="812"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the illustration we can see path that the first 16 bit of the IP address would span. The nodes of the 3rd byte are not shown, to keep the illustration simple. But just imagine a continued path down to the leaf node. The leaf node would contain the country code and also would be marked as a terminal node.&lt;/p&gt;

&lt;p&gt;That means when we want to search for the country of the IP address, we must just process the bits of the given IP address and follow the path in the trie. If we reach a terminal node, we have found the country code.&lt;/p&gt;

&lt;p&gt;That is the basic idea of the CIDR trie. Let's implement this trie in Rust now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Let's introduce the &lt;code&gt;CidrCountryMap&lt;/code&gt; struct that holds the trie and the methods to insert and search for a given IP address.&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="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;CidrCountryMap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Node&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;Node&lt;/code&gt; struct represents a single node in the trie. It holds the country code, the child nodes and it keeps the information if it's a terminal node in the whole trie or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Default)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;is_terminal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&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;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&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;value&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: we're using a fixed size array of for 2 Nodes (&lt;code&gt;children: [Option&amp;lt;Box&amp;lt;Node&amp;gt;&amp;gt;;2]&lt;/code&gt;) to represent the child nodes. This is a common pattern in Rust to represent a tree structure. This avoids further allocations when inserting nodes. Just in case, could also use a &lt;code&gt;Vec&lt;/code&gt; instead of an array. Also this is specific to a binary trie, e.g. for storing arbitrary ASCII characters we would have to (pre-)allocate 256 children (one per character). In that case it would be better to use a &lt;code&gt;HashMap&lt;/code&gt; insteaf of a fixed size array.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We have to use &lt;code&gt;Box&lt;/code&gt; because Rust does not allow recursive types that are not on the heap.&lt;/p&gt;

&lt;p&gt;Let's implement the &lt;code&gt;CidrCountryMap&lt;/code&gt; insert method.&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="n"&gt;CidrCountryMap&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;insert&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="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cidr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&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;Into&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;-&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="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="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cidr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;take_bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cidr&lt;/span&gt;
            &lt;span class="nf"&gt;.split_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.ok_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CidrCountryMapError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SplitError&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;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;take_bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;take_bits&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;usize&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_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;CidrCountryMapError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;ParseIntError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&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;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;current_node&lt;/span&gt; &lt;span class="o"&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="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.root&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;byte&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cidr&lt;/span&gt;&lt;span class="nf"&gt;.split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.flat_map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;octet&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;octet&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;u8&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;for&lt;/span&gt; &lt;span class="n"&gt;bi&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&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;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.rev&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;take_bits&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;break&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;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;current_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.get_or_insert&lt;/span&gt;&lt;span class="p"&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;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="n"&gt;take_bits&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="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.is_terminal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.value&lt;/span&gt; &lt;span class="o"&gt;=&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;data&lt;/span&gt;&lt;span class="nf"&gt;.into&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="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;it splits the CIDR notation into the IP address and the number of bits&lt;/li&gt;
&lt;li&gt;it iterates over the bytes of the IP address and the bits of the CIDR notation&lt;/li&gt;
&lt;li&gt;it processes the bits from left to right by using bit shifting and masking &lt;code&gt;(byte &amp;gt;&amp;gt; bi) &amp;amp; 1&lt;/code&gt; (bi is the amount of bits we shift to the right)

&lt;ul&gt;
&lt;li&gt;first we shift by 7 bits, then by 6 bits, then by 5 bits and so on&lt;/li&gt;
&lt;li&gt;after shifting the bits to the right we select the right-most bit with the mask &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;by doing so we iterate through the bits of the byte from left to right&lt;/li&gt;
&lt;li&gt;this gives either true or false (1 or 0) and we use this as an index to access the child array&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;we take or insert a new node in the trie for each bit&lt;/li&gt;
&lt;li&gt;after all &lt;code&gt;current_node&lt;/code&gt; is the leaf node and we set the country code and mark it as terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: You might wonder about the the use of &lt;code&gt;Result&amp;lt;()&amp;gt;&lt;/code&gt; and &lt;code&gt;CidrCountryMapError&lt;/code&gt;. I kept it out on purpose to keep the code simple and not use &lt;code&gt;.unwrap()&lt;/code&gt;. You can find the full code in playground link on the References section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The search method is quite similar to the insert method. We just have to iterate over the bits of the IP address and follow the path in the trie.&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="n"&gt;CidrCountryMap&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;search&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;cidr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="nb"&gt;str&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;current_node&lt;/span&gt; &lt;span class="o"&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="py"&gt;.root&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;byte&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cidr&lt;/span&gt;&lt;span class="nf"&gt;.split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.flat_map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;octet&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;octet&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;u8&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;for&lt;/span&gt; &lt;span class="n"&gt;bi&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&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;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.rev&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;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bi&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;0b1&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;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;current_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.is_terminal&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="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="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="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.value&lt;/span&gt;&lt;span class="nf"&gt;.as_deref&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;ul&gt;
&lt;li&gt;we break the loop if we reach a terminal node&lt;/li&gt;
&lt;li&gt;we return &lt;code&gt;None&lt;/code&gt; if we reach a node that has no children&lt;/li&gt;
&lt;li&gt;we return the country code of the end node, the leaf node, if we reach the end of the IP address&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Searching an IP Address in the CIDR trie is done in &lt;code&gt;O(k)&lt;/code&gt; time complexity. Where &lt;code&gt;k&lt;/code&gt; is the number of bits in the IP Adress to look up, so &lt;code&gt;O(32)&lt;/code&gt;. It may also take less than &lt;code&gt;O(k)&lt;/code&gt; time when the IP is not present in the trie.&lt;/p&gt;

&lt;p&gt;The CIDR trie is a very efficient data structure to search for IP addresses in a given range.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: For other more complex use cases it might be better to roll the &lt;code&gt;trie_rs&lt;/code&gt; crate, which provides a more generic trie implementation. However, I want to encourage you to mind a clean and small dependency list in your projects. Be aware that every external dependency comes with the cost of maintenance and less control over security and stability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Improvement ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we could store the whole trie Nodes in a single &lt;code&gt;Vec&lt;/code&gt; to avoid multiple allocations and to improve cache locality&lt;/li&gt;
&lt;li&gt;we could compress the trie by combining nodes that have only one child, this approach is then called to be a &lt;a href="https://en.wikipedia.org/wiki/Radix_tree"&gt;Radix Trie&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;we could store the country code in a separate vector and use the index as a reference in the trie nodes, to save memory and to avoid storing the country code multiple times&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Special thanks to Jonas and David for providing feedback and improvement suggestions to this post 🙏 🦀 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=040d97e3ee3e38ec5b5e4ca34adedbf7"&gt;Full Code on the Rust-Playground&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/introduction-to-trie-data-structure-and-algorithm-tutorials/#what-is-trie-data-structure"&gt;Introduction to trie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/trie-insert-and-search/"&gt;Insert and search for Trie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/trie-rs/latest/trie_rs/"&gt;For more complex tries is a crate available: trie_rs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>datastructures</category>
      <category>algorithms</category>
      <category>rust</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What is the matter with `AsRef`?</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Tue, 09 Aug 2022 15:33:11 +0000</pubDate>
      <link>https://dev.to/5422m4n/what-is-the-matter-with-asref-271p</link>
      <guid>https://dev.to/5422m4n/what-is-the-matter-with-asref-271p</guid>
      <description>&lt;p&gt;the &lt;code&gt;AsRef&lt;/code&gt; trait is everywhere in the std lib and very handy. However, the benefit using it is maybe not too obvious. But read on, and you will see some useful examples and where to apply it.&lt;/p&gt;

&lt;p&gt;This is the 2nd post on the series &lt;a href="https://d34dl0ck.me/tags/practical-rust-bites/index.html"&gt;"practical rust bites"&lt;/a&gt; that shows very tiny pieces of rust taken out of practical real projects. It aims to illustrate only one rust idiom or concept at a time with very practical examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;AsRef&lt;/code&gt; can be &lt;a href="https://doc.rust-lang.org/std/convert/trait.AsRef.html"&gt;found in the&lt;/a&gt; &lt;code&gt;std::convert&lt;/code&gt; module and is used &lt;br&gt;
for cheap reference-to-reference conversion.&lt;/p&gt;

&lt;p&gt;It's a very essential trait widely used in the std library and helps with seamless reference conversions from one type to another. &lt;br&gt;
Often it is at play, and you do not even realize it is there.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example: &lt;code&gt;String&lt;/code&gt; or &lt;code&gt;&amp;amp;str&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Did you ever have had a function where you wanted to accept a string as a parameter?&lt;br&gt;
You might then also have asked yourself should you accept a string reference (as in &lt;code&gt;&amp;amp;str&lt;/code&gt;) or an owned string (as in &lt;code&gt;String&lt;/code&gt;)?&lt;/p&gt;

&lt;p&gt;So you would have something like this in mind:&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;take_a_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the other one:&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;take_a_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;some&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;So why not have both?!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this very point &lt;code&gt;AsRef&amp;lt;str&amp;gt;&lt;/code&gt; comes in very handy, &lt;br&gt;
because both types &lt;a href="https://doc.rust-lang.org/std/primitive.str.html#impl-AsRef%3Cstr%3E"&gt;&lt;code&gt;str&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/std/primitive.str.html#impl-AsRef%3Cstr%3E-1"&gt;&lt;code&gt;String&lt;/code&gt;&lt;/a&gt; implement this trait.&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;take_a_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;some&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;AsRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;str&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;let&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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;"{some}"&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="nf"&gt;take_a_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"str"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;take_a_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"String"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// also `&amp;amp;String` is supported:&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;string_ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"StringRef"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;take_a_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="n"&gt;string_ref&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=ccb7bce2bc6db0dd2e5e5a58fa7e9c61"&gt;check out the code on the playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see this version of &lt;code&gt;take_a_str&lt;/code&gt; accepts a type that just implements &lt;code&gt;AsRef&amp;lt;str&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By doing so &lt;code&gt;some: impl AsRef&amp;lt;str&amp;gt;&lt;/code&gt; does not make any concrete assumptions on the type that is provided. &lt;br&gt;
Instead, it just insists that any given type only implements this trait.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example: wrapper type
&lt;/h2&gt;

&lt;p&gt;In this example we want to focus on how can you implement &lt;code&gt;AsRef&lt;/code&gt; yourself for any arbitrary struct.&lt;/p&gt;

&lt;p&gt;Let's look at this tiny program:&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;Envelope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;letter&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;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;a_letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Envelope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"a poem"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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;"this is a letter: {}"&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;a_letter&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;But of course you'd say now, well, it does not implement &lt;code&gt;Display&lt;/code&gt; and so does the rust compiler agree with you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0277]: `Envelope` doesn't implement `std::fmt::Display`
  --&amp;gt; src/main.rs:10:38
   |
10 |     println!("this is a letter: {}", &amp;amp;a_letter);
   |                                      ^^^^^^^^^ `Envelope` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `Envelope`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we ignore &lt;code&gt;Display&lt;/code&gt; for now and focus on another use case. That is we want to access the inner value of &lt;code&gt;Envelope&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Solving this problem with implementing &lt;code&gt;AsRef&amp;lt;str&amp;gt;&lt;/code&gt; we would do the following:&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="nb"&gt;AsRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Envelope&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;as_ref&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// here we up-call to the `AsRef&amp;lt;str&amp;gt;` implementation for String&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.letter&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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 with this we need just one little adjustment:&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a_letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Envelope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"a poem"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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;"this is a letter: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a_letter&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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;Now the rust compiler does not complain anymore.&lt;/p&gt;

&lt;p&gt;Again, of course it would be appropriate to implement &lt;code&gt;Display&lt;/code&gt; for this very &lt;code&gt;println!&lt;/code&gt; case, but the point is here that we would want to access the inner data as reference. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=ff6dd63f6f6bc0d08b20b319397cd087"&gt;check out the full example on the playground&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: a composed type
&lt;/h2&gt;

&lt;p&gt;I have to admit, take this example with a grain of salt. It's very likely that this kind of usage&lt;br&gt;
would lead to problems with bigger structs. So as a rule of thumb if a struct has more than 2 fields, better not go down this path.&lt;/p&gt;

&lt;p&gt;let's look at a simple struct that represents a weight:&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;struct&lt;/span&gt; &lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;unit&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;impl&lt;/span&gt; &lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/// Weight in Tons that is 157.47 stones &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;from_tons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&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="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"t"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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="cd"&gt;/// Weight in Stones&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;from_stones&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&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="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"st"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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 we have not given &lt;code&gt;pub&lt;/code&gt; fields and also no getter accessor functions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So how we can actually get our hand on the data inside?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You've guessed it, &lt;code&gt;AsRef&lt;/code&gt; is our friend here 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;impl&lt;/span&gt; &lt;span class="nb"&gt;AsRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Weight&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;as_ref&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.unit&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;AsRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Weight&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;as_ref&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;f32&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="py"&gt;.weight&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 here we use the &lt;code&gt;AsRef&lt;/code&gt; trait for the types &lt;code&gt;f32&lt;/code&gt; and &lt;code&gt;str&lt;/code&gt; to get access to the weight and unit inside the struct.&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a_ton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Weight&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_tons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.3&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;tons&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;f32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a_ton&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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;unit&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;=&lt;/span&gt; &lt;span class="n"&gt;a_ton&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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;"a weight of {tons} {unit}"&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 also skip the variable bindings and make it less verbose:&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a_ton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Weight&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_tons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.3&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;"a weight of {} {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;a_ton&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;a_ton&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=be1a8d34116766920dda8e6abd082600"&gt;checkout the full example on the playground&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;AsRef&lt;/code&gt; is a very handy tool and if you go through the standard library, you will find it implemented for a lot of types. &lt;br&gt;
By this a lot of reference types become interchangeable and this increases the overall ergonomics a lot.&lt;/p&gt;

&lt;p&gt;As you also have seen how &lt;code&gt;AsRef&lt;/code&gt; can be useful to get access to inner data of structs without having to provide accessory methods or public fields.&lt;/p&gt;

&lt;p&gt;A very related function to get the inner value of a struct, but as value (not as reference) is the &lt;a href="https://doc.rust-lang.org/std/convert/trait.Into.html?search=into_inner"&gt;.into_inner()&lt;/a&gt;. &lt;br&gt;
As you can see it is used a lot in the std lib, but it is not bound to a trait. So this is more of a convention: Whenever you need to consume a struct and unfold the inner wrapped type, then &lt;code&gt;.into_inner()&lt;/code&gt; is the common schema to go for.&lt;/p&gt;

&lt;p&gt;Versions used for this post:&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="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rustc &lt;span class="nt"&gt;--version&lt;/span&gt;
cargo 1.61.0 &lt;span class="o"&gt;(&lt;/span&gt;a028ae42f 2022-04-29&lt;span class="o"&gt;)&lt;/span&gt;
rustc 1.61.0 &lt;span class="o"&gt;(&lt;/span&gt;fe5b13d68 2022-05-18&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To receive updates about new blog post and other rust related news you can &lt;a href="https://twitter.com/5422m4n"&gt;follow me on twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>programming</category>
      <category>bites</category>
    </item>
    <item>
      <title>🎉 🚀 🍺 New release of Terminal Recorder - t-rec</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Mon, 12 Oct 2020 16:00:15 +0000</pubDate>
      <link>https://dev.to/5422m4n/new-release-of-terminal-recorder-t-rec-36g0</link>
      <guid>https://dev.to/5422m4n/new-release-of-terminal-recorder-t-rec-36g0</guid>
      <description>&lt;p&gt;Blazingly fast terminal recorder that generates animated gif images for the web written in rust for MacOS.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mMmABu_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/sassman/t-rec-rs/raw/main/docs/demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mMmABu_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/sassman/t-rec-rs/raw/main/docs/demo.gif" alt="demo" width="560" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Screenshotting your terminal with 4 frames per second (every 250ms)&lt;/li&gt;
&lt;li&gt;Generates high quality small sized animated gif images&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build-In idle frames detection and optimization&lt;/strong&gt; (for super fluid presentations)&lt;/li&gt;
&lt;li&gt;Runs (only) on MacOS&lt;/li&gt;
&lt;li&gt;Uses native efficient APIs&lt;/li&gt;
&lt;li&gt;Runs without any cloud service and entirely offline&lt;/li&gt;
&lt;li&gt;No issues with terminal sizes larger than 80x24&lt;/li&gt;
&lt;li&gt;No issues with fonts or colors&lt;/li&gt;
&lt;li&gt;No issues with curses based programs&lt;/li&gt;
&lt;li&gt;No issues with escape sequences&lt;/li&gt;
&lt;li&gt;No record and replay - just one simple command to rule them all&lt;/li&gt;
&lt;li&gt;Hidden feature: Record every window you want&lt;/li&gt;
&lt;li&gt;Written in Rust 🦀&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; for now &lt;code&gt;t-rec&lt;/code&gt; depends on &lt;code&gt;imagemagick&lt;/code&gt;, but this is going to change soon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ brew &lt;span class="nb"&gt;install &lt;/span&gt;imagemagick
❯ cargo &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; t-rec 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Hidden Gems
&lt;/h2&gt;

&lt;p&gt;You can record not only the terminal but also every other window. There 2 ways to do so:&lt;/p&gt;

&lt;p&gt;1) abuse the env var &lt;code&gt;TERM_PROGRAM&lt;/code&gt; like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;for example lets record a window 'Google Chrome'&lt;/li&gt;
&lt;li&gt;make sure chrome is running and visible on screen
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nv"&gt;TERM_PROGRAM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"google chrome"&lt;/span&gt; t-rec
Frame cache &lt;span class="nb"&gt;dir&lt;/span&gt;: &lt;span class="s2"&gt;"/var/folders/m8/084p1v0x4770rpwpkrgl5b6h0000gn/T/trec-74728.rUxBx3ohGiQ2"&lt;/span&gt;
Press Ctrl+D to end recording
Recording Window: &lt;span class="s2"&gt;"Google Chrome 2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this is how it looks then:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OcZ-W8oC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/sassman/t-rec-rs/raw/main/docs/demo-chrome.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OcZ-W8oC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/sassman/t-rec-rs/raw/main/docs/demo-chrome.gif" alt="demo-chrome" width="880" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) use the env var &lt;code&gt;WINDOWID&lt;/code&gt; like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;for example let's record a &lt;code&gt;VSCode&lt;/code&gt; window&lt;/li&gt;
&lt;li&gt;figure out the window id program, and make it &lt;/li&gt;
&lt;li&gt;make sure the window is visible on screen&lt;/li&gt;
&lt;li&gt;set the variable and run &lt;code&gt;t-rec&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ t-rec &lt;span class="nt"&gt;--ls-win&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; code
Code | 27600

&lt;span class="c"&gt;# set the WINDOWID variable and run t-rec&lt;/span&gt;
❯ &lt;span class="nv"&gt;WINDOWID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;27600 t-rec

Frame cache &lt;span class="nb"&gt;dir&lt;/span&gt;: &lt;span class="s2"&gt;"/var/folders/m8/084p1v0x4770rpwpkrgl5b6h0000gn/T/trec-77862.BMYiHNRWqv9Y"&lt;/span&gt;
Press Ctrl+D to end recording

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

&lt;/div&gt;



&lt;p&gt;this is how it looks then:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dJMsmgfS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/sassman/t-rec-rs/raw/main/docs/demo-vscode.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dJMsmgfS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/sassman/t-rec-rs/raw/main/docs/demo-vscode.gif" alt="demo-vscode" width="880" height="796"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Contribute
&lt;/h2&gt;

&lt;p&gt;Testers on different Apple hardware needed. Also, exotic shell setups are very interesting for testing.&lt;/p&gt;

&lt;p&gt;To contribute to &lt;code&gt;t-rec&lt;/code&gt; you can either checkout existing issues &lt;a href="https://github.com/sassman/t-rec-rs/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22"&gt;labeled with &lt;code&gt;good first issue&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://github.com/sassman/t-rec-rs/issues/new/choose"&gt;open a new issue&lt;/a&gt; and describe your problem.&lt;br&gt;
Also every PR is welcome. Support for Linux and Windows needs to be done.&lt;/p&gt;

&lt;h2&gt;
  
  
  License
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.gnu.org/licenses/gpl-3.0"&gt;GNU GPL v3 license&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Copyright 2020 © &lt;a href="https://www.d34dl0ck.me"&gt;Sven Assmann&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>tools</category>
      <category>terminalrecorder</category>
      <category>productivity</category>
    </item>
    <item>
      <title>🎉 🚀 🍺 The new release v0.4.1 of stegano-rs is out</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Tue, 22 Sep 2020 23:46:51 +0000</pubDate>
      <link>https://dev.to/5422m4n/the-new-release-v0-4-1-of-stegano-rs-is-out-2l0m</link>
      <guid>https://dev.to/5422m4n/the-new-release-v0-4-1-of-stegano-rs-is-out-2l0m</guid>
      <description>&lt;p&gt;The new major release contains the following:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✨ Features
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WAV Audio media file support - by &lt;a href="https://github.com/sassman"&gt;sassman&lt;/a&gt;, &lt;a href="https://github.com/steganogram/stegano-rs/pull/6"&gt;pull/6&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stegano&lt;/code&gt; has now support for input and output wav audio files (&lt;em&gt;.wav). This means that hiding secret messages and files are now **not&lt;/em&gt;* only possible for png image media files but also wav audio files in the same way. For example like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ stegano hide &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-i&lt;/span&gt; resources/plain/carrier-audio.wav &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; resources/secrets/Blah.txt &lt;span class="se"&gt;\ &lt;/span&gt;         
     resources/secrets/Blah-2.txt &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; secret.wav
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Arch Linux packages - by &lt;a href="https://github.com/orhun"&gt;orhun&lt;/a&gt;, &lt;a href="https://github.com/steganogram/stegano-rs/pull/10"&gt;pull/10&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stegano&lt;/code&gt; can now be installed from available &lt;a href="https://aur.archlinux.org/packages/?O=0&amp;amp;SeB=b&amp;amp;K=stegano&amp;amp;outdated=&amp;amp;SB=n&amp;amp;SO=a&amp;amp;PP=50&amp;amp;do_Search=Go"&gt;AUR packages&lt;/a&gt; using an &lt;a href="https://wiki.archlinux.org/index.php/AUR_helpers"&gt;AUR helper&lt;/a&gt;. For example like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ yay &lt;span class="nt"&gt;-S&lt;/span&gt; stegano
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🛠️ Maintenance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Update &lt;code&gt;stegano-core&lt;/code&gt; to latest dependencies - by &lt;a href="https://github.com/sassman"&gt;sassman&lt;/a&gt;, &lt;a href="https://github.com/steganogram/stegano-rs/pull/2"&gt;pull/2&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://crates.io/search?q=stegano-cli"&gt;check it out on crates.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/5422m4n/status/1308550516390191105"&gt;reference tweet&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>cli</category>
      <category>tools</category>
      <category>steganography</category>
    </item>
    <item>
      <title>Rust Munich Meetup #3</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Wed, 26 Aug 2020 21:13:38 +0000</pubDate>
      <link>https://dev.to/5422m4n/rust-munich-meetup-3-m64</link>
      <guid>https://dev.to/5422m4n/rust-munich-meetup-3-m64</guid>
      <description>&lt;p&gt;Yesterday was the third online meetup of the rust munich group, just in case you missed it, no worries it's available on youtube. I recommend giving it a watch.&lt;/p&gt;

&lt;p&gt;Things you can learn / expect&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tons of details about binary formats&lt;/li&gt;
&lt;li&gt;how steganography (hiding data) in binaries works&lt;/li&gt;
&lt;li&gt;history of the image crate&lt;/li&gt;
&lt;li&gt;tons of design details in the image crate to coop with all the different formats and platform differences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also some side topics to learn about&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;importance of code formatting, especially in OSS and to get it right as early as possible&lt;/li&gt;
&lt;li&gt;the super powers of fuzzing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to our host &lt;a href="https://twitter.com/drahnr"&gt;Bernhard&lt;/a&gt; and all the speakers for their amazing talks.&lt;/p&gt;

&lt;p&gt;You can now also &lt;a href="https://twitter.com/RustMunich"&gt;follow us on twitter&lt;/a&gt; to not miss the next one.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>meetup</category>
      <category>talk</category>
      <category>programming</category>
    </item>
    <item>
      <title>container less cloud computing - wascc</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Tue, 09 Jun 2020 08:11:47 +0000</pubDate>
      <link>https://dev.to/5422m4n/container-less-cloud-computing-wascc-27d3</link>
      <guid>https://dev.to/5422m4n/container-less-cloud-computing-wascc-27d3</guid>
      <description>&lt;p&gt;If you are curious about a container less secure server side future you need to watch this talk.&lt;/p&gt;

&lt;p&gt;At time index 19min it's getting real. Kevin Hoffman demonstrates how hot swap of modules is possible, means deployment with zero downtime, not only of code but also of attached resources like key value stores etc.&lt;/p&gt;

&lt;p&gt;This is super exciting! What do you think about this possible future?&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vqBtoPJoQOE"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;a href="https://wascc.dev/"&gt;Read more about waSCC.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>webassembly</category>
      <category>rust</category>
      <category>polyglot</category>
    </item>
    <item>
      <title>steganography cli in rust - architecture</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Sat, 30 May 2020 16:21:56 +0000</pubDate>
      <link>https://dev.to/5422m4n/steganography-cli-in-rust-architecture-5634</link>
      <guid>https://dev.to/5422m4n/steganography-cli-in-rust-architecture-5634</guid>
      <description>&lt;p&gt;Little preview of my talk about steganography in rust, a little hobby project of mine, at the #rust #meetup #munich on 3rd of June. Fully remote.&lt;/p&gt;

&lt;p&gt;You can also join on &lt;a href="https://www.meetup.com/rust-munich/events/270790293/" rel="noopener noreferrer"&gt;meetup.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UPDATE 2020-06-02:&lt;br&gt;
The Livestream will be &lt;a href="https://www.youtube.com/watch?v=ARDhkujNXrY" rel="noopener noreferrer"&gt;hosted on youtube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/stegano-cli" rel="noopener noreferrer"&gt;stegano-cli on crates.io&lt;/a&gt;&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%2Fpbs.twimg.com%2Fmedia%2FEZRwYpaXYAQJpM8%3Fformat%3Djpg%26name%3D4096x4096" 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%2Fpbs.twimg.com%2Fmedia%2FEZRwYpaXYAQJpM8%3Fformat%3Djpg%26name%3D4096x4096" alt="architecture"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>meetup</category>
      <category>steganography</category>
      <category>talk</category>
    </item>
    <item>
      <title>rust macro rules in practice</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Fri, 22 May 2020 22:55:34 +0000</pubDate>
      <link>https://dev.to/5422m4n/rust-macro-rules-in-practice-40ne</link>
      <guid>https://dev.to/5422m4n/rust-macro-rules-in-practice-40ne</guid>
      <description>&lt;p&gt;This is the first post on my new series "practical rust bites" that shows very tiny pieces of rust, taken out of practical real projects. So this article will be super short, easy to follow and hopefully helpful to find your way into the rust eco system.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;macro rules are very nice to keep your code &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt; wherever you can't or don't want to use functions.&lt;br&gt;
e.g. having several &lt;code&gt;println!&lt;/code&gt; statements in your code that repeat with a lot of similarity, or when you want to wrap or intercept your code with some action before and after your code.&lt;/p&gt;

&lt;p&gt;In this post we explore a profiling macro, called &lt;code&gt;prof&lt;/code&gt; that is used 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="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;total_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Duration&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;total_time&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nd"&gt;prof!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code examples are based on &lt;a href="https://dev.to/sassman/super-simple-disk-benchmark-written-in-rust-1maf"&gt;a little program that I wrote recently that does a write to disk benchmark&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course you can also &lt;a href="https://doc.rust-lang.org/stable/rust-by-example/macros.html"&gt;checkout the amazing rust macro rules documentation&lt;/a&gt; to learn more about rust macro rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;You can checkout the tool I mentioned above, &lt;a href="https://github.com/sassman/ssd-benchmark-rs"&gt;super simple disk benchmark on GitHub&lt;/a&gt; or &lt;a href="https://crates.io/crates/ssd-benchmark"&gt;on crates.io&lt;/a&gt;. It's nothing fancy and only solves my very own issue of benchmarking the writing speed of a hard disk.&lt;/p&gt;

&lt;p&gt;I started with no macros at all, then I found myself repeating on 2 things.&lt;/p&gt;

&lt;p&gt;The first was printing out metrics like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Total &lt;span class="nb"&gt;time                                &lt;/span&gt;29598 ms
Min write &lt;span class="nb"&gt;time                             &lt;/span&gt;2516 ms
&lt;span class="o"&gt;[&lt;/span&gt;...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where the width between the unit and the label is fixed, so that they align nicely on the console.&lt;/p&gt;

&lt;p&gt;The second was profiling how long an operation takes, for instance writing a buffer to file on disk or writing data into a buffer. Data are written in chunks in a loop, so I wanted to avoid to profile the time of the whole loop, but rather profile only the write operation itself, to be more accurate on the numbers (some sort of).&lt;/p&gt;

&lt;p&gt;So the code doing the profiling looks essentially 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="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;total_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Duration&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="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="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// doing the thing&lt;/span&gt;

&lt;span class="n"&gt;total_time&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="nf"&gt;.elapsed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I did not want to have the overhead of a function call, so I took it as an opportunity to explore the macro rule system of rust. Both cases are suited to explore macro rules further, but we want to focus on the second one here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Macro in rust
&lt;/h2&gt;

&lt;p&gt;A macro in rust is safe, the compiler is pretty strict about the syntax and all type and ownership check uphold there as well and there is no way of messing this up as you can in c/c++. To give an example of messing things up in c/c++:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define MAX(a,b) ((a) &amp;gt; (b) ? a : b)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then calling &lt;code&gt;c = MAX(a++, b);&lt;/code&gt; causes some unpleasant side effects of double incrementing. Since the preprocessor just does a search and replace job, and &lt;code&gt;a++&lt;/code&gt; is pasted 2 times as it is executed 2 times. Bad luck!&lt;/p&gt;

&lt;p&gt;In rust this would not have happened.&lt;/p&gt;

&lt;p&gt;The most popular macro that you might already know and probably did use is &lt;code&gt;println!&lt;/code&gt; it just simplifies the usage of formatting output that ends with a newline and is send to &lt;code&gt;stdout&lt;/code&gt;.&lt;br&gt;
Macros can also call functions and other macros inside.&lt;/p&gt;

&lt;p&gt;So a macro rule has the following anatomy:&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;name_of_the_macro&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$param1:expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$param2: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="c1"&gt;// here you go with your function call or macro call here or whatever logic&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 macro above takes 2 arguments, both can be an expression on they own. Isn't it simple?&lt;/p&gt;

&lt;h2&gt;
  
  
  An Example
&lt;/h2&gt;

&lt;p&gt;Let's first imagine how our future code should look like, starting from 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;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;total_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Duration&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="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="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// file and buffer is declared somewhere above..&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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;total_time&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="nf"&gt;.elapsed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we want something 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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;total_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Duration&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;total_time&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nd"&gt;prof!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so we want the macro called &lt;code&gt;prof!&lt;/code&gt;, like profiling and it should have no arguments but a block where things can be done inside. Last it will return the &lt;code&gt;Duration&lt;/code&gt; it took for executing the block.&lt;/p&gt;

&lt;p&gt;This is how it looks:&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;prof&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$something: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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$something&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="nf"&gt;.elapsed&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;Alright, let's walk that through line by line:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;prof&lt;/code&gt; is the name of the macro&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$something&lt;/code&gt; describes one parameter called &lt;code&gt;something&lt;/code&gt;, &lt;code&gt;:expr&lt;/code&gt; declares the parameter to be a rust expression, followed by a literal &lt;code&gt;;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;opens a block &lt;code&gt;{&lt;/code&gt; - the first &lt;code&gt;{&lt;/code&gt; belongs to the macro, the second &lt;code&gt;{&lt;/code&gt; actually starts a block&lt;/li&gt;
&lt;li&gt;we store the start time - regular rust code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$something;&lt;/code&gt; means the expression we give into the macro will be placed here&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;start.elapsed()&lt;/code&gt; regular rust code, without the &lt;code&gt;;&lt;/code&gt; means we will return this from the block, that's like the return value of the macro.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;}&lt;/code&gt; closing the block of the generated rust code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can verify the result and inspect what the compiler will generate out of it. Unfortunately it requires rust unstable to be installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustup run nightly cargo rustc &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-Z&lt;/span&gt; unstable-options &lt;span class="nt"&gt;--pretty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;expanded | less
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will produce a lot of code, very interesting to dig through that. But what we are actually looking for is the following:&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;total_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Duration&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;total_time&lt;/span&gt; &lt;span class="o"&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;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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;start&lt;/span&gt;&lt;span class="nf"&gt;.elapsed&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 as you can see the macro expands to a block, that contains the code from the macro with the stuff we have given to the macro in between. Eventually it returns the duration &lt;code&gt;start.elapsed()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus Track
&lt;/h2&gt;

&lt;p&gt;So far so good, but let's have a look at yet another use case of the 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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&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="n"&gt;TOTAL_SIZE_MB&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;BUF_SIZE_MB&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;write_time&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nd"&gt;prof!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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="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;stdout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.flush&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="p"&gt;};&lt;/span&gt;
    &lt;span class="nd"&gt;print!&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here we have 2 expressions in side the macro body. Unfortunately the compiler will yell at us with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;error: no rules expected the token &lt;span class="sb"&gt;`&lt;/span&gt;std&lt;span class="sb"&gt;`&lt;/span&gt;
   &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/main.rs:179:17
    |
44  | macro_rules! prof &lt;span class="o"&gt;{&lt;/span&gt;
    | &lt;span class="nt"&gt;-----------------&lt;/span&gt; when calling this macro
...
179 |                 std::io::stdout&lt;span class="o"&gt;()&lt;/span&gt;.flush&lt;span class="o"&gt;()&lt;/span&gt;?&lt;span class="p"&gt;;&lt;/span&gt;
    |                 ^^^ no rules expected this token &lt;span class="k"&gt;in &lt;/span&gt;macro call
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clearly the second expression gives us this troubles. The good thing is that we can have quantifier in the left hand side of the matching tree in the macro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-    ($($something:expr)) =&amp;gt; {
&lt;/span&gt;&lt;span class="gi"&gt;+    ($something:expr; $($otherthings:expr;)*) =&amp;gt; {
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we extend the macro by &lt;code&gt;$($otherthings:expr;)*&lt;/code&gt; that is basically the same as the first argument, just with the difference &lt;code&gt;*&lt;/code&gt; modifies, similar to a RegEx, the the expression to be &lt;a href="https://doc.rust-lang.org/stable/rust-by-example/macros/repeat.html"&gt;present 0 or n times&lt;/a&gt;. Now we can hand more expressions over to the macro, but yet we don't use them. For this we need to change the content of the macro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;             $something;
&lt;span class="gi"&gt;+            $(
+                $otherthings;
+            )*
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At &lt;code&gt;$otherthings;&lt;/code&gt; will be the expression placed, and &lt;code&gt;$()*&lt;/code&gt; will expand the expression as often as expressions given to the macro.&lt;/p&gt;

&lt;p&gt;As a whole the macro looks now 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;prof&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$something: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;$otherthings: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;let&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$something&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;$otherthings&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;start&lt;/span&gt;&lt;span class="nf"&gt;.elapsed&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;Let's verify again how this macro would expand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="n"&gt;write_time&lt;/span&gt; &lt;span class="o"&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;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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="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;stdout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.flush&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;start&lt;/span&gt;&lt;span class="nf"&gt;.elapsed&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;
  
  
  Simplification
&lt;/h3&gt;

&lt;p&gt;Alright, now let's have a final look if we can simplify that macro further because the first parameter and the second are basically identically. So let's just get rid of the second one, and apply the repeat modifier to the first one.&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;prof&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;$something: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;let&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&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;$something&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;start&lt;/span&gt;&lt;span class="nf"&gt;.elapsed&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;&lt;code&gt;$($something:expr;)+&lt;/code&gt; has now the modifier &lt;code&gt;+&lt;/code&gt; that says once or multiple times the whole expression terminated by a &lt;code&gt;;&lt;/code&gt;.&lt;br&gt;
In the macro body we now only expand the one and only parameter &lt;code&gt;$($something;)*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The only drawback is that expressions that are not terminated by a &lt;code&gt;;&lt;/code&gt; like a for loop for instance, now must be terminated by a &lt;code&gt;;&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;let&lt;/span&gt; &lt;span class="n"&gt;buffer_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;prof!&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="n"&gt;BUF_SIZE&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="nf"&gt;.gen&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;vs&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;buffer_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;prof!&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="n"&gt;BUF_SIZE&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="nf"&gt;.gen&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;Versions used for this post&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="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rustc &lt;span class="nt"&gt;--version&lt;/span&gt;
cargo 1.43.0 &lt;span class="o"&gt;(&lt;/span&gt;2cbe9048e 2020-05-03&lt;span class="o"&gt;)&lt;/span&gt;
rustc 1.43.1 &lt;span class="o"&gt;(&lt;/span&gt;8d69840ab 2020-05-04&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please don't forget to share your feedback, give a 👍, &lt;a href="https://twitter.com/5422m4n"&gt;follow me on twitter&lt;/a&gt; and most importantly share your learnings and your struggles while learning rust.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>programming</category>
      <category>testing</category>
    </item>
    <item>
      <title>Time spend on writing CI configurations</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Sun, 17 May 2020 14:25:34 +0000</pubDate>
      <link>https://dev.to/5422m4n/time-spend-on-writing-ci-configurations-o76</link>
      <guid>https://dev.to/5422m4n/time-spend-on-writing-ci-configurations-o76</guid>
      <description>&lt;p&gt;How much time, at the beginning and summed up overall did you spend on writing your ci configuration? Be it for github actions or Travis CI or even Jenkins?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>ci</category>
      <category>pipeline</category>
      <category>build</category>
    </item>
    <item>
      <title>Super Simple Disk Benchmark written in rust</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Thu, 07 May 2020 21:52:28 +0000</pubDate>
      <link>https://dev.to/5422m4n/super-simple-disk-benchmark-written-in-rust-1maf</link>
      <guid>https://dev.to/5422m4n/super-simple-disk-benchmark-written-in-rust-1maf</guid>
      <description>&lt;p&gt;Today I discovered &lt;a href="http://www.geschke-online.de/sdb/"&gt;simple disk benchmark&lt;/a&gt; that is written in C and I wanted to give a very minimal version of it a try in rust. So here I'am reporting of my new crate and command line tool &lt;code&gt;ssd-benchmark&lt;/code&gt;. It is so super simple you cannot do anything wrong. Give it a try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Purpose of life
&lt;/h2&gt;

&lt;p&gt;This tool has just one single purpose, it measures the writing performance of your hard disk on macOS and Linux. More precisely spoken of the disk under your &lt;code&gt;CWD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It used random data from &lt;a href="https://crates.io/crates/rand"&gt;&lt;code&gt;rand crate&lt;/code&gt;&lt;/a&gt; and writes first sequentially chunks of 8MB until a total 1GB is written. It measures writing time and throughput.&lt;/p&gt;

&lt;p&gt;After that it writes this random data 8 times again on disk and measures the average writing times and throughput for this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;

&lt;p&gt;To install the ssd-benchmark tool, you just need to run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt; ssd-benchmark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(--force just makes it update to the latest version if it's already installed)&lt;/p&gt;

&lt;p&gt;to verify if the installation went through, you can run &lt;code&gt;ssd-benchmark&lt;/code&gt; that should output similar to&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;$HOME&lt;/span&gt;/.cargo/bin/ssd-benchmark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage
&lt;/h3&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;ssd-benchmark

&lt;span class="c"&gt;###             Super Simple Disk Benchmark              ###&lt;/span&gt;
&lt;span class="c"&gt;## Star me on https://github.com/sassman/ssd-benchmark-rs ##&lt;/span&gt;

Filling buffer with 8 MB random data...
Initilisation of buffer &lt;span class="k"&gt;done               &lt;/span&gt;4890 ms

Starting benchmark...

Perform sequential writing of total 1024 MB &lt;span class="k"&gt;in &lt;/span&gt;8 MB chunks
................................................................................................................................

Total &lt;span class="nb"&gt;time                                 &lt;/span&gt;2522 ms
Throughput                               512.00 MB/s

Perform 8 write cycles of 1024 MB
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................

Total &lt;span class="nb"&gt;time                                &lt;/span&gt;29598 ms
Min write &lt;span class="nb"&gt;time                             &lt;/span&gt;2516 ms
Max write &lt;span class="nb"&gt;time                             &lt;/span&gt;4934 ms
Range write &lt;span class="nb"&gt;time                           &lt;/span&gt;2418 ms
Average write &lt;span class="nb"&gt;time &lt;/span&gt;μ                       3699 ms
Standard deviation σ                        801 ms

Min throughput                           207.54 MB/s
Max throughput                           407.00 MB/s
Average throughput Ø                     276.83 MB/s
Standard deviation σ                      64.76 MB/s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The great thing is, there are no parameters or options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Missing something?
&lt;/h2&gt;

&lt;p&gt;If you miss a feature file an issue on &lt;a href="https://github.com/sassman/ssd-benchmark-rs/issues"&gt;github&lt;/a&gt; and don't forget to &lt;a href="https://github.com/sassman/ssd-benchmark-rs"&gt;star the repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading and don't miss out to give feedback :)&lt;/p&gt;

&lt;p&gt;Used versions:&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;rustc &lt;span class="nt"&gt;--version&lt;/span&gt;
rustc 1.43.0 &lt;span class="o"&gt;(&lt;/span&gt;4fb7144ed 2020-04-20&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;cargo &lt;span class="nt"&gt;--version&lt;/span&gt;
cargo 1.43.0 &lt;span class="o"&gt;(&lt;/span&gt;3532cf738 2020-03-17&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Originally published &lt;a href="https://www.d34dl0ck.me/super-simple-disk-benchmark-written-in-rust.html#super-simple-disk-benchmark-written-in-rust"&gt;on my blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>cli</category>
      <category>tool</category>
      <category>helper</category>
    </item>
    <item>
      <title>little rust starter hint series: lifetimes made easy</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Sun, 03 May 2020 15:07:32 +0000</pubDate>
      <link>https://dev.to/5422m4n/little-rust-starter-hint-series-lifetimes-made-easy-40oc</link>
      <guid>https://dev.to/5422m4n/little-rust-starter-hint-series-lifetimes-made-easy-40oc</guid>
      <description>&lt;p&gt;As usual, I want to share with you an &lt;a href="https://rust-unofficial.github.io/too-many-lists/"&gt;awesome online-book to learn rust in a very problem centric way.&lt;/a&gt; This book focuses on the problem of implementing a &lt;a href="https://en.wikipedia.org/wiki/Linked_list"&gt;linked list&lt;/a&gt;, which is a very essential data structure, and a fundamental lesson in computer science and programming. It's for instance also a very popular exam exercise at universities in c++ programming.&lt;/p&gt;

&lt;p&gt;While the problem of a linked list is basic, it does not mean it is trivial to implement especially in a language that is new and, in this case, that is memory safe. So why is that? Well, read the book than you'll know 😁.&lt;/p&gt;

&lt;p&gt;All right, to keep that post very focused to the topic of lifetimes, I'll pick one example from the problem of a linked list - very specifically the iteration of items. What I mean with iteration of items is, that we want to be able to loop over the list and get every item until there are no more items. But more importantly, we want the list to remain intact as it was before we started to iterate. So we don't want to &lt;em&gt;consume&lt;/em&gt; the list. Pretty much 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;#[test]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;loop_over_vec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// creating a Vec&amp;lt;i32&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&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;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// looping over all items&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="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// print the item to stdout&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;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// printing the length of the Vector (should be 5)&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;v&lt;/span&gt;&lt;span class="nf"&gt;.len&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;just with our list implementation instead of &lt;code&gt;Vec&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, how is this connected with lifetimes?
&lt;/h2&gt;

&lt;p&gt;Glad, you asked. Let me introduce few little data structures first, that would help to make the connection: a &lt;code&gt;Node&lt;/code&gt;, a &lt;code&gt;Link&lt;/code&gt;, and the &lt;code&gt;List&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;Note: for the sake of simplicity I'll not use a generic list but a simple list of integers (&lt;code&gt;i32&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;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// the link to the next item or to None&lt;/span&gt;
    &lt;span class="n"&gt;data&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="c1"&gt;// the actual data item&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Option is used because the Link might be 'empty', means there is no item.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Link&lt;/span&gt; &lt;span class="o"&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;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;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;struct&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Link&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 structs should be easy to read. Just in case you wonder about &lt;code&gt;type Link = Option&amp;lt;Box&amp;lt;Node&amp;gt;&amp;gt;&lt;/code&gt;, it is called a type alias and just renames the rust &lt;code&gt;Option&lt;/code&gt; type to our use case. You might have seen it in c/c++ as a &lt;code&gt;typedef&lt;/code&gt; statement. And in case you wonder about the mysterious &lt;code&gt;Box&lt;/code&gt;: imagine it as a very literally box that surrounds a &lt;code&gt;Node&lt;/code&gt; (the details doesn't matter for lifetimes).&lt;/p&gt;

&lt;p&gt;Let's see if the compiler agrees with 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="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;test&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;super&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="nd"&gt;#[test]&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;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;let&lt;/span&gt; &lt;span class="n"&gt;last_item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Link&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="n"&gt;data&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first_item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&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="n"&gt;last_item&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
            &lt;span class="n"&gt;data&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="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;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&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="n"&gt;first_item&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;It compiles, nice. Well, it's not very handy to use that list, but as said, we focus on lifetimes. So let's move on and implement the &lt;a href="https://doc.rust-lang.org/std/iter/trait.Iterator.html"&gt;&lt;code&gt;Iterator&lt;/code&gt;&lt;/a&gt; trait for this list. Well not directly for the List, but a helper &lt;code&gt;Iter&lt;/code&gt; that allows us to operate on the list items.&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;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;next&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;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Node&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;// has a reference to the Node, not Node by value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// implementing the Iterator trait for the helper Iter&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;Iterator&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Iter&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;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// has a reference to the data of the Node&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;next&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="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;Option&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;Item&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;self&lt;/span&gt;&lt;span class="py"&gt;.next&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;|&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;.next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.next&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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="n"&gt;node&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;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// What?&lt;/span&gt;
            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.data&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;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// obtain the helper Iter from our list&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;List&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;iter&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="n"&gt;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;next&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;.head&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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="n"&gt;node&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;node&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// again?&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, we got the &lt;code&gt;Iter&lt;/code&gt; that has the next node or &lt;code&gt;None&lt;/code&gt; in case we are done or empty. We obtain the &lt;code&gt;Iter&lt;/code&gt; from the &lt;code&gt;List&lt;/code&gt; by calling &lt;code&gt;iter&lt;/code&gt; - ok that was simple. When we call &lt;code&gt;next&lt;/code&gt; on &lt;code&gt;Iter&lt;/code&gt; an item is returned and the next node of the list is set to it's &lt;code&gt;next&lt;/code&gt; property. By that we are moving from a to z until we encounter &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ok, but what is that &lt;code&gt;|node| &amp;amp;**node&lt;/code&gt;? So 2 things here: The &lt;code&gt;|node|&lt;/code&gt; states that this is a closure. If you know a bit of ruby, then that feels like home. And the other &lt;code&gt;&amp;amp;**node&lt;/code&gt; just means we dereference (&lt;code&gt;*&lt;/code&gt;) the &lt;code&gt;node&lt;/code&gt; (because &lt;code&gt;node&lt;/code&gt; is a reference to a &lt;code&gt;Box&lt;/code&gt; that holds the actual &lt;code&gt;Node&lt;/code&gt;), then we dereference again (this time we &lt;em&gt;unbox&lt;/em&gt;), and then we take the reference to that &lt;code&gt;node&lt;/code&gt; and return it.&lt;/p&gt;

&lt;p&gt;Ok, let's move on and compile: 🧨&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;error[E0106]: missing lifetime specifier
  &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/list_for_article.rs:22:18
   |
22 |     next: Option&amp;lt;&amp;amp;Node&amp;gt;,
   |                  ^ expected named lifetime parameter
   |
&lt;span class="nb"&gt;help&lt;/span&gt;: consider introducing a named lifetime parameter
   |
21 | pub struct Iter&amp;lt;&lt;span class="s1"&gt;'a&amp;gt; {
22 |     next: Option&amp;lt;&amp;amp;'&lt;/span&gt;a Node&amp;gt;,
   |

error[E0106]: missing lifetime specifier
  &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/list_for_article.rs:40:17
   |
40 |     &lt;span class="nb"&gt;type &lt;/span&gt;Item &lt;span class="o"&gt;=&lt;/span&gt; &amp;amp;i32&lt;span class="p"&gt;;&lt;/span&gt;
   |                 ^ expected named lifetime parameter
   |
&lt;span class="nb"&gt;help&lt;/span&gt;: consider introducing a named lifetime parameter
   |
40 |     &lt;span class="nb"&gt;type &lt;/span&gt;Item&amp;lt;&lt;span class="s1"&gt;'a&amp;gt; = &amp;amp;'&lt;/span&gt;a i32&lt;span class="p"&gt;;&lt;/span&gt;
   |              ^^^^   ^^^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we encounter 2 issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in line 22, where we want to store a reference to the &lt;code&gt;Node&lt;/code&gt; as the next node in &lt;code&gt;Iter&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;in line 40, where we want to return a reference to the data of the node, not a copy of it!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The compiler wants us here to specify the lifetime of the &lt;code&gt;Node&lt;/code&gt; reference and the node's data reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  When are lifetimes required?
&lt;/h2&gt;

&lt;p&gt;There are 3 types of variables in rust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a value like: &lt;code&gt;let a = 1;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a reference to a value like: &lt;code&gt;&amp;amp;a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a mutable reference to a value like: &lt;code&gt;&amp;amp;mut a&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's put that into the context of structures: our struct &lt;code&gt;Iter&lt;/code&gt; contains an &lt;code&gt;Option&lt;/code&gt; to a reference of &lt;code&gt;Node&lt;/code&gt;. So that reference lives in &lt;code&gt;Iter&lt;/code&gt;, but the actual value of that reference lives in &lt;code&gt;List&lt;/code&gt;. You can think of a lifetime as a hidden information that exists in every block, and when you want to use references to a value, you need to explicitly pass that information from the block where the value lives to the place where the reference will live. For &lt;code&gt;Iter&lt;/code&gt; that looks 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="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Iter&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;next&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;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="n"&gt;Node&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;First we mark the struct itself using the generics notation &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;, however, this time a lifetime &lt;code&gt;'&lt;/code&gt; called &lt;code&gt;a&lt;/code&gt; is provided instead of a type. Together that looks like &lt;code&gt;&amp;lt;'a&amp;gt;&lt;/code&gt;. You can call it whatever you like, only &lt;code&gt;'static&lt;/code&gt; is reserved for the lifetime of the whole program.&lt;/p&gt;

&lt;p&gt;Second, we mark the field &lt;code&gt;next&lt;/code&gt; to be of type &lt;code&gt;Option&amp;lt;&amp;amp;'a Node&amp;gt;&lt;/code&gt;. So to say, the lifetime is passed into the reference from the block where it is created in:&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="n"&gt;List&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;iter&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="n"&gt;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// here the lifetime of the list itself is passed over too the Iter&lt;/span&gt;
        &lt;span class="n"&gt;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;next&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;.head&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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="n"&gt;node&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;node&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;That implies, that the &lt;code&gt;Iter&lt;/code&gt; from above cannot live longer than the list where it came from. Essentially, that is very logical - of course you cannot hold an iterator to a node of a list that is gone. The lifetime notation just makes it more explicit that there is a connection between the two structs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Invisible
&lt;/h2&gt;

&lt;p&gt;There is this helpful feature of &lt;a href="https://doc.rust-lang.org/nomicon/lifetime-elision.html"&gt;lifetime elision&lt;/a&gt; that allows the programmer to hide that lifetimes basically everywhere. Otherwise every variable or function would need to have it written out. That would be very painful. So in fact the &lt;code&gt;List::iter&lt;/code&gt; method looks like the following:&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="n"&gt;List&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;iter&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&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="n"&gt;Iter&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;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;next&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;.head&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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="n"&gt;node&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;node&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;There it is even more explicit, that so to say, the lifetime of the reference to &lt;code&gt;self&lt;/code&gt; is the same as the one of &lt;code&gt;Iter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Does the compiler know, that the lifetime of &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;Iter&lt;/code&gt; are the same if you don't explicitly write them?&lt;/p&gt;

&lt;p&gt;Let's check out that little change:&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="n"&gt;List&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;iter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'z&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="nv"&gt;'y&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="nv"&gt;'z&lt;/span&gt; &lt;span class="n"&gt;List&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;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="py"&gt;.head&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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="n"&gt;node&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;node&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;We add a second parameter of the same type &lt;code&gt;List&lt;/code&gt; but with a different lifetime &lt;code&gt;'z&lt;/code&gt; and still keep omitting the lifetime of &lt;code&gt;Iter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's compile and see if the compiler get's it right:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;error[E0623]: lifetime mismatch
  &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/list_for_article.rs:36:9
   |
32 |       pub fn iter&amp;lt;&lt;span class="s1"&gt;'y, '&lt;/span&gt;z&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;&amp;amp;&lt;span class="s1"&gt;'y self, other: &amp;amp;'&lt;/span&gt;z List&lt;span class="o"&gt;)&lt;/span&gt; -&amp;gt; Iter &lt;span class="o"&gt;{&lt;/span&gt;
   |                                            &lt;span class="nt"&gt;--------&lt;/span&gt;     &lt;span class="nt"&gt;----&lt;/span&gt;
   |                                            |
   |                                            this parameter and the &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="nb"&gt;type &lt;/span&gt;are declared with different lifetimes...
...
36 | /         Iter &lt;span class="o"&gt;{&lt;/span&gt;
37 | |             next: other.head.as_ref&lt;span class="o"&gt;()&lt;/span&gt;.map&lt;span class="o"&gt;(&lt;/span&gt;|node| &amp;amp;&lt;span class="k"&gt;**&lt;/span&gt;node&lt;span class="o"&gt;)&lt;/span&gt;,
38 | |         &lt;span class="o"&gt;}&lt;/span&gt;
   | |_________^ ...but data from &lt;span class="sb"&gt;`&lt;/span&gt;other&lt;span class="sb"&gt;`&lt;/span&gt; is returned here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well in that case, the compiler doesn't know what is the right lifetime to use, so we have to be explicit about our intentions that we want the lifetime of &lt;code&gt;other&lt;/code&gt; to be used for &lt;code&gt;Iter&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;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'y&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="nv"&gt;'y&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="nv"&gt;'z&lt;/span&gt; &lt;span class="n"&gt;List&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;Iter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'z&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;Iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="py"&gt;.head&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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="n"&gt;node&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;node&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 it compiles just fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to the Iterator
&lt;/h2&gt;

&lt;p&gt;There was the other error about the lifetime of the Iterator's item that we did not yet fix:&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="nb"&gt;Iterator&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Iter&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;type&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="o"&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;i32&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;next&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="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;Option&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;Item&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;self&lt;/span&gt;&lt;span class="py"&gt;.next&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;|&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;.next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.next&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&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="n"&gt;node&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;node&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;node&lt;/span&gt;&lt;span class="py"&gt;.data&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;We make here as well explicit that lifetime of &lt;code&gt;Iter&lt;/code&gt; is the same as the one of the item. Here, the name &lt;code&gt;'a&lt;/code&gt; is not the same &lt;code&gt;'a&lt;/code&gt; as we used before in &lt;code&gt;List&lt;/code&gt; - the 2 are not connected with each other. However there is this, so to say, chain of passing the lifetime from the &lt;code&gt;List&lt;/code&gt; to the &lt;code&gt;Iter&lt;/code&gt; to the &lt;code&gt;Item&lt;/code&gt; of the iterator. They all live together and happily ever after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final test
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[test]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;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;let&lt;/span&gt; &lt;span class="n"&gt;last_item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Link&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="n"&gt;data&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first_item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&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="n"&gt;last_item&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="n"&gt;data&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="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;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&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="n"&gt;first_item&lt;/span&gt;&lt;span class="p"&gt;)),&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;x&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="nf"&gt;.iter&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;x&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;iter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="nf"&gt;.iter&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;iter&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&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="n"&gt;iter&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&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;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="nf"&gt;.next&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Lifetimes are present in rust everytime and everywhere, we normally just don't see them and often don't need to see them. Mainly, when we deal with references that are owned by some other piece of code, then we have to be explicit about where they live.&lt;/p&gt;

&lt;p&gt;You can find the full code example as &lt;a href="https://gist.github.com/sassman/0d2aa2ddf1220237a36917715a98d2d6"&gt;a gist on github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading and don't miss out to give feedback :)&lt;/p&gt;

&lt;p&gt;Let me know, if that was helpful for you and if there are other concepts of rust that appear confusing or not easy to grasp.&lt;/p&gt;

&lt;p&gt;Used versions:&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;rustc &lt;span class="nt"&gt;--version&lt;/span&gt;
rustc 1.43.0 &lt;span class="o"&gt;(&lt;/span&gt;4fb7144ed 2020-04-20&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;cargo &lt;span class="nt"&gt;--version&lt;/span&gt;
cargo 1.43.0 &lt;span class="o"&gt;(&lt;/span&gt;3532cf738 2020-03-17&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Originally published &lt;a href="https://www.d34dl0ck.me/little-rust-starter-hint-series-lifetimes-made-easy.html#little-rust-starter-hint-series-lifetimes-made-easy"&gt;on my blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>programming</category>
      <category>basics</category>
    </item>
    <item>
      <title>little rust starter hint series: Polymorphism and Traits</title>
      <dc:creator>Sven Kanoldt</dc:creator>
      <pubDate>Thu, 05 Sep 2019 22:16:09 +0000</pubDate>
      <link>https://dev.to/5422m4n/little-rust-starter-hint-series-polymorphism-and-traits-3n70</link>
      <guid>https://dev.to/5422m4n/little-rust-starter-hint-series-polymorphism-and-traits-3n70</guid>
      <description>&lt;p&gt;Today we going to explore Polymorphism and how that is actually doable in Rust.&lt;br&gt;
For those that have not done any OOP language yet, Polymorphism is just a fancy term for behaving or being polymorph. For example a instance of something can also be or behave as something else. In Java, you would use &lt;code&gt;interfaces&lt;/code&gt; to declare some behaviour that can be implemented by a class. So one class can implement one or many interfaces. In rust there are only structs no classes and traits that act as interfaces. As simple as that.&lt;/p&gt;
&lt;h2&gt;
  
  
  the problem statement
&lt;/h2&gt;

&lt;p&gt;We want to implement a very basic hexdump tool that either accepts a file as argument or reads from &lt;code&gt;stdin&lt;/code&gt; if that file is not provided.&lt;/p&gt;

&lt;p&gt;for instance usable like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hexdump README.md
0000000 23 20 48 65 78 64 75 6d 70 0a 0a 23 23 20 55 73
0000010 61 67 65 0a 0a 60 60 60 62 61 73 68 0a 68 65 78
0000020 64 75 6d 70 20 52 45 41 44 4d 45 2e 6d 64 0a 0a
0000030 60 60 60 0a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or without a file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hexdump
foo bar bak^D
0000000 66 6f 6f 20 62 61 72 20 62 61 6b 0a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  the basics
&lt;/h2&gt;

&lt;p&gt;Q: How to open a file&lt;br&gt;
A: &lt;code&gt;File::open(file)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Q: How to read from a file&lt;br&gt;
A: &lt;code&gt;BufReader::new(File::open(file))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Q: How to read from stdin&lt;br&gt;
A: &lt;code&gt;stdin().lock()&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  explanation
&lt;/h3&gt;

&lt;p&gt;So it seems that &lt;code&gt;stdin().lock()&lt;/code&gt; and &lt;code&gt;BufReader::new()&lt;/code&gt; seems to have something in common that. The both allow to read &lt;code&gt;bytes&lt;/code&gt; from them. Well, we come to this in a moment. Let's dump the full code for now:&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="n"&gt;env&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;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&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;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&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;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;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;stdin&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;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BufReader&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="k"&gt;-&amp;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="nb"&gt;Result&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;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;args&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;String&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;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;args&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;match&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="nf"&gt;.get&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="p"&gt;{&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;file&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;read_and_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;BufReader&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;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&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="nb"&gt;None&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;read_and_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="c1"&gt;//      ^--- this function will be implemented later on, don't worry&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  the trait &lt;code&gt;BufRead&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;So the thing that both (&lt;code&gt;stdin().lock()&lt;/code&gt; and &lt;code&gt;BufReader::new()&lt;/code&gt;) have in common, the both implement the trait &lt;a href="https://doc.rust-lang.org/std/io/trait.BufRead.html#provided-methods" rel="noopener noreferrer"&gt;&lt;code&gt;BufRead&lt;/code&gt;&lt;/a&gt;&lt;br&gt;
at the declaration we can see &lt;code&gt;pub trait BufRead: Read&lt;/code&gt; that means that the &lt;code&gt;BufRead&lt;/code&gt; extends &lt;code&gt;Read&lt;/code&gt; by some more methods.&lt;/p&gt;
&lt;h2&gt;
  
  
  the naive approach
&lt;/h2&gt;

&lt;p&gt;Perfect so let's now implement the missing method from above and hand over the instance that implements the &lt;code&gt;BufRead&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;fn&lt;/span&gt; &lt;span class="nf"&gt;read_and_dump&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;BufRead&lt;/span&gt;&lt;span class="p"&gt;)&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;i&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="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print_line_no_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// &amp;lt;-- we'll come to that later&lt;/span&gt;
        &lt;span class="nf"&gt;print_byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&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;// &amp;lt;-- we'll come to that later&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;print!&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool, let's ask the compiler how he likes it..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;
   Compiling hexdump v0.1.0
warning: trait objects without an explicit &lt;span class="sb"&gt;`&lt;/span&gt;dyn&lt;span class="sb"&gt;`&lt;/span&gt; are deprecated
  &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/main.rs:17:21
   |
17 | fn read_and_dump&lt;span class="o"&gt;(&lt;/span&gt;r: BufRead&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   |                     ^^^^^^^ &lt;span class="nb"&gt;help&lt;/span&gt;: use &lt;span class="sb"&gt;`&lt;/span&gt;dyn&lt;span class="sb"&gt;`&lt;/span&gt;: &lt;span class="sb"&gt;`&lt;/span&gt;dyn BufRead&lt;span class="sb"&gt;`&lt;/span&gt;
   |
   &lt;span class="o"&gt;=&lt;/span&gt; note: &lt;span class="c"&gt;#[warn(bare_trait_objects)] on by default&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;...]

error[E0277]: the size &lt;span class="k"&gt;for &lt;/span&gt;values of &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;dyn std::io::BufRead + &lt;span class="s1"&gt;'static)` cannot be known at compilation time
  --&amp;gt; src/main.rs:17:18
   |
17 | fn read_and_dump(r: BufRead) {
   |                  ^ doesn'&lt;/span&gt;t have a size known at compile-time
   |
   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;help&lt;/span&gt;: the trait &lt;span class="sb"&gt;`&lt;/span&gt;std::marker::Sized&lt;span class="sb"&gt;`&lt;/span&gt; is not implemented &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;dyn std::io::BufRead + &lt;span class="s1"&gt;'static)`
   = note: to learn more, visit &amp;lt;https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait&amp;gt;
   = note: all local variables must have a statically known size
   = help: unsized locals are gated as an unstable feature
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fcupheadmemes.com%2Fwp-content%2Fuploads%2F2018%2F08%2FBest-Programming-Memes-94.jpg" 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%2Fcupheadmemes.com%2Fwp-content%2Fuploads%2F2018%2F08%2FBest-Programming-Memes-94.jpg" alt="tilt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;well, that would be too easy.&lt;br&gt;
It took me actually a bit time to gasp the problem, I read the docs and not got much further until I realized that traits should not be used as direct types but rather as "marker".&lt;/p&gt;

&lt;p&gt;To explain what I mean with "marker" let's checkout the next iteration&lt;/p&gt;
&lt;h2&gt;
  
  
  Version 1: the impl on anonymous type
&lt;/h2&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;read_and_dump&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;impl&lt;/span&gt; &lt;span class="n"&gt;BufRead&lt;/span&gt;&lt;span class="p"&gt;)&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;i&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="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print_line_no_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;print_byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&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="nd"&gt;print!&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;So here we not name any type and just say that whatever type we provide it will implement the trait &lt;code&gt;BufRead&lt;/code&gt;. And by doing so the compiler is perfectly fine with everything.&lt;/p&gt;
&lt;h2&gt;
  
  
  Version 2: generic short hand
&lt;/h2&gt;

&lt;p&gt;I was curious if generics are not as well capable of solving this. Just with the difference that the compiler might be able to do further optimizations.&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="n"&gt;read_and_dump&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;BufRead&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;r&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="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;i&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="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print_line_no_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;print_byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&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="nd"&gt;print!&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so in &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; we specify a type &lt;code&gt;T&lt;/code&gt; that implements &lt;code&gt;BufRead&lt;/code&gt; that is called a &lt;a href="https://doc.rust-lang.org/rust-by-example/generics/bounds.html" rel="noopener noreferrer"&gt;bound generic&lt;/a&gt; in rust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version 3: generic verbose
&lt;/h2&gt;

&lt;p&gt;When you implement traits you will see that syntax quite often, so it is worth to mentioning the &lt;a href="https://doc.rust-lang.org/rust-by-example/generics/where.html" rel="noopener noreferrer"&gt;where syntax&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;read_and_dump&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;r&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;where&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;BufRead&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;i&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="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print_line_no_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;print_byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&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="nd"&gt;print!&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we name the bounds of the generic by the word &lt;code&gt;where&lt;/code&gt; directly before the body &lt;code&gt;{}&lt;/code&gt; braces. More than just one can be appended by &lt;code&gt;,&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  wrap up
&lt;/h2&gt;

&lt;p&gt;to not miss out the other functions, even thou they are not showing much here you go:&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;print_line_no_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;0x10&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;if&lt;/span&gt; &lt;span class="n"&gt;i&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="nd"&gt;print!&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="p"&gt;}&lt;/span&gt;
        &lt;span class="nd"&gt;print!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:07x}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&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;print_byte&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;u8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;print!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" {:02x}"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we have now learned how we can use anonymous types or generics to make use of loosely couple our functions to traits instead of tightly couple them to the real structs that they are. That is also sometimes referred to as the &lt;a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle" rel="noopener noreferrer"&gt;Open Close Principle&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  references
&lt;/h2&gt;

&lt;p&gt;Further reading about subtle differences can be found &lt;a href="https://www.reddit.com/r/rust/comments/8jfn7z/what_is_the_advantage_of_impl_trait_in_argument/" rel="noopener noreferrer"&gt;on reddit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the title image belongs to Blizzard Entertainment and is available under &lt;a href="https://creativecommons.org/licenses/by-nc-sa/3.0/" rel="noopener noreferrer"&gt;CC BY-NC-SA 3.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;used versions:&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;rustc &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo &lt;span class="nt"&gt;--version&lt;/span&gt;
rustc 1.37.0 &lt;span class="o"&gt;(&lt;/span&gt;eae3437df 2019-08-13&lt;span class="o"&gt;)&lt;/span&gt;
cargo 1.37.0 &lt;span class="o"&gt;(&lt;/span&gt;9edd08916 2019-08-02&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please don't forget to share your feedback, and let me know what was your learning if there was any. If you have more variants that I missed, please share them.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>programming</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
