<?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: Steve Pryde</title>
    <description>The latest articles on DEV Community by Steve Pryde (@stevepryde).</description>
    <link>https://dev.to/stevepryde</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%2F347512%2F5a623269-5ce4-4079-be9c-6904061d3fc5.jpeg</url>
      <title>DEV Community: Steve Pryde</title>
      <link>https://dev.to/stevepryde</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stevepryde"/>
    <language>en</language>
    <item>
      <title>A better home for your automated test results</title>
      <dc:creator>Steve Pryde</dc:creator>
      <pubDate>Mon, 23 Feb 2026 20:30:00 +0000</pubDate>
      <link>https://dev.to/stevepryde/a-better-home-for-your-automated-test-results-3951</link>
      <guid>https://dev.to/stevepryde/a-better-home-for-your-automated-test-results-3951</guid>
      <description>&lt;p&gt;In my previous job, I was tasked with creating the test automation for a SaaS startup, from scratch. It was a 10-person team working in a share-office. Over the next four years it would double in size each year and then got acquired by a fortune-100 company. The test automation story went from zero to a full test automation platform, with a test results database integrated with JIRA, automated test runners that auto-scale, and an interface where any developer could run their tests on demand, on any branch. This was more than a job. It was a passion project and I'm grateful for that experience.&lt;/p&gt;

&lt;p&gt;I am proud of what I achieved in those four years, initially solo and later with a small test automation team that was eventually folded into the dev team as demand for tests increased. We were running 30,000 tests per month, and yet the automation infrastructure was still just getting started.&lt;/p&gt;

&lt;p&gt;Two features in particular taught me what developers actually want from test tooling.&lt;/p&gt;

&lt;p&gt;The first was the screenshot comparison tool. The MVP was written in two days and yet it became one of our most valuable features. A single endpoint for uploading a screenshot, triggered in tests by a single function call. Each screenshot was given a code in the test. The first upload with that code became the reference image. Subsequent uploads would be compared to the reference and given a score, as well as a new image generated showing the diff in two different shades. Later I built an entire UI around it including pan-and-zoom so you could compare the two images, approve/reject, or leave comments for that image code.&lt;/p&gt;

&lt;p&gt;The second was the JIRA integration. Knowing when a test failed for the same reason that had already been captured in a ticket was invaluable. And if there wasn't a ticket, you could click a button and it would open the "create ticket" flow in JIRA with the description already pre-populated with the error message, some useful context, and a link to the original test result. Subsequent failures of the same type would search for the error message and then show that ticket against the test result. You could also mark it as a "known failure", so you would know not to waste time diagnosing it again. If the same test then failed for any other reason, you'd know it was a new failure mode.&lt;/p&gt;

&lt;p&gt;What both of these had in common was a simple idea: test results are data, and they deserve better than a CI log.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated Future
&lt;/h2&gt;

&lt;p&gt;Today, I'm taking what I learned from those four years and building my own platform. It's called &lt;a href="https://automatedfuture.co" rel="noopener noreferrer"&gt;Automated Future&lt;/a&gt;, and the core idea is straightforward: &lt;strong&gt;CI is for builds. AF is for tests.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most projects start out with CI running your tests. That's fine for a short while but it doesn't scale. Your results end up buried in logs that expire, terminal output that's already gone, or artifacts scattered across half a dozen services. There's no single place to see your test health over time. No trends. No search. No history.&lt;/p&gt;

&lt;p&gt;Automated Future gives your test results a dedicated home.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it does today
&lt;/h3&gt;

&lt;p&gt;AF is a test results platform with a dashboard, a CLI, and a public API, accessible via API Keys. Invite your team and set up projects for each of your apps. It works with any test framework that produces JUnit XML output, which covers Jest, Vitest, pytest, JUnit, RSpec, Go test, NUnit, xUnit, and more. It integrates into any CI pipeline — GitHub Actions, GitLab CI, Jenkins, whatever you use.&lt;/p&gt;

&lt;p&gt;The fastest way to get results into AF is with the CLI. Install it, then wrap your existing test command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;af run &lt;span class="nt"&gt;--&lt;/span&gt; npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single command creates a test run, executes your tests, auto-discovers the JUnit XML files, parses and uploads the results, and exits with your test command's exit code so your pipeline still fails when it should. You don't change how your tests work. You just prefix the command.&lt;/p&gt;

&lt;p&gt;Once results are flowing in, the dashboard gives you a real view of your test health:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pass/fail charts and trend graphs over time, so you can see at a glance whether things are getting better or worse&lt;/li&gt;
&lt;li&gt;A searchable, sortable history of every test run and result across all your projects&lt;/li&gt;
&lt;li&gt;A custom query language for filtering your data — JIRA users will find the syntax familiar (&lt;code&gt;status = Failed AND duration &amp;gt; 5000&lt;/code&gt;, &lt;code&gt;started_at &amp;gt; -7d&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Artifact storage with in-browser previews — upload screenshots, videos, logs, or JSON to any test result and view them directly in the dashboard with syntax highlighting, image zoom, and video playback&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Where it's going
&lt;/h3&gt;

&lt;p&gt;The features I described earlier — the screenshot comparison, the JIRA integration, the known failure tracking — those are all on the roadmap. But rather than building them in an opinionated way, I want to build them with input from developers who are actually using the platform. The problems I solved at my previous company aren't unique. Every team doing test automation hits the same pain points. I'd rather build solutions shaped by real feedback than assumptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out
&lt;/h2&gt;

&lt;p&gt;Automated Future is live and free to get started with. You can be up and running in about five minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://dashboard.automatedfuture.co" rel="noopener noreferrer"&gt;dashboard.automatedfuture.co&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a project and grab your API key&lt;/li&gt;
&lt;li&gt;Install the CLI in your pipeline&lt;/li&gt;
&lt;li&gt;Wrap your test command with &lt;code&gt;af run&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Open the dashboard and see your results&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://docs.automatedfuture.co" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; has step-by-step guides for every major CI system and test framework.&lt;/p&gt;

&lt;p&gt;If you're interested in helping to shape where this goes, I'd love to hear from you. Try it out, tell me what's missing, tell me what matters to you. Let's build a better home for test results together.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>automation</category>
      <category>testing</category>
      <category>devops</category>
    </item>
    <item>
      <title>Create a desktop app in Rust using Tauri and Yew</title>
      <dc:creator>Steve Pryde</dc:creator>
      <pubDate>Sun, 16 Jan 2022 05:31:38 +0000</pubDate>
      <link>https://dev.to/stevepryde/create-a-desktop-app-in-rust-using-tauri-and-yew-2bhe</link>
      <guid>https://dev.to/stevepryde/create-a-desktop-app-in-rust-using-tauri-and-yew-2bhe</guid>
      <description>&lt;p&gt;I recently created a complete desktop app in Rust using Tauri and Yew. A few people expressed interest in how I did this, so here is a tutorial to show how to get started.&lt;/p&gt;

&lt;p&gt;If you're into Rust and want to build desktop apps, Tauri is a great choice. It's still very early days for web front-ends in Rust but Yew is already quite usable as you will see.&lt;/p&gt;

&lt;p&gt;So let's get started.&lt;/p&gt;

&lt;p&gt;First let's create a directory for our new project. We'll create a monorepo containing separate directories for the front-end and the back-end.&lt;/p&gt;

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

mkdir tauri-yew-demo
cd tauri-yew-demo
git init


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

&lt;/div&gt;

&lt;p&gt;If you like, you can create a new github repository for it and add the git origin following the instructions &lt;a href="https://docs.github.com/en/get-started/getting-started-with-git/managing-remote-repositories" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All of the code in this tutorial is available on my github if you want to just download it and follow along:&lt;br&gt;
&lt;a href="https://github.com/stevepryde/tauri-yew-demo" rel="noopener noreferrer"&gt;https://github.com/stevepryde/tauri-yew-demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Front-end
&lt;/h2&gt;

&lt;p&gt;Next we'll create the front-end directory. We do this first because later the &lt;code&gt;tauri&lt;/code&gt; setup will ask where this directory is.&lt;/p&gt;

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

cargo new --bin frontend
cd frontend
mkdir public


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

&lt;/div&gt;

&lt;p&gt;(The &lt;code&gt;public&lt;/code&gt; directory is where our CSS will go)&lt;/p&gt;

&lt;p&gt;Since this will be the &lt;code&gt;Yew&lt;/code&gt; part of the project, let's follow the setup instructions here: &lt;a href="https://yew.rs/docs/getting-started/introduction" rel="noopener noreferrer"&gt;https://yew.rs/docs/getting-started/introduction&lt;/a&gt;&lt;/p&gt;

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

rustup target add wasm32-unknown-unknown
cargo install trunk
cargo install wasm-bindgen-cli


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

&lt;/div&gt;

&lt;p&gt;Next create &lt;code&gt;index.html&lt;/code&gt; in the base of the &lt;code&gt;frontend&lt;/code&gt; directory:&lt;/p&gt;

&lt;p&gt;frontend/index.html&lt;/p&gt;

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

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Tauri Yew Demo App&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;data-trunk&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"css"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/public/main.css"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We'll also create &lt;code&gt;main.css&lt;/code&gt; in the &lt;code&gt;public/&lt;/code&gt; directory we created earlier:&lt;/p&gt;

&lt;p&gt;frontend/public/main.css&lt;/p&gt;

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

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2d2d2d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.heading&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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 can now build your frontend app and view it in the browser! Let's test it out:&lt;/p&gt;

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

trunk build
trunk serve


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

&lt;/div&gt;

&lt;p&gt;Now open your browser and go to &lt;code&gt;http::/localhost:8080&lt;/code&gt;. You should see a blank page with a grey background.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You may be wondering why we are viewing this in a browser when we are supposed to be creating a desktop app. We will get to that soon. Tauri essentially bundles your web app inside a desktop app using the OS-provided browser rendering engine to display your front-end app. So the process of creating your front-end part is very similar to creating a regular web front-end, except that instead of making HTTP requests to an external web server, we will make function calls to the tauri back-end via some Javascript glue code (there's very little Javascript required, I promise!).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Adding Yew
&lt;/h3&gt;

&lt;p&gt;We haven't yet added &lt;code&gt;yew&lt;/code&gt; to the project, so let's do that now.&lt;/p&gt;

&lt;p&gt;To install rust packages to your project, I highly recommend the &lt;code&gt;cargo-edit&lt;/code&gt; tool, which you can install via &lt;code&gt;cargo install cargo-edit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;cargo-edit&lt;/code&gt; installed you can do:&lt;/p&gt;

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

cargo add yew


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

&lt;/div&gt;

&lt;p&gt;If you prefer to add dependencies manually, just add the following lines to the &lt;code&gt;dependencies&lt;/code&gt; section of &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;/p&gt;

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

yew = "0.19.3"


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

&lt;/div&gt;

&lt;p&gt;Now open &lt;code&gt;src/main.rs&lt;/code&gt; and replace its contents with the following:&lt;/p&gt;

&lt;p&gt;frontend/src/main.rs&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;yew&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;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;start_app&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;App&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="nd"&gt;#[function_component(App)]&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;app&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;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"heading"&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="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&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;Now you should be able to re-run &lt;code&gt;trunk serve&lt;/code&gt; and see the updated page in your browser. This is a real Rust front-end, compiled to WASM, running in your browser. Yes, it is that easy!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By the way, if you ever wish to make a regular &lt;code&gt;Yew&lt;/code&gt; web front-end, you can follow the exact same process and just continue on with this front-end as a standalone project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Adding Tauri
&lt;/h2&gt;

&lt;p&gt;For this step you'll need to be back in the base &lt;code&gt;tauri-yew-demo&lt;/code&gt; directory. Hit &lt;code&gt;Ctrl+C&lt;/code&gt; if you're still running &lt;code&gt;trunk serve&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you're still in the &lt;code&gt;frontend&lt;/code&gt; directory, go up one directory:&lt;/p&gt;

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

cd ..


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

&lt;/div&gt;

&lt;p&gt;Tauri has its own CLI that we'll use to manage the app.&lt;/p&gt;

&lt;p&gt;There are various installation options but since we're using Rust, we'll install it via &lt;code&gt;cargo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The Tauri CLI installation instructions can be found here: &lt;a href="https://tauri.studio/docs/getting-started/beginning-tutorial#alternatively-install-tauri-cli-as-a-cargo-subcommand" rel="noopener noreferrer"&gt;https://tauri.studio/docs/getting-started/beginning-tutorial#alternatively-install-tauri-cli-as-a-cargo-subcommand&lt;/a&gt;&lt;/p&gt;

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

cargo install tauri-cli --locked --version ^1.0.0-rc


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;EDIT: Many readers have had trouble installing the Tauri CLI due to various bugs in previous versions or compatibility issues with newer Rust versions. I recommend checking the &lt;a href="https://tauri.studio/docs/getting-started/beginning-tutorial#alternatively-install-tauri-cli-as-a-cargo-subcommand" rel="noopener noreferrer"&gt;official docs&lt;/a&gt; and following the instructions there, especially as the Tauri CLI version gets updated in the future.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then run &lt;code&gt;cargo tauri init&lt;/code&gt; which will ask you some questions about the app:&lt;/p&gt;

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

$ cargo tauri init
What is your app name?: tauri-yew-demo
What should the window title be?: Tauri Yew Demo
Where are your web assets (HTML/CSS/JS) located, relative to the "&amp;lt;current dir&amp;gt;/src-tauri/tauri.conf.json" file that will be created?: ../frontend/dist
What is the url of your dev server?: http://localhost:8080


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

&lt;/div&gt;

&lt;p&gt;This will create a &lt;code&gt;src-tauri&lt;/code&gt; directory, containing all of the back-end code for your app.&lt;/p&gt;

&lt;p&gt;You can run &lt;code&gt;cargo tauri info&lt;/code&gt; to check all of the installation details.&lt;/p&gt;

&lt;p&gt;Before we can run the app, we need to tell &lt;code&gt;tauri&lt;/code&gt; how to actually start the front-end server.&lt;/p&gt;

&lt;p&gt;Edit the &lt;code&gt;tauri.conf.json&lt;/code&gt; file that is in the &lt;code&gt;src-tauri&lt;/code&gt; directory. This file contains all of the tauri config that tells tauri how to build your app. You will want to bookmark &lt;a href="https://tauri.studio/en/docs/api/config/" rel="noopener noreferrer"&gt;https://tauri.studio/en/docs/api/config/&lt;/a&gt; because it contains a lot of very useful info about all of the options in this file. For now we will just update the build settings.&lt;/p&gt;

&lt;p&gt;Replace the &lt;code&gt;build&lt;/code&gt; section with the following:&lt;/p&gt;

&lt;p&gt;src-tauri/tauri.conf.json&lt;/p&gt;

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

"build": {
    "distDir": "../frontend/dist",
    "devPath": "http://localhost:8080",
    "beforeDevCommand": "cd frontend &amp;amp;&amp;amp; trunk serve",
    "beforeBuildCommand": "cd frontend &amp;amp;&amp;amp; trunk build",
    "withGlobalTauri": true
  },


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

&lt;/div&gt;

&lt;p&gt;This means we won't need to manually run &lt;code&gt;trunk serve&lt;/code&gt; in another tab while developing. We can develop in the front-end and back-end and both will hot-reload automatically when changes are made.&lt;/p&gt;

&lt;p&gt;Ok, we're now ready to start the tauri dev server that you'll use while developing your app:&lt;/p&gt;

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

cargo tauri dev


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

&lt;/div&gt;

&lt;p&gt;And there's your desktop app, running with &lt;code&gt;tauri&lt;/code&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding tauri commands
&lt;/h2&gt;

&lt;p&gt;Tauri itself is written in Rust and your back-end application will be a Rust application that provides "commands" through &lt;code&gt;tauri&lt;/code&gt; in much the same way that a Rust web-server provides routes. You can even have managed state, for things like &lt;code&gt;sqlite&lt;/code&gt; databases!&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;src/main.rs&lt;/code&gt; in the &lt;code&gt;src-tauri&lt;/code&gt; project and add the following below the &lt;code&gt;main()&lt;/code&gt; function:&lt;/p&gt;

&lt;p&gt;src-tauri/src/main.rs&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;#[tauri::command]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="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;Result&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="p"&gt;,&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="c1"&gt;// This is a very simplistic example but it shows how to return a Result&lt;/span&gt;
  &lt;span class="c1"&gt;// and use it in the front-end.&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.contains&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Name should not contain spaces"&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="k"&gt;else&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="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="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 will also need to modify the &lt;code&gt;main()&lt;/code&gt; function slightly to tell &lt;code&gt;tauri&lt;/code&gt; about your new command:&lt;/p&gt;

&lt;p&gt;src-tauri/src/main.rs&lt;/p&gt;

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

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nn"&gt;tauri&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.invoke_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;tauri&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;generate_handler!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="nf"&gt;.run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;tauri&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;generate_context!&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error while running tauri application"&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's all for the back-end.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more details on what you can do with &lt;code&gt;tauri&lt;/code&gt; commands, including async commands, error handling and accessing managed state, I highly recommend reading through all of the sections in the &lt;code&gt;tauri&lt;/code&gt; docs here: &lt;a href="https://tauri.studio/en/docs/guides/command" rel="noopener noreferrer"&gt;https://tauri.studio/en/docs/guides/command&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Accessing tauri commands from Rust in the front-end
&lt;/h2&gt;

&lt;p&gt;In order to access tauri commands on the front-end in Rust/WASM we need to add some glue code in Javascript.&lt;/p&gt;

&lt;p&gt;There is a &lt;code&gt;tauri&lt;/code&gt; npm package but since we want to keep any Javascript usage to a minimum and prefer to use &lt;code&gt;cargo&lt;/code&gt; and &lt;code&gt;trunk&lt;/code&gt; to manage our front-end, we will use a different approach.&lt;/p&gt;

&lt;p&gt;Tauri also exports its functions via the &lt;code&gt;window&lt;/code&gt; object in Javascript.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;front-end&lt;/code&gt; project, create a new file called &lt;code&gt;glue.js&lt;/code&gt; inside the &lt;code&gt;public/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;frontend/public/glue.js&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoke&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__TAURI__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;invoke&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;invokeHello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&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 is all the Javascript we will add. I told you it would be minimal!&lt;/p&gt;

&lt;p&gt;Notice that the Javascript function is async. That is because the tauri &lt;code&gt;invoke()&lt;/code&gt; command returns a Javascript promise. And through WASM, Javascript promises can be converted into Rust futures. Just let that awesomeness sink in for a while :)&lt;/p&gt;

&lt;p&gt;How do we call that Javascript function from Rust? We add more glue code, this time in Rust. Add the following in your frontend's &lt;code&gt;main.rs&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;frontend/src/main.rs&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;#[wasm_bindgen(module&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/public/glue.js"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[wasm_bindgen(js_name&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;invokeHello,&lt;/span&gt; &lt;span class="nd"&gt;catch)]&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;JsValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;JsValue&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;Here we tell wasm_bindgen about our javascript code in &lt;code&gt;/public/glue.js&lt;/code&gt;. We give it the javascript function name, and the &lt;code&gt;catch&lt;/code&gt; parameter tells wasm_bindgen that we want to add a &lt;code&gt;catch()&lt;/code&gt; handler to the javascript promise and turn it into a &lt;code&gt;Result&lt;/code&gt; in Rust.&lt;/p&gt;

&lt;p&gt;This new code won't work yet, because we haven't added &lt;code&gt;wasm-bindgen&lt;/code&gt; to our front-end dependencies. Let's do that now. We'll also add &lt;code&gt;wasm-bindgen-futures&lt;/code&gt; which we'll use to call this later, &lt;code&gt;web-sys&lt;/code&gt; which provides access to the browser &lt;code&gt;window&lt;/code&gt; object, and &lt;code&gt;js-sys&lt;/code&gt; which gives us the &lt;code&gt;JsValue&lt;/code&gt; types we referenced above.&lt;/p&gt;

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

cargo add wasm-bindgen
cargo add wasm-bindgen-futures
cargo add web-sys
cargo add js-sys


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

&lt;/div&gt;

&lt;p&gt;This will add the following dependencies to &lt;code&gt;Cargo.toml&lt;/code&gt; in the front-end:&lt;/p&gt;

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

wasm-bindgen = "0.2.78"
wasm-bindgen-futures = "0.4.28"
web-sys = "0.3.55"
js-sys = "0.3.55"


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

&lt;/div&gt;

&lt;p&gt;We also need to add some imports to the top of main.rs.&lt;/p&gt;

&lt;p&gt;frontend/src/main.rs&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;wasm_bindgen&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;wasm_bindgen_futures&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;spawn_local&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;web_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;So now we've added the glue code in Javascript and the Rust code that calls that method. What we need to do is wire that up to the front-end code and actually use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling Tauri commands in Yew code
&lt;/h2&gt;

&lt;p&gt;In version 0.19 Yew added function components, which operate much like React hooks if you're familiar with the React framework in Javascript. If you're not familiar with that, I will attempt to give a brief explanation of the concepts used in this tutorial, but a fuller explanation of hooks is out of scope. The yew docs themselves go into some more detail. &lt;/p&gt;

&lt;p&gt;Replace the function component in your front-end &lt;code&gt;main.rs&lt;/code&gt; with the following:&lt;/p&gt;

&lt;p&gt;frontend/src/main.rs&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;#[function_component(App)]&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;app&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;Html&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;welcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use_state_eq&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use_state_eq&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="s"&gt;"World"&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;// Execute tauri command via effects.&lt;/span&gt;
    &lt;span class="c1"&gt;// The effect will run every time `name` changes.&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;welcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;welcome&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;use_effect_with_deps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;update_welcome_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="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;message&lt;/span&gt; &lt;span class="o"&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;welcome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"heading"&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="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&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;fn&lt;/span&gt; &lt;span class="nf"&gt;update_welcome_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UseStateHandle&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="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;spawn_local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This will call our glue code all the way through to the tauri&lt;/span&gt;
        &lt;span class="c1"&gt;// back-end command and return the `Result&amp;lt;String, String&amp;gt;` as&lt;/span&gt;
        &lt;span class="c1"&gt;// `Result&amp;lt;JsValue, JsValue&amp;gt;`.&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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="n"&gt;welcome&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.as_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;window&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;window&lt;/span&gt;
                    &lt;span class="nf"&gt;.alert_with_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                    &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;And this should compile and run.&lt;/p&gt;

&lt;p&gt;Navigate up one directory (to the &lt;code&gt;tauri-yew-demo&lt;/code&gt; directory), and run:&lt;/p&gt;

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

cargo tauri dev


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

&lt;/div&gt;

&lt;p&gt;You should see the application window showing &lt;code&gt;Hello, World!&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9l7wl9f5njmldbt9zml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9l7wl9f5njmldbt9zml.png" alt="App screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, that was a lot of code. Let's unpack it.&lt;/p&gt;

&lt;p&gt;First we add some state to the component through the &lt;code&gt;use_state_eq&lt;/code&gt; hook.&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;welcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use_state_eq&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use_state_eq&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Component state has an initial value, and a method for updating that value. Normally, updating a state value will cause the component to be re-rendered with the new value.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;use_state_eq&lt;/code&gt; hook gives us a state handle that will only cause the component to be re-rendered if the value has changed. It uses Rust's &lt;code&gt;PartialEq&lt;/code&gt; trait for this.&lt;/p&gt;

&lt;p&gt;You can dereference a &lt;code&gt;UseStateHandle&lt;/code&gt; to get the underlying state value.&lt;/p&gt;

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

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;welcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;welcome&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;use_effect_with_deps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;update_welcome_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="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 need to clone the &lt;code&gt;welcome&lt;/code&gt; handle so that we can move it into the closure.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;use_effect_with_deps()&lt;/code&gt; hook is a variant of the &lt;code&gt;use_effect&lt;/code&gt; hook where this one only runs the hook when some dependency changes. &lt;/p&gt;

&lt;p&gt;It takes two arguments. The first is the closure we want to run when the dependency value changes, and the second is the dependency value itself.&lt;/p&gt;

&lt;p&gt;In this example the dependency is specified as &lt;code&gt;(*name).clone()&lt;/code&gt;, which means we are dereferencing the handle to get the underlying &lt;code&gt;String&lt;/code&gt; and then cloning the &lt;code&gt;String&lt;/code&gt; because we cannot move it.&lt;/p&gt;

&lt;p&gt;That value is then passed as the argument to the closure.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;use_effect*()&lt;/code&gt; hook is generally used to do some longer operation or some async operation where the component will update with the result of that operation. This is why we pass in the &lt;code&gt;welcome&lt;/code&gt; handle, because this allows the closure to set the value of that handle, which will cause the component to re-render, but only if the value has changed. Calls to tauri commands will generally go inside a &lt;code&gt;use_effect&lt;/code&gt; or &lt;code&gt;use_effect_with_deps&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;The return value of the closure is always another closure that will run when the component is unloaded from the virtual DOM. You can use this closure to perform any cleanup relating to this effect hook. In this case there is nothing to clean up so we return an empty closure.&lt;/p&gt;

&lt;p&gt;Let's look at the &lt;code&gt;update_welcome_message()&lt;/code&gt; function.&lt;/p&gt;

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

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;update_welcome_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UseStateHandle&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="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;spawn_local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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="n"&gt;welcome&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.as_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="o"&gt;...&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;spawn_local()&lt;/code&gt; function is from &lt;code&gt;wasm_bindgen_futures&lt;/code&gt; and it allows us to run async functions in the current thread. In this case we need it in order to call our &lt;code&gt;hello()&lt;/code&gt; function, because it is async.&lt;/p&gt;

&lt;p&gt;Next we call the &lt;code&gt;hello()&lt;/code&gt; function, which returns &lt;code&gt;Result&amp;lt;JsValue, JsValue&amp;gt;&lt;/code&gt;. We know the &lt;code&gt;JsValue&lt;/code&gt; will be a string since the original tauri command we implemented returned &lt;code&gt;Result&amp;lt;String, String&amp;gt;&lt;/code&gt;, so we can just unwrap() here.&lt;/p&gt;

&lt;p&gt;Finally if the result was &lt;code&gt;Ok(..)&lt;/code&gt; then we set the new value of the &lt;code&gt;welcome&lt;/code&gt; state variable. Otherwise we display an alert. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Alerts are not a great way to handle errors like this, but as a simple example it shows how the &lt;code&gt;Result&lt;/code&gt; type is passed through to the front-end. In a proper application you would probably want to show a toast popup and optionally log to the browser console (in debug builds).&lt;br&gt;
See the &lt;a href="https://docs.rs/wasm-logger/0.2.0/wasm_logger/" rel="noopener noreferrer"&gt;&lt;code&gt;wasm-logger&lt;/code&gt;&lt;/a&gt; crate for an easy way to send logs to the browser console using the &lt;code&gt;log&lt;/code&gt; crate macros.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Hopefully this tutorial has given you a taste for how to create a desktop app almost entirely in Rust, using &lt;code&gt;Tauri&lt;/code&gt; for the back-end and &lt;code&gt;Yew&lt;/code&gt; for the front-end.&lt;/p&gt;

&lt;p&gt;You can find all of the code for this tutorial on my github:&lt;br&gt;
&lt;a href="https://github.com/stevepryde/tauri-yew-demo" rel="noopener noreferrer"&gt;https://github.com/stevepryde/tauri-yew-demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to use it and modify it as a base for your own projects.&lt;/p&gt;

&lt;p&gt;I highly recommend reading through the documentation for both Tauri and Yew.&lt;/p&gt;

&lt;p&gt;Tauri: &lt;a href="https://tauri.studio/en/docs/get-started/intro" rel="noopener noreferrer"&gt;https://tauri.studio/en/docs/get-started/intro&lt;/a&gt;&lt;br&gt;
Yew: &lt;a href="https://yew.rs/docs/getting-started/introduction" rel="noopener noreferrer"&gt;https://yew.rs/docs/getting-started/introduction&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If there's anything I missed or anything that is still unclear from this tutorial, please let me know in the comments and I'll aim to update it.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>webassembly</category>
      <category>tauri</category>
      <category>yew</category>
    </item>
    <item>
      <title>Using Selenium with Rust</title>
      <dc:creator>Steve Pryde</dc:creator>
      <pubDate>Sun, 29 Nov 2020 01:57:21 +0000</pubDate>
      <link>https://dev.to/stevepryde/using-selenium-with-rust-aca</link>
      <guid>https://dev.to/stevepryde/using-selenium-with-rust-aca</guid>
      <description>&lt;p&gt;Selenium is a tool for automating web browsers, and is often used for testing websites, especially for end-to-end testing. Rust is commonly known as a Systems Programming language and might not be your first choice when it comes to browser testing but it can actually work pretty well.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, let's introduce Rust.
&lt;/h2&gt;

&lt;p&gt;For those who may not be familiar with the Rust language, let me give you a small taste of what its strengths are. This won't be a comprehensive introduction, but I hope to give you a sense of why this language exists and what it can offer you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Performance&lt;br&gt;
Rust code often performs very well due to it being a statically compiled language and also due to it encouraging patterns that naturally lead to good optimizations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safety&lt;br&gt;
Rust prevents entire classes of common bugs and mistakes, which means your code is more likely to work correctly. Safety-by-default is a very common theme in Rust.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rich type system&lt;br&gt;
Rust has a very expressive type system which allows you to more accurately model your data objects and the relationships between them. It borrows many of the best features from other languages including its familiar syntax.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Awesome and welcoming community&lt;br&gt;
Rust has a fantastic community behind it, willing to help you learn and succeed with the language. &lt;a href="https://www.rust-lang.org/community"&gt;Click here for more info&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Required tools for selenium
&lt;/h2&gt;

&lt;p&gt;To use selenium, we first need to download the selenium server from &lt;a href="https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Selenium server is written in Java so you will also need Java installed.&lt;/p&gt;

&lt;p&gt;We also need a &lt;code&gt;webdriver&lt;/code&gt; to interact with your browser of choice. We will use Chrome, so you will need &lt;code&gt;chromedriver&lt;/code&gt; which you can download from &lt;a href="https://chromedriver.chromium.org/downloads"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check your version of Chrome (open Chrome and select &lt;code&gt;menu &amp;gt; Help &amp;gt; About Google Chrome&lt;/code&gt;) and then download the version of &lt;code&gt;chromedriver&lt;/code&gt; that corresponds to your version of Chrome.&lt;/p&gt;

&lt;p&gt;Unzip the downloaded file and place the &lt;code&gt;chromedriver&lt;/code&gt; executable somewhere in your PATH. You can put it in the same directory as the selenium jar file if you want.&lt;/p&gt;

&lt;p&gt;Now start selenium like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java -jar selenium-server-standalone-3.141.59.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should start selenium server on port 4444.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's see the code
&lt;/h2&gt;

&lt;p&gt;In order to interact with a web browser from Rust we will use the &lt;code&gt;thirtyfour&lt;/code&gt; library (or "crate" in Rust lingo).&lt;/p&gt;

&lt;p&gt;It is called "thirtyfour" because 34 is the atomic number for the Selenium chemical element.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Full Disclosure: I wrote the &lt;code&gt;thirtyfour&lt;/code&gt; crate, with contributions from several other volunteers as well.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;thirtyfour&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="n"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;color_eyre&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="nn"&gt;color_eyre&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;install&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;caps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;DesiredCapabilities&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="nf"&gt;.add_chrome_arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"--enable-automation"&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="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebDriver&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="s"&gt;"http://localhost:4444/wd/hub"&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;caps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://wikipedia.org"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="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;p&gt;Some brief notes about other crates we are using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We are using tokio for async/await. If you want to learn more about async in Rust, &lt;a href="https://rust-lang.github.io/async-book/01_getting_started/01_chapter.html"&gt;click here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you prefer not to use async, there is a sync version of the crate called &lt;a href="https://docs.rs/thirtyfour_sync"&gt;thirtyfour_sync&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We are also using the awesome &lt;code&gt;color_eyre&lt;/code&gt; crate for error reporting. It makes any error messages much clearer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok, so firstly we set up a &lt;code&gt;DesiredCapabilities&lt;/code&gt; struct. In this case we want to use the Chrome presets. There are also presets for other browsers (to use other browsers you need the webdriver for that browser in your PATH).&lt;/p&gt;

&lt;p&gt;We want to enable the automation flags for Chrome, via this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="nf"&gt;.add_chrome_arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"--enable-automation"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we start the web browser and return a &lt;code&gt;WebDriver&lt;/code&gt; struct for us to interact with it.&lt;/p&gt;

&lt;p&gt;If you run the above code you should see a Chrome browser open and automatically navigate to &lt;code&gt;https://wikipedia.org&lt;/code&gt;. Note that selenium will automatically wait for the page to load. This can all happen fairly quickly so if you need it to wait at the end you can add this line (requires the &lt;code&gt;time&lt;/code&gt; feature of tokio):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;time&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&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;from_secs&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="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(In previous versions of tokio, &lt;code&gt;sleep&lt;/code&gt; was named &lt;code&gt;delay_for&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Aside: The ? symbol in Rust
&lt;/h3&gt;

&lt;p&gt;You may be wondering what the ? symbol is for at the end of each line. This is an error-handling feature of Rust. You can see that the main() function returns a Result. This means it can either return &lt;code&gt;Ok(value)&lt;/code&gt; or &lt;code&gt;Err(error_value)&lt;/code&gt;. The ? is a shorthand way of handling the error without having to type out all of the boilerplate code.&lt;/p&gt;

&lt;p&gt;It is the equivalent of doing something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebDriver&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="s"&gt;"http://localhost:4444/wd/hub"&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;caps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&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;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this would get very tedious so instead Rust provides the ? operator so we can just do this instead:&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;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebDriver&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="s"&gt;"http://localhost:4444/wd/hub"&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;caps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Great! Now let's make it do something
&lt;/h3&gt;

&lt;p&gt;First we want to find a particular element. To do this we use an element selector. We can search by Id, Name, Class name, Tag, and we can use CSS or XPath selectors as well.&lt;/p&gt;

&lt;p&gt;To keep things simple, let's search by Id.&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;elem_search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="nf"&gt;.find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;By&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"searchInput"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;elem_search&lt;/span&gt;&lt;span class="nf"&gt;.send_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"selenium"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will find the element with the id &lt;code&gt;searchInput&lt;/code&gt; and then type the word &lt;code&gt;selenium&lt;/code&gt; into it.&lt;/p&gt;

&lt;p&gt;Note that we can also search for an element that is nested below another element. Another way to locate the &lt;code&gt;searchInput&lt;/code&gt; element is as follows:&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;elem_form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="nf"&gt;.find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;By&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"search-form"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;elem_search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;elem_form&lt;/span&gt;&lt;span class="nf"&gt;.find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;By&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"searchInput"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will first find the element with id &lt;code&gt;search-form&lt;/code&gt; and then it will look for an element with id &lt;code&gt;searchInput&lt;/code&gt; that is nested below the first element. This can be useful for performing more complex element searches, however you should also check out CSS and XPath selectors which can often do the same thing in one single query.&lt;/p&gt;

&lt;p&gt;If you want to get more information about this element, you can get CSS properties like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Font size: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elem_search&lt;/span&gt;&lt;span class="nf"&gt;.get_css_property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"font-size"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will display the font size of the &lt;code&gt;search&lt;/code&gt; input element.&lt;/p&gt;

&lt;p&gt;Ok, now let's find a button and click it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;elem_button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;elem_form&lt;/span&gt;&lt;span class="nf"&gt;.find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;By&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"button[type='submit']"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;elem_button&lt;/span&gt;&lt;span class="nf"&gt;.click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you can see the CSS selector being used to locate the &lt;code&gt;button&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;If preferred you can shorten the code by simply chaining these calls together, 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="n"&gt;elem_form&lt;/span&gt;&lt;span class="nf"&gt;.find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;By&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"button[type='submit']"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nf"&gt;.click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point we could "sleep" for a few seconds to wait for the page to load, but using "sleep" in selenium tests is often very unreliable and can result in flaky tests.&lt;/p&gt;

&lt;p&gt;Instead, it is better to locate some element on the page that indicates the page has finished loading. So let's wait for the page heading.&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;driver&lt;/span&gt;&lt;span class="nf"&gt;.find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;By&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;ClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"firstHeading"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, &lt;code&gt;thirtyfour&lt;/code&gt; sets a 30 second implicit wait for all element searches. For more advanced polling, see &lt;a href="https://docs.rs/thirtyfour_query"&gt;thirtyfour_query&lt;/a&gt;, but the implicit wait will work fine for this particular example.&lt;/p&gt;

&lt;p&gt;If for some reason the element was not found within 30 seconds, the above call would return an error (&lt;code&gt;WebDriverError::NoSuchElement&lt;/code&gt;). That error would be propagated up by the ? operator and would return the error from the &lt;code&gt;main()&lt;/code&gt; function, exiting the program.&lt;/p&gt;

&lt;p&gt;Now we can display the page title, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Title = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="nf"&gt;.title&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this should display "Selenium - Wikipedia" if everything has worked correctly.&lt;/p&gt;

&lt;p&gt;So hopefully this has given you a taste of how you can automate a web browser in Rust. This is also useful for testing your web applications, especially if those applications are also written in Rust.&lt;/p&gt;

&lt;h2&gt;
  
  
  A little "Rusty" feature
&lt;/h2&gt;

&lt;p&gt;There is one more thing I want to point out, and it's something perhaps unique to Rust.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;thirtyfour&lt;/code&gt; crate uses a feature of Rust called &lt;code&gt;lifetimes&lt;/code&gt; to guarantee at compile-time that no references to the selenium session can be used after the browser has been instructed to close. It does this by sharing a reference to the session between the &lt;code&gt;WebDriver&lt;/code&gt; and all &lt;code&gt;WebElement&lt;/code&gt; structs related to it. When you call &lt;code&gt;WebDriver::quit()&lt;/code&gt; (or the &lt;code&gt;WebDriver&lt;/code&gt; struct goes out of scope) this will consume the struct and destroy the session, and this means Rust knows that all of the other references to it are now invalid and cannot be used.&lt;/p&gt;

&lt;p&gt;The following code will not compile:&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;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebDriver&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="s"&gt;"http://localhost:4444/wd/hub"&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;caps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://wikipedia.org"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;elem_search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="nf"&gt;.find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;By&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"searchInput"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// The session is "moved" here, preventing further use of either the driver or elements.&lt;/span&gt;
&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="nf"&gt;.quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="c1"&gt;// This attempts to "borrow" the session after it has been moved, which Rust will not allow.&lt;/span&gt;
&lt;span class="n"&gt;elem_search&lt;/span&gt;&lt;span class="nf"&gt;.send_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"this won't work"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rust compiler tells us that the call to &lt;code&gt;driver.quit()&lt;/code&gt; here is not allowed because the driver is also "borrowed" later in the call to &lt;code&gt;elem_search.send_keys()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;While other selenium libraries may be able to perform such checks at runtime, Rust is able to do the check at compile-time, saving you time in debugging and making your tests a little bit more reliable from the start.&lt;/p&gt;

&lt;p&gt;Thank you for reading. Hopefully I have shown you that interacting with a web browser in Rust can be quite easy, especially if you are already familiar with Selenium :)&lt;/p&gt;

&lt;p&gt;For more documentation on the &lt;code&gt;thirtyfour&lt;/code&gt; crate, &lt;a href="https://docs.rs/thirtyfour"&gt;click here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>selenium</category>
      <category>webdriver</category>
    </item>
    <item>
      <title>Why Learn Rust?</title>
      <dc:creator>Steve Pryde</dc:creator>
      <pubDate>Fri, 27 Nov 2020 12:35:59 +0000</pubDate>
      <link>https://dev.to/stevepryde/why-learn-rust-1dag</link>
      <guid>https://dev.to/stevepryde/why-learn-rust-1dag</guid>
      <description>&lt;p&gt;In this article I want to share my thoughts on what Rust is really good for, why it exists, and what it can offer you that other languages might not.&lt;/p&gt;

&lt;p&gt;I find that when I learn anything new, I first need to have a reason for learning it. There needs to be a purpose. What can it offer me? The same is true for programming languages. Learning anything can bring challenges and some setbacks, and overcoming those is going to be a lot easier if we can answer that simple question... "Why?"&lt;/p&gt;

&lt;h1&gt;
  
  
  Bugs
&lt;/h1&gt;

&lt;p&gt;I hate bugs. I hate using software that has bugs. I hate it when programs crash, or go slow, or use all of my computer's memory, or leave my data vulnerable to security flaws.&lt;/p&gt;

&lt;p&gt;In 2020 we are still using and writing software that has the same bugs, the same mistakes, the same security issues, that were present 20 or even 30 years ago.&lt;/p&gt;

&lt;h1&gt;
  
  
  The human factor
&lt;/h1&gt;

&lt;p&gt;Most modern programming languages focus on making coding easier, and many have succeeded. But unfortunately they often make coding bugs easier too. We need a change.&lt;/p&gt;

&lt;p&gt;Most programming languages still leave it up to the programmer to "get everything right" and it is up to us to remember to put in all of the right safety checks. But programmers are lazy (myself included). We take shortcuts and tell ourselves we'll fix it later. We never fix it later. And so we still have software that crashes.&lt;/p&gt;

&lt;p&gt;We tell ourselves that bugs are the programmer's fault. We just need to write better code. Follow better practices. Use better tooling. Become better programmers. Become more experienced.&lt;/p&gt;

&lt;p&gt;But is that enough? Even experienced programmers can (and often do) make the same mistakes. We're all human.&lt;/p&gt;

&lt;p&gt;Today we have coding guidelines, formatters, linters, static analysis, profilers, benchmarks, unit tests, entire test frameworks, CI/CD, best practices, architects, analysts, experienced software engineers, and open source. And these are all fantastic things that really do help. But they're still not enough.&lt;/p&gt;

&lt;p&gt;We still make the same mistakes. Null pointer access, double-free, use-after-free, data races, undefined variables, type mismatch, conversion errors, unhandled exceptions, uncaught errors, and a whole lot more!&lt;/p&gt;

&lt;h1&gt;
  
  
  Enter Rust
&lt;/h1&gt;

&lt;p&gt;This is why Rust exists. It won't prevent all bugs. No language will do that. But it can prevent entire classes of bugs and that is something we haven't really seen in this industry before in a relatively mainstream language. No null pointers. No data races. Sum types (for more accurate modeling). Exhaustive pattern matching. And a strong focus on correctness and safety by default.&lt;/p&gt;

&lt;p&gt;I believe the whole point of Rust, its reason for being, is to allow programmers like you and me to create software that does exactly what we want, with less bugs, and runs faster. By making many types of bugs impossible, I think Rust really does deliver on that goal. Yes it has some new concepts to learn that may be different from other languages, but in return it enables you to create software that is more reliable, with better error handling, and awesome performance. It is not uncommon to spend a little more time fixing errors reported by the compiler, and then much less time debugging.&lt;/p&gt;

&lt;p&gt;Last but not least, learning Rust will teach you a lot about common programming mistakes and how to avoid them, even when you're programming in other languages. It will change the way you code everywhere, for the better.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>safety</category>
      <category>performance</category>
    </item>
    <item>
      <title>Rust String vs &amp;str</title>
      <dc:creator>Steve Pryde</dc:creator>
      <pubDate>Sat, 10 Oct 2020 13:22:45 +0000</pubDate>
      <link>https://dev.to/stevepryde/rust-string-vs-str-1l93</link>
      <guid>https://dev.to/stevepryde/rust-string-vs-str-1l93</guid>
      <description>&lt;p&gt;"Why does Rust have different types of Strings? Why not just one String type?"&lt;/p&gt;

&lt;p&gt;I have seen these questions posed in different ways online and it is true that Rust's &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;&amp;amp;str&lt;/code&gt; types can be confusing for people new to Rust, especially people who are familiar with dynamic programming languages. So let's talk about the two string types and see if we can clear up some of the confusion.&lt;/p&gt;

&lt;p&gt;It will make sense eventually and Rust really does need both types. They are quite different and have different use cases.&lt;/p&gt;

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

&lt;p&gt;It's all about "who owns the memory".&lt;/p&gt;

&lt;h4&gt;
  
  
  String
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;String&lt;/code&gt; contains a string in memory and owns the memory for it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;String&lt;/code&gt; for returning strings created within a function or (usually) when storing strings in a struct or enum.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you have a &lt;code&gt;String&lt;/code&gt; you can pass a reference to it to convert it to &lt;code&gt;&amp;amp;str&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &amp;amp;str
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;amp;str&lt;/code&gt; is just a reference to another string (slice) but does not own the memory for it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prefer &lt;code&gt;&amp;amp;str&lt;/code&gt; in function arguments to accept string slices and make it clear the function will not mutate the string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you have a &lt;code&gt;&amp;amp;str&lt;/code&gt; and want a new &lt;code&gt;String&lt;/code&gt; you can clone it either by &lt;code&gt;to_owned()&lt;/code&gt; or &lt;code&gt;to_string()&lt;/code&gt; (they are effectively the same - use whichever makes your code clearer to read and consistent). These will copy the memory and make a new &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  It's about memory and ownership
&lt;/h2&gt;

&lt;p&gt;Firstly, we need to talk a little about how Rust manages memory. I'll try to keep this brief but it will be very important later when we discuss the difference between &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;&amp;amp;str&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As you may be aware, Rust does not have a garbage collector. That means, the compiler needs to explicitly allocate and deallocate memory at specific points in the code, and it needs a mechanism for determining when something is no longer in use so that its memory can be deallocated safely.&lt;/p&gt;

&lt;p&gt;This mechanism in Rust is called "ownership" (and "borrowing"). Consider the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="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;owned_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;print_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;owned_string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// In Rust we return s by omitting the semicolon&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;print_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="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;my_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;p&gt;Here in &lt;code&gt;get_string()&lt;/code&gt; we allocate memory for a String on the heap (to learn more about what the heap is, &lt;a href="https://doc.rust-lang.org/1.22.0/book/first-edition/the-stack-and-the-heap.html"&gt;see here&lt;/a&gt;) and assign it to the variable &lt;code&gt;s&lt;/code&gt;. At this point we can say that &lt;code&gt;s&lt;/code&gt; "owns" that memory. The Rust compiler will now track the scope of &lt;code&gt;s&lt;/code&gt; in order to know when to deallocate it. This would occur when &lt;code&gt;s&lt;/code&gt; goes out of scope, unless &lt;code&gt;s&lt;/code&gt; is instead "moved" (which you can think of like a transfer of ownership). In the above case, &lt;code&gt;s&lt;/code&gt; is indeed moved, into the variable &lt;code&gt;owned_string&lt;/code&gt; at the top.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;get_string()&lt;/code&gt; returns, the memory isn't copied and it doesn't go anywhere. Rather, the ownership of that memory is now transferred to the caller (in this case the variable &lt;code&gt;owned_string&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The Rust compiler would now track this new owner &lt;code&gt;owned_string&lt;/code&gt; in order to know when to deallocate. In this case it would be deallocated at the end of the &lt;code&gt;main()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;String&lt;/code&gt; will only ever have 1 owner. That owner can allow others to "borrow" it temporarily (see the line &lt;code&gt;print_string(&amp;amp;owned_string);&lt;/code&gt;) , but the memory will only be deallocated when the owner goes out of scope (unless it is moved, in which case it will be deallocated when the new owner goes out of scope, and so on).&lt;/p&gt;

&lt;h1&gt;
  
  
  Borrowing and references
&lt;/h1&gt;

&lt;p&gt;So now let's look at the other function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;print_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="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;my_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;p&gt;The &lt;code&gt;&amp;amp;&lt;/code&gt; symbol means this is a reference to a &lt;code&gt;str&lt;/code&gt; (a string slice). You will almost never use &lt;code&gt;str&lt;/code&gt; without &lt;code&gt;&amp;amp;&lt;/code&gt; so it's easier to just think of them as &lt;code&gt;&amp;amp;str&lt;/code&gt;, or "a reference to a string slice".&lt;/p&gt;

&lt;p&gt;Consider the &lt;code&gt;String&lt;/code&gt; we had earlier with its owned, allocated memory. What if we wanted to pass a reference to that string (or part of it), but without allowing the recipient to modify it. In Rust we call that an "immutable borrow", and that is what the &lt;code&gt;&amp;amp;&lt;/code&gt; means. It is like a "reference" in other languages, but Rust goes a step further and lets you declare whether or not its contents can be mutated (changed).&lt;/p&gt;

&lt;p&gt;In the above example we could have used &lt;code&gt;&amp;amp;String&lt;/code&gt; in the function signature instead of &lt;code&gt;&amp;amp;str&lt;/code&gt; and that would have worked ok because we passed in the entire string anyway. However, that wouldn't allow other callers to pass in a substring (at least without copying its memory into another &lt;code&gt;String&lt;/code&gt;). This is where a string slice &lt;code&gt;&amp;amp;str&lt;/code&gt; is much more useful.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;amp;str&lt;/code&gt; is effectively a pointer directly to the string's memory, with a fixed length. You will notice in the original code the line &lt;code&gt;print_string(&amp;amp;owned_string);&lt;/code&gt;. We passed a reference to a &lt;code&gt;String&lt;/code&gt; into the function, but the function wanted &lt;code&gt;&amp;amp;str&lt;/code&gt;. This works because the &lt;code&gt;String&lt;/code&gt; type can automatically convert into &lt;code&gt;&amp;amp;str&lt;/code&gt; - this is just returning a pointer to the very same memory, with a known length. &lt;code&gt;&amp;amp;str&lt;/code&gt; is also an immutable reference so you cannot modify the memory it points to.&lt;/p&gt;

&lt;p&gt;In fact, Rust will ensure that the &lt;code&gt;&amp;amp;str&lt;/code&gt; is safe to use (even across threads!) by guaranteeing that &lt;em&gt;nothing&lt;/em&gt; can modify the memory it points to (even the owner), for as long as the &lt;code&gt;&amp;amp;&lt;/code&gt; reference variable is in scope. Rust will also guarantee that the owned &lt;code&gt;String&lt;/code&gt; (that the &lt;code&gt;&amp;amp;str&lt;/code&gt; points to) cannot go out of scope while the reference remains in scope (otherwise the reference would be a dangling pointer). These are very powerful features of Rust's borrow checker that prevent all kinds of nasty bugs you might encounter with other languages where you create a string over here then pass a reference to it over there but it accidentally modifies the original.&lt;/p&gt;

&lt;h2&gt;
  
  
  The difference between String and &amp;amp;str is...
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;String&lt;/code&gt; holds a string in memory and owns the memory for it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;amp;str&lt;/code&gt; is just a reference to another string but it doesn't own the memory for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use either one
&lt;/h2&gt;

&lt;p&gt;In general, use &lt;code&gt;String&lt;/code&gt; in structs and enums where you want the struct or enum to own the contents. Also use &lt;code&gt;String&lt;/code&gt; when returning a string from a function where that string was allocated within the function (Rust will not let you return a reference in that case because the memory would be deallocated at the end of the function and the reference returned would be a dangling pointer)&lt;/p&gt;

&lt;p&gt;Prefer &lt;code&gt;&amp;amp;str&lt;/code&gt; for function arguments unless you explicitly want to move a &lt;code&gt;String&lt;/code&gt; into the function and give up ownership of it (this tends to be rare).&lt;/p&gt;

&lt;h2&gt;
  
  
  One last time...
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;String&lt;/code&gt; when you need to own the memory, for example you created a string in a function and need to return it.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;&amp;amp;str&lt;/code&gt; when you want an immutable reference to memory that is owned by another &lt;code&gt;String&lt;/code&gt; variable (or a string literal in your code).&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Intro to Rust Modules</title>
      <dc:creator>Steve Pryde</dc:creator>
      <pubDate>Wed, 07 Oct 2020 13:13:23 +0000</pubDate>
      <link>https://dev.to/stevepryde/intro-to-rust-modules-3g8k</link>
      <guid>https://dev.to/stevepryde/intro-to-rust-modules-3g8k</guid>
      <description>&lt;p&gt;The Rust module system can be very confusing and difficult to understand when you are just starting out learning Rust. Something as simple as just putting a function in another file and importing it into your &lt;code&gt;main.rs&lt;/code&gt; can send you on a frustrating search and leave you with even more questions.&lt;/p&gt;

&lt;p&gt;In this article I will share some info that I hope will be helpful in understanding how to make better use of the module system and perhaps even start to embrace the functionality it gives you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just import by file path?
&lt;/h2&gt;

&lt;p&gt;I'm sure this is the approach many of us tried first and we were disappointed when it didn't work.&lt;/p&gt;

&lt;p&gt;As an example, let's imagine we have some file called &lt;code&gt;cat.rs&lt;/code&gt; and it contains the function &lt;code&gt;meow()&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;meow&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;"Meow, Meow!"&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 then we try to call &lt;code&gt;meow()&lt;/code&gt; from &lt;code&gt;main.rs&lt;/code&gt; like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="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;meow&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 Rust says no:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0425]: cannot find function `meow` in this scope
 --&amp;gt; src/main.rs:2:5
  |
2 |     meow();
  |     ^^^^ not found in this scope
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok. We forgot to make &lt;code&gt;meow()&lt;/code&gt; public using the &lt;code&gt;pub&lt;/code&gt; keyword, so we will fix that now and try again. Nope, same error.&lt;/p&gt;

&lt;p&gt;What we might try next is something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;cat&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="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;meow&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 we get this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0432]: unresolved import `cat`
 --&amp;gt; src/main.rs:1:5
  |
1 | use cat;
  |     ^^^ no `cat` external crate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mistake in the above code is that it assumes there is a 1 to 1 mapping between module name and our directory structure. However, Rust does not work like that, and I think this is the key point that helps in understanding how Rust modules work.&lt;/p&gt;

&lt;p&gt;Rust's module paths are not tied directly to the filesystem. Rather we need to tell Rust a little more about the module structure before we can &lt;code&gt;use&lt;/code&gt; our modules in our code. That is, think of the module structure as its own thing independent of the file system layout. First we need to tell Rust where each file belongs in the module hierarchy, and then we can import our module using the "module path" rather than the filesystem path.&lt;/p&gt;

&lt;p&gt;This can seem cumbersome at first, but you will come to understand the reasons why it works this way.&lt;/p&gt;

&lt;p&gt;To demonstrate why Rust doesn't just use file paths as the module path, let's look at an example with multiple modules in one file, like this &lt;code&gt;main.rs&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;mod&lt;/span&gt; &lt;span class="n"&gt;cat&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;meow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;woof&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;mod&lt;/span&gt; &lt;span class="n"&gt;dog&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;woof&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;"Woof, Woof!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;meow&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;Obviously using separate modules for this is overkill but it demonstrates the way modules work.&lt;/p&gt;

&lt;p&gt;Note that we need to use the &lt;code&gt;pub&lt;/code&gt; keyword to allow each function to be visible to other modules (and you can also make things private to a module by omitting the &lt;code&gt;pub&lt;/code&gt; keyword).&lt;/p&gt;

&lt;p&gt;This will compile. And when we run it we get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Woof, Woof!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we can see that &lt;code&gt;mod cat&lt;/code&gt; created a kind of module path with the function &lt;code&gt;meow()&lt;/code&gt; nested below it, even though it is in the same file. And the module itself is nested below a global namespace called &lt;code&gt;crate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this way we can declare different module namespaces in a much more flexible way than if we could only use file paths. For a simple example like this you may think it is unnecessarily complex but when you are writing a library and you want to provide a nice import structure for your API without needing to match that exact structure in your filesystem, this is a really nice feature. If you have ever used a library that let you do: &lt;code&gt;use somelib::prelude::*;&lt;/code&gt; that is one of the benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about different files?
&lt;/h2&gt;

&lt;p&gt;Ok, so hopefully multiple modules in 1 file makes sense. What about importing functions from another file?&lt;/p&gt;

&lt;p&gt;Let's return to our first example, with &lt;code&gt;meow()&lt;/code&gt; declared in another file, named &lt;code&gt;cat.rs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The change we need to make within &lt;code&gt;main.rs&lt;/code&gt; is to first tell Rust about the module &lt;code&gt;cat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The way we do this is by adding the following to our &lt;code&gt;main.rs&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;mod&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That tells Rust to look for either a &lt;code&gt;cat.rs&lt;/code&gt; in the same directory OR alternatively a directory named &lt;code&gt;cat&lt;/code&gt; with a &lt;code&gt;mod.rs&lt;/code&gt; file within it (but you cannot have both a &lt;code&gt;cat.rs&lt;/code&gt; file and a &lt;code&gt;cat&lt;/code&gt; directory). We will get to directories shortly.&lt;/p&gt;

&lt;p&gt;In our case we have &lt;code&gt;cat.rs&lt;/code&gt; in the same directory, so now in our &lt;code&gt;main.rs&lt;/code&gt; we can call the function within that module like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;cat&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="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that works!&lt;/p&gt;

&lt;h2&gt;
  
  
  What about directories?
&lt;/h2&gt;

&lt;p&gt;Previously I mentioned that &lt;code&gt;mod cat;&lt;/code&gt; could point to a directory named &lt;code&gt;cat&lt;/code&gt; containing a file called &lt;code&gt;mod.rs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's create this directory for our example, and then move &lt;code&gt;cat.rs&lt;/code&gt; into that directory. Actually we will also rename &lt;code&gt;cat.rs&lt;/code&gt; to &lt;code&gt;kitten.rs&lt;/code&gt; to disambiguate (it's in a "child" module hehe).&lt;/p&gt;

&lt;p&gt;So now we have a &lt;code&gt;main.rs&lt;/code&gt; and a directory named &lt;code&gt;cat&lt;/code&gt; containing two files, &lt;code&gt;mod.rs&lt;/code&gt; and &lt;code&gt;kitten.rs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We &lt;em&gt;could&lt;/em&gt; just put our &lt;code&gt;meow()&lt;/code&gt; function in &lt;code&gt;mod.rs&lt;/code&gt; and that would work just fine. However let's show how to import from another file within that directory.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;mod.rs&lt;/code&gt; we now need to tell Rust about &lt;code&gt;kitten.rs&lt;/code&gt;, 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;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;kitten&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note the &lt;code&gt;pub&lt;/code&gt; keyword which makes the &lt;code&gt;kitten&lt;/code&gt; module visible to the parent module as well)&lt;/p&gt;

&lt;p&gt;But now our &lt;code&gt;main()&lt;/code&gt; would need to call &lt;code&gt;meow()&lt;/code&gt; 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;mod&lt;/span&gt; &lt;span class="n"&gt;cat&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="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;kitten&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if instead we wanted to use the original import path in &lt;code&gt;main()&lt;/code&gt;, while keeping our new file structure? Can we do that?&lt;/p&gt;

&lt;p&gt;Yes we can! This is where Rust's module system hopefully starts to make more sense.&lt;/p&gt;

&lt;p&gt;Try this in &lt;code&gt;mod.rs&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;mod&lt;/span&gt; &lt;span class="n"&gt;kitten&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;use&lt;/span&gt; &lt;span class="nn"&gt;kitten&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now we can once again call &lt;code&gt;cat::meow()&lt;/code&gt; from within our &lt;code&gt;main()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;What this does is within &lt;code&gt;mod.rs&lt;/code&gt; we tell Rust about another module, called &lt;code&gt;kitten&lt;/code&gt; (which here points to &lt;code&gt;kitten.rs&lt;/code&gt; in the same directory as &lt;code&gt;mod.rs&lt;/code&gt;), which then becomes visible to the current module scope. But without the &lt;code&gt;pub&lt;/code&gt; keyword, the nested module is invisible to the parent. Rather than make the entire module visible, we can import the &lt;code&gt;meow()&lt;/code&gt; function from that module via &lt;code&gt;use&lt;/code&gt; and we can make only this import public (visible to the parent module) with &lt;code&gt;pub use&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We could even change the name of the function when re-exporting it, like this, in &lt;code&gt;mod.rs&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;mod&lt;/span&gt; &lt;span class="n"&gt;kitten&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;use&lt;/span&gt; &lt;span class="nn"&gt;kitten&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;meow&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;woof&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and now our &lt;code&gt;main()&lt;/code&gt; would need to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;woof&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you are starting to see the flexibility that the Rust module system gives you over your entire namespace hierarchy. You can organise your files in a way that is convenient for you, and you can export your structs and modules in the way that makes more sense for the caller.&lt;/p&gt;

&lt;p&gt;Sometimes these will be the same, and sometimes they won't. Rust lets you choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declaring the module hierarchy in one place
&lt;/h2&gt;

&lt;p&gt;Putting module declarations in &lt;code&gt;mod.rs&lt;/code&gt; files and so on is ok, but I personally think it can start to lead to too many module declarations scattered throughout the codebase and it can become difficult to follow.&lt;/p&gt;

&lt;p&gt;In my own code I prefer to declare the entire module structure in &lt;code&gt;main.rs&lt;/code&gt; (or &lt;code&gt;lib.rs&lt;/code&gt; for library crates), which avoids the need for any &lt;code&gt;mod.rs&lt;/code&gt; files while offering all of the same functionality.&lt;/p&gt;

&lt;p&gt;For our above example, we can have our directory named &lt;code&gt;cat&lt;/code&gt; and within it just the file &lt;code&gt;kitten.rs&lt;/code&gt; (no &lt;code&gt;mod.rs&lt;/code&gt; this time), and now our &lt;code&gt;main.rs&lt;/code&gt; can look 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;mod&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;kitten&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;use&lt;/span&gt; &lt;span class="nn"&gt;kitten&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;meow&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="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I discovered this, that was the moment when I realised how powerful the Rust module system really is. This lets me describe my module structure all in one place, and then my whole crate can just refer to this structure to import things.&lt;/p&gt;

&lt;p&gt;For example, let's add a new directory below &lt;code&gt;cat&lt;/code&gt; called &lt;code&gt;activities&lt;/code&gt; and containing a file called &lt;code&gt;play.rs&lt;/code&gt;.&lt;br&gt;
Here is &lt;code&gt;play.rs&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;CatToy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;CatToy&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;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="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="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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&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="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;fetch&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="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;"Fetch the {}"&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;.name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can describe this layout in &lt;code&gt;main.rs&lt;/code&gt; like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// We still have our imports from before.&lt;/span&gt;
    &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;kitten&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;use&lt;/span&gt; &lt;span class="nn"&gt;kitten&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// And now we describe the additional structure.&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;activities&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;mod&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;activities&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;play&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;CatToy&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="s"&gt;"ball"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="nf"&gt;.fetch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is ok, but our import path is a bit long. We want to keep our files organised but we don't want the callers of these functions to have to worry about our directory structure. Or perhaps we want to modify our directory structure without modifying the import paths (so users of your crate don't need to update their code too).&lt;/p&gt;

&lt;p&gt;So we can shorten the import path 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;mod&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;kitten&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;use&lt;/span&gt; &lt;span class="nn"&gt;kitten&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;activities&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;mod&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;activities&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;play&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="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;ball&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;CatToy&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="s"&gt;"ball"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="nf"&gt;.fetch&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 you can see this greatly simplifies the use of the code for the caller.&lt;/p&gt;

&lt;h2&gt;
  
  
  One last thing (well, several)
&lt;/h2&gt;

&lt;p&gt;If you're importing (with &lt;code&gt;use&lt;/code&gt;) something into another module outside of &lt;code&gt;main.rs&lt;/code&gt;, you would need to add &lt;code&gt;crate::&lt;/code&gt; to the start of the module path.&lt;/p&gt;

&lt;p&gt;For example, if we wanted to use &lt;code&gt;CatToy&lt;/code&gt; from another file:&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="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CatToy&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;fetch_ball&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;ball&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CatToy&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="s"&gt;"ball"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="nf"&gt;.fetch&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 didn't need to do that in the above examples because the &lt;code&gt;main()&lt;/code&gt; function was already at the base level &lt;code&gt;crate&lt;/code&gt; scope and all of the other modules were children of that scope.&lt;/p&gt;

&lt;p&gt;Finally, if you just want to import and use a module somewhere without needing to re-export it to the parent module, you don't need &lt;code&gt;pub use&lt;/code&gt;. Just &lt;code&gt;use crate::module::path;&lt;/code&gt; will work fine. Only use &lt;code&gt;pub&lt;/code&gt; when you need to make something visible to the parent scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;p&gt;Hopefully this article has helped to make the Rust module system a little easier to understand.&lt;/p&gt;

&lt;p&gt;There is a lot more that I didn't cover.&lt;/p&gt;

&lt;p&gt;If you want to read more about this, I highly recommend the documentation at &lt;a href="https://doc.rust-lang.org/rust-by-example/mod.html"&gt;Rust By Example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also the &lt;a href="https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html"&gt;Official Rust Book&lt;/a&gt; has a good section on this as well.&lt;/p&gt;

&lt;p&gt;I found a lot of the official documentation difficult to understand at first, but once I understood the basics of modules I was able to go back and re-read them and everything started to fall into place. It still took a lot of practice to get my head around it, but now I find it really nice and very powerful.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>import</category>
      <category>module</category>
      <category>system</category>
    </item>
    <item>
      <title>Using Types To Prevent Unit Conversion Errors</title>
      <dc:creator>Steve Pryde</dc:creator>
      <pubDate>Mon, 09 Mar 2020 03:10:27 +0000</pubDate>
      <link>https://dev.to/stevepryde/using-types-to-prevent-unit-conversion-errors-1fka</link>
      <guid>https://dev.to/stevepryde/using-types-to-prevent-unit-conversion-errors-1fka</guid>
      <description>&lt;p&gt;What if we could use static types to prevent passing a value in Centimetres to a function that expected Inches? Or what if we could prevent passing a Person id to a function that expected a Book id?&lt;/p&gt;

&lt;p&gt;In this article I will show you a technique I use all the time that can accomplish just that. I did not come up with this technique. I just find it incredibly useful.&lt;/p&gt;

&lt;p&gt;I will give examples in Rust (and a few in TypeScript) but you can adapt this technique to other statically typed languages as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Ids
&lt;/h2&gt;

&lt;p&gt;Suppose you have a function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;give_book_to_person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_id&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="py"&gt;.books&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What would happen if you accidentally called it with the ids in the wrong order? 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="nf"&gt;give_book_to_person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;person_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This could result in a runtime error (could not find book? could not find person?), or worse it could give the wrong book to the wrong person! We used static types, but both ids are the same type so the compiler won't complain. This kind of problem can be difficult to debug and cause headaches for you later.&lt;/p&gt;

&lt;p&gt;So how do we avoid it?&lt;/p&gt;

&lt;p&gt;We wrap the ids in their own types. This allows the type system to work for us, and can practically eliminate this class of bugs entirely.&lt;/p&gt;

&lt;p&gt;Let's see how it works.&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="nf"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;BookId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;give_book_to_person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BookId&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;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="py"&gt;.books&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book_id&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 if we call this with the ids the wrong way around, we will get a compile-time error. Congratulations, you have just saved yourself a headache and a lot of time!&lt;/p&gt;

&lt;p&gt;But wait, how do we access the wrapped value?&lt;/p&gt;

&lt;p&gt;In Rust, you can do it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;person_id&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it is much better to keep the internal value private and provide an accessor method instead.&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="nf"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;PersonId&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;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;person_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PersonId&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;person_id&lt;/span&gt;&lt;span class="nf"&gt;.id&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another pattern is to use the dereference operator to access the internal value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ops&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Deref&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Deref&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;PersonId&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;Target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;deref&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="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Target&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="na"&gt;.0&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;person_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PersonId&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;person_id&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other languages you might use an object and access the member variable by name. For example, in TypeScript you might do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;PersonId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;personId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// We can access the actual id like this:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;myId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;personId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typically the internal value should only be accessed when outputting the value, or when calling an external function from another library. By keeping all access to the internal value within the same file, we reduce the potential for mistakes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Equality comparison
&lt;/h3&gt;

&lt;p&gt;Sometimes you will want to compare an id against another to see if they match. Remember we want to limit any access to the internal value to as few places as possible. The best way to do this is to do the equality check via operator overloading, or via an instance method on the type itself.&lt;/p&gt;

&lt;p&gt;In Rust we can simply derive the Eq (i.e. equality) 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="nd"&gt;#[derive(Eq,&lt;/span&gt; &lt;span class="nd"&gt;PartialEq)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;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;person_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PersonId&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;person_b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PersonId&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;person_a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;person_b&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;"It's a match!"&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;If your language supports operator overloading, you can use a similar approach. However, a language like TypeScript does not support operator overloading, so we would instead do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;PersonId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="nx"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;other&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;personA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PersonId&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;personB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PersonId&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;personA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;personB&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;It's a match!&lt;/span&gt;&lt;span class="dl"&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;Feel free to add any other comparison methods you find useful. By only adding these methods to the class / object itself, we limit the places that access the internal value, and thus significantly reduce the possibility of making a mistake.&lt;/p&gt;

&lt;p&gt;Everywhere else, we use the PersonId object, and the compiler will be able to check that we always supplied an instance of the correct type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unit Conversion
&lt;/h2&gt;

&lt;p&gt;By now you should be able to see other uses for this technique. My other favourite is in unit conversion.&lt;/p&gt;

&lt;p&gt;Suppose we want to convert between Centimetres and Inches. We might provide a function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;convert_inches_to_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inches&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="nb"&gt;f32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;inches&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.54&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;get_rect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&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;height&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="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="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// How big is the rect going to be?&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;width_cm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convert_inches_to_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&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;height_cm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convert_inches_to_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width_cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height_cm&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;Do you see the problem?&lt;/p&gt;

&lt;p&gt;We (or someone else working on the same code) might call &lt;code&gt;get_rect()&lt;/code&gt; with values that are already in cm, and get unexpected results.&lt;/p&gt;

&lt;p&gt;How do we avoid this? We wrap each unit in its own type!&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="nf"&gt;Centimetres&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;impl&lt;/span&gt; &lt;span class="nb"&gt;From&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Inches&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;Centimetres&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;from&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="n"&gt;Inches&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="nf"&gt;Centimetres&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.54&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;struct&lt;/span&gt; &lt;span class="nf"&gt;Inches&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;impl&lt;/span&gt; &lt;span class="nb"&gt;From&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Centimetres&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;Inches&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;from&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="n"&gt;Centimetres&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="nf"&gt;Inches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.54&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;// Might as well make the Rect a type too.&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;RectInCM&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Centimetres&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Centimetres&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;get_rect_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Inches&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Inches&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;RectInCM&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;RectInCM&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="nf"&gt;.into&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;Great! Now it is very unlikely you will get the units wrong again. More headaches and debugging time avoided!&lt;/p&gt;

&lt;p&gt;But we can do even better. Rust supports generics, which means we can write the &lt;code&gt;get_rect_cm()&lt;/code&gt; function in a way that supports either units.&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;get_rect_cm&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;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;RectInCM&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="nb"&gt;Into&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Centimetres&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;RectInCM&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="nf"&gt;.into&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;Generics are beyond the scope of this article, but basically what this is saying is that the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; parameters must both be the same type, and that type can be anything that implements the trait &lt;code&gt;Into&amp;lt;Centimetres&amp;gt;&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now you can call &lt;code&gt;get_rect_cm()&lt;/code&gt; and pass in either &lt;code&gt;Centimetres&lt;/code&gt; or &lt;code&gt;Inches&lt;/code&gt; and it will always produce the correct &lt;code&gt;RectInCM&lt;/code&gt; struct.&lt;/p&gt;

&lt;p&gt;Pretty neat, hey?&lt;/p&gt;

&lt;p&gt;I hope you find this technique useful.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>typescript</category>
      <category>types</category>
    </item>
    <item>
      <title>In defence of (some) fragmentation</title>
      <dc:creator>Steve Pryde</dc:creator>
      <pubDate>Sun, 08 Mar 2020 03:16:09 +0000</pubDate>
      <link>https://dev.to/stevepryde/in-defence-of-some-fragmentation-3j6j</link>
      <guid>https://dev.to/stevepryde/in-defence-of-some-fragmentation-3j6j</guid>
      <description>&lt;p&gt;Any time a new project is announced, especially in a relatively young language such as Rust, there will be the inevitable responses regarding "fragmentation", "wasted effort", "duplication of work" and so on.&lt;/p&gt;

&lt;p&gt;I believe these responses are usually born out of a genuine desire to build a better, more mature ecosystem, and the fear that competing projects will mean slower progress towards that goal. There may be cases where these fears are justified, but in general I disagree with them.&lt;/p&gt;

&lt;p&gt;In this article I aim to show why I think these responses are usually counter-productive.&lt;/p&gt;

&lt;h2&gt;
  
  
  The benefits of pooling resources
&lt;/h2&gt;

&lt;p&gt;Firstly, let's look at some of the positives that come from pooling resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Maturity
&lt;/h3&gt;

&lt;p&gt;Anyone familiar with Open Source knows that lots of eyes on the code can lead to more bug reports, more contributions towards fixing those bugs, and thus a more stable and mature project.&lt;/p&gt;

&lt;p&gt;There is also the ecosystem that can build up around a project in the form of plug-ins, supporting libraries, interoperability with other projects, and perhaps more importantly, better tutorials, books, and online courses. The guarantee that a project is going to be around for the long term should not be understated, and this allows developers and companies to invest resources in building products based on the stable and mature codebase. These are all very good things.&lt;/p&gt;

&lt;h3&gt;
  
  
  Productivity
&lt;/h3&gt;

&lt;p&gt;When a project becomes stable and mature, it is likely that it will meet the needs of a greater percentage of downstream developers, companies, and so on. That means they can use the project to build products that benefit their customers, and they can spend their time and effort building their own products rather than debugging the upstream project or trying to figure out how it works. The increased educational resources mentioned above also lead to greater productivity across the board. Now companies can mention the project in their hiring criteria and they can likely find developers who already know how to work with the upstream software.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost of pooling resources
&lt;/h2&gt;

&lt;p&gt;The above benefits are great, but there are also some downsides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are larger teams always more productive?
&lt;/h3&gt;

&lt;p&gt;Let's assess the idea that if everyone worked on a single project, that project would move faster, and conversely if many people worked on different projects, progress would be slower.&lt;/p&gt;

&lt;p&gt;Anyone who has managed a large team of people knows that progress in a software project does not scale linearly with the number of people contributing to it. There is real complexity that emerges once a team grows beyond certain milestones (the actual numbers are fuzzy). The more developers you have, the greater the potential there is for bugs, internal fragmentation (feature A does not interoperate well with feature B), and instability. Larger projects need more maintainers willing to oversee the project design and hold regular team meetings to determine the technical direction of the project.&lt;/p&gt;

&lt;p&gt;I am not saying that large teams never work. Clearly they do. Projects such as the Linux kernel show that large software projects can work incredibly well. Open Source is built on the incredible ability of humans to collaborate and achieve amazing things. But this collaboration isn't easy, and it does come with several costs. More contributors will bring technical and practical challenges that must be overcome, and this will generally mean the project must move much slower in order to guarantee consistency and harmony between the contributions and the overall vision and direction of the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do larger projects really move faster?
&lt;/h3&gt;

&lt;p&gt;Once a project matures it will also see a growing user base, with many other projects that now depend on it. Stability and backwards-compatibility then become far more important goals than adding new experimental features. Every change requires more and more testing to ensure it does not break some other part of the software, and does not break any projects that rely on it.&lt;/p&gt;

&lt;p&gt;The result of all of this is, contrary to the original assumption, projects with a larger codebase may actually move much slower. The slowdown comes from some combination of having a greater emphasis on API stability and backwards-compatibility, and also the technical and practical complexity that comes from managing a larger team of people.&lt;/p&gt;

&lt;p&gt;In general (though there surely are exceptions), the larger the project, the less it is able to innovate rapidly. Backwards-compatibility and API stability are benefits that often come at the cost of reduced innovation.&lt;/p&gt;

&lt;h2&gt;
  
  
  An alternative view
&lt;/h2&gt;

&lt;p&gt;If larger projects tend to move slower and innovate less, should we abandon all large projects in favour of smaller ones? Or should we cap the number of contributors?&lt;/p&gt;

&lt;p&gt;No, of course not! As mentioned at the top of this article, there are clear benefits to having larger projects that are more robust, mature, and stable. This article is not suggesting we stop supporting these projects. We have to stop thinking in terms of "there can only be one". It's not either-or. We can do both.&lt;/p&gt;

&lt;p&gt;Rather, what I am proposing is that we continue to support these larger projects where they provide benefits to us, but I think we should also allow space in the ecosystem for more upstarts and offshoots. Look at them as budding experiments that may or may not provide valuable benefits down the track.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where does innovation come from?
&lt;/h3&gt;

&lt;p&gt;Choose any large software project and take a look back in history to when it was just starting out. How did it become the project it is today? Did it do so by people only contributing their efforts onto other projects that existed before? Or was there instead some point where an individual or small team started a new project and tried to build something better. They may have seen a niche that needed to be filled, or a better way to do something. It is very often the entrepreneurial drive of such individuals that sees the creation of new paradigms, new frameworks, and new ways of making software.&lt;/p&gt;

&lt;p&gt;Almost every piece of software we use today was once a competitor to some larger, more mature product. The new projects could innovate much faster because they did not have the baggage of legacy software, legacy features and a long history of dependencies and unfortunate design decisions. There will always be early-adopters willing to try a new piece of software and put up with the bugs and instability in exchange for some benefit not available elsewhere. As more people join the project, the trend towards maturity and away from innovation begins, but the original innovation remains. Innovation can still happen of course - but with every stable API release, the pace of innovation and experimentation must inevitably slow down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does fragmentation really slow the pace of software?
&lt;/h3&gt;

&lt;p&gt;If we were building physical products, then it follows logically that if a person spends their time and energy on one product, that time and energy is not being spent on other products. However, software is not like that, especially when it comes to Open Source.&lt;/p&gt;

&lt;p&gt;If I make a change to a piece of software, or implement a useful feature, the only thing preventing others from copying said feature would be Copyright/Trademark laws and the like. In the world of Open Source this restriction is often reduced or eliminated (depending on the licenses used). We can and should share code between projects, and benefit from each other's work, giving appropriate attribution generously as we go. Definitely ask for permission from the author if you are unsure. Software patents complicate this a lot but that is beyond the scope of this article.&lt;/p&gt;

&lt;p&gt;If a feature is implemented in a competing project and becomes well-received by users, other projects should be encouraged to implement it also, either by re-using the code or the design or otherwise tweaking the overall idea to fit. In this way, fragmentation isn't zero-sum in terms of features and effort. Everyone benefits from the ideas of others, and we end up with the best of all possible features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fragmentation = Experimentation, and that is a Good Thing&lt;sup&gt;TM&lt;/sup&gt;
&lt;/h3&gt;

&lt;p&gt;When we view competing projects as little experiments designed to explore some corner or niche in design space, the picture changes. No longer are we looking at "wasted effort", but rather we are looking at parallel development that might lead to exciting new innovations down the track. Some of those innovations may even be incorporated back into the other projects once they have proven their effectiveness and success.&lt;/p&gt;

&lt;p&gt;True, most of these experiments will go nowhere and may fizzle out early, but we can learn from those outcomes too. It is this repeated process of experiment, implementation, evaluation, and reincorporation of what we learned, that drives software innovation right across the industry. It has always been thus, and we are all the beneficiaries of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The downsides of fragmentation
&lt;/h2&gt;

&lt;p&gt;There are some notable downsides to fragmentation, however, and I would like to mention a few of them so that we can learn how best to avoid them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Confusion for newcomers
&lt;/h3&gt;

&lt;p&gt;Probably the main downside of fragmentation is the confusing landscape presented to newcomers. Anyone who has used Linux in the 90's or early 2000's knows of the confusing process of figuring out which distro they should try. Each distro had its own pros and cons, and each had its own band of proponents advocating one and disparaging others.&lt;/p&gt;

&lt;p&gt;This is clearly counter-productive and can put new developers off entirely. The state of npm packages in Javascript is another example where it sometimes is not clear which of the 900 competing frameworks one should use. We use the number of weekly downloads as a proxy for determining which projects are reliable or stable. Over time some clear winners do emerge, such as React, Angular, and Vue, and their popularity will compound their success to the point where they become the mature projects we mentioned at the start of this article.&lt;/p&gt;

&lt;p&gt;But how do we get there without the confusion?&lt;/p&gt;

&lt;p&gt;Unfortunately I don't have any clear solutions for this, mostly because it's difficult to predict which project will become successful in order to know which to promote ahead of time. This kind of thing will usually naturally emerge over time.&lt;/p&gt;

&lt;p&gt;My suggestion is for the core team of any programming language to at least provide a single page outlining the various options, and attempt to provide pros and cons for each (as unbiased as possible) and continually update the page to report the latest state of the ecosystem, including popularity within the community. The Rust community has such central pages, for example &lt;a href="https://www.arewewebyet.org/"&gt;https://www.arewewebyet.org/&lt;/a&gt; and these are extremely helpful. By reporting this feedback regularly in one central location, the stand-out projects will become known more quickly, and this will accelerate the community out of the confusing landscape and towards a more mature ecosystem containing a few large projects and many experiments from which they can draw inspiration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disagreements, insults, and factions
&lt;/h3&gt;

&lt;p&gt;The tendency to view fragmentation as unwelcome competition or even as a threat can unfortunately bring out the worst human behaviours in all of us. We compete for "customers" for our projects as if our very livelihoods depended on it (perhaps in some cases it does).&lt;/p&gt;

&lt;p&gt;But if we have learned anything from past experience, competition almost always leads to better outcomes for the consumer. Perhaps this sounds a little like free-market capitalism, and yes there are some parallels, though not intentionally. I think any system where individuals or groups compete in an evolutionary playing field will show similar traits. It is notable that the cases where such markets do not serve the consumer are precisely where there is a &lt;em&gt;lack&lt;/em&gt; of competition, not too much of it. This would suggest we should look more favourably on those projects willing to experiment and try something different.&lt;/p&gt;

&lt;h3&gt;
  
  
  Too much reinventing the wheel
&lt;/h3&gt;

&lt;p&gt;There probably is a point beyond which we should stop trying to reinvent the wheel or improve on past inventions, but the problem is that we don't know where on that scale we are. Perhaps if no new web framework delivers any benefits in 10 years that might suggest we should go back to incrementally improving existing ones, but I don't think we are there yet. The space of possible designs is potentially infinite, and we often cannot assess the effectiveness (or lack thereof) of a design until we try it out.&lt;/p&gt;

&lt;p&gt;There is a practical aspect as well. When it comes to the modern world, we all need to earn money and get paid. In this market, there is a significant cost to working on failed experiments and an increased benefit to being more cautious and sticking to tried-and-tested designs. The space of innovation is still open, but the innovations often need to deliver benefit in the short term. The upshot of this is that we should probably not be too concerned with people reinventing the wheel. The projects that should succeed, probably will. The rest will cease due to lack of funding, or interest, or both.&lt;/p&gt;

&lt;p&gt;So perhaps we should be hesitant to reinvent the wheel, but keep an open mind when it comes to reinventing the web framework, for example. We don't need to jump on board every new project, but we can wish their contributors all the best just the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embrace fragmentation, but not too much
&lt;/h2&gt;

&lt;p&gt;In general, fragmentation = experimentation. We should celebrate it, and encourage people to explore their ideas and see what they can build.&lt;/p&gt;

&lt;p&gt;At the same time, we can (and should) still put our efforts and resources into building a stable ecosystem via the more popular community projects. This is not a zero-sum game. We can borrow ideas (and sometimes code if licenses permit) from other projects and all benefit as a result. Communities will form naturally around projects that deliver good results.&lt;/p&gt;

&lt;p&gt;There is an optimal balance between the two which probably somewhat favours mature ecosystems and stable APIs while ensuring that experimentation can and does still freely occur.&lt;/p&gt;

&lt;p&gt;At the end of the day, having a few mature projects that can incorporate new features that were designed and perfected via little experiments and other offshoot projects, is the best of both worlds. It's not fragmentation vs pooling resources. It's a big world full of amazing developers. We can support both approaches. And as consumers of the resulting software, we all benefit.&lt;/p&gt;

</description>
      <category>fragmentation</category>
      <category>ecosystem</category>
      <category>software</category>
      <category>rust</category>
    </item>
  </channel>
</rss>
