<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Herbert Wolverson on Medium]]></title>
        <description><![CDATA[Stories by Herbert Wolverson on Medium]]></description>
        <link>https://medium.com/@herberticus?source=rss-1e6a85607f68------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*70pkyH1ufYt4q0fCv10L7A.jpeg</url>
            <title>Stories by Herbert Wolverson on Medium</title>
            <link>https://medium.com/@herberticus?source=rss-1e6a85607f68------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 16 May 2026 22:56:53 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@herberticus/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Fearless Concurrency with Rust: Part 3 — Asynchronous Concurrency]]></title>
            <link>https://medium.com/pragmatic-programmers/fearless-concurrency-with-rust-part-3-asynchronous-concurrency-e23bad856087?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/e23bad856087</guid>
            <category><![CDATA[web-server]]></category>
            <category><![CDATA[concurrency]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[asynchronous]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Mon, 19 Sep 2022 10:32:10 GMT</pubDate>
            <atom:updated>2022-09-19T10:32:10.325Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fONJMaPDTLXggF0xxl_A1Q.jpeg" /><figcaption>Image by <a href="https://www.shutterstock.com/g/ladik">andrey_l</a> on <a href="https://www.shutterstock.com/image-illustration/time-3d-illustration-1060908011">Shutterstock</a></figcaption></figure><h4>PART III</h4><h3>Fearless Concurrency with Rust</h3><h4>Asynchronous Concurrency</h4><figure><img alt="https://pragprog.com/newsletter/" src="https://cdn-images-1.medium.com/max/1024/1*KvVW4vtyKwkcPUgF1SVFIA.png" /><figcaption><a href="https://pragprog.com/newsletter/">https://pragprog.com/newsletter/</a></figcaption></figure><p>In parts <a href="https://medium.com/p/683cef1acb6b">1</a> and <a href="https://medium.com/pragmatic-programmers/fearless-concurrency-with-rust-part-2-6cb215718ded">2</a> of this series, we used multi-threading to hands <em>CPU-bound</em> loads. These are workloads that use all of the CPU-time you can give them, and can be sped up by dividing the calculations between cores in your system. Rust — and Rayon — provide great solutions for this type of workload.</p><p>In this part, we’re going to examine another form of concurrency: <em>asynchronous code</em>.</p><blockquote>Note that asynchronous code does <em>not</em> mean multi-threaded. It’s quite possible to run an asynchronous program on a single thread and still benefit from its performance boost. Node.js is a great example of this approach.</blockquote><h3>Why Use Asynchronous Code?</h3><p>Many workloads — especially in server programs — spend a lot of time waiting for other things. Your code may be waiting for a database to send it results, a file to open and process, or a network request to arrive. It’s certainly possible to spin off a thread for every request — and have that thread wait until a result arrives — but doing so can be very inefficient. Creating a thread requires server resources, and can be a relatively slow operation; the cost is measured in milliseconds, but on a heavily loaded server milliseconds can add-up quickly. You also can’t have more than 63,704 threads active at a time on Linux.</p><p>Asynchronous code uses a technique called <em>green threads</em>. Green threads (sometimes known as <em>fibers</em>) aren’t a full operating system thread: they represent a task and store a minimal amount of information about the task — and where it should send its result. Green threads may be (and often are) distributed between operating system threads — but they incur a significantly lower overhead than full threads.</p><h3>How do Asynchronous Tasks Work?</h3><p>An <em>asynchronous task</em> is a function marked with the async tag. When it executes, it runs until one of the following occurs:</p><ul><li>The task calls await on another asynchronous task.</li><li>The task completes, optionally yielding a result.</li></ul><p>Calling an async function doesn’t run it. It instead returns a Future. This represents a promise to coalesce into a result in the future — once you await the future’s result. When you call await, the future is added to your asynchronous green-thread scheduler, and the calling function sits idle until the future completes execution.</p><p>Consider the common scenario of a web user requesting frontpage.html from a server. If the requested page requires some content from a database, and some template application, the request goes through a number of steps:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/543/1*NTv0vf0-chqTGdYBqqZTUA.png" /></figure><p>Each await represents a time that the caller is idle: they are sitting doing nothing until another process completes. If frontpage.html is popular, managing this with a thread-per-task — with each thread spinning while it waits for a child task — quickly explodes into a huge number of threads. Worse, most of the threads would spend their life idling. Idle threads still have to be polled by the operating system scheduler — large numbers of idle threads can consume a surprising amount of CPU time!</p><p>Managing with asynchronous futures requires a significantly lower overhead as each task pauses (in a waiting state) until it receives results.</p><h3>Build a Simple Asynchronous Web Service</h3><p>Let’s use <a href="https://rocket.rs/">Rocket </a>to build a simple web service that demonstrates asynchronous execution. There are several popular web frameworks for Rust; Rocket is a simple one to get started.</p><p>Create a new Rust project with cargo:</p><pre>cargo init rocket-async-medium</pre><p>Add Rocket to your dependencies in Cargo.toml:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b83fd0c0d3b5398f75cff68b88b9ca03/href">https://medium.com/media/b83fd0c0d3b5398f75cff68b88b9ca03/href</a></iframe><p>We’re importing the json feature to help us mock (pretend to use) some database queries.</p><p>Now open src/main.rs and we’ll build a website. We’ll start with a main function, launching Rocket:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a434c95422a46631fed09838ec0503fb/href">https://medium.com/media/a434c95422a46631fed09838ec0503fb/href</a></iframe><p>Rocket provides a convenient #[launch] macro that creates a main() function and performs initialization for you — before calling your rocket function. That’s all you need to start a basic web server with Rocket.</p><h4>Loading an Index Template</h4><p>We still need to define the index function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eedb01b69b1d3cc237f5cc939b0dde76/href">https://medium.com/media/eedb01b69b1d3cc237f5cc939b0dde76/href</a></iframe><p>There’s a few things to learn here:</p><ul><li>We use #[get(&quot;/&quot;)] to map the function to the website’s root.</li><li>The function returns a RawHtml type — Rocket will accept a string, and ensure that the HTTP headers contain the correct content type.</li><li>The function loads a file named index.html (we’ll write that in a moment), builds sections of the website with build_menu(), build_news() and build_footer() functions. It then replaces placeholders in the index file with strings returned from these functions.</li><li>build_menu() and build_news() are asynchronous; build_footer is not. You can mix and match, so long as the calling function is itself asynchronous.</li></ul><p>That’s a good representation of a typical templating process for a server-rendered website. All that remains is to build the content.</p><p>Make a new file named src/index.html and insert the following HTML into it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3a823538adab586f115f4eb887ce5f74/href">https://medium.com/media/3a823538adab586f115f4eb887ce5f74/href</a></iframe><p>If you’re familiar with HTML, this is very straightforward:</p><ul><li>The file is simple HTML.</li><li>A style-sheet is defined inline, providing visual layout for the content.</li><li>Three placeholders are present: !!MENU!!, !!NEWS!! and !!FOOTER!!. In the index() function above you are replacing these markers with site content.</li></ul><h4>Loading the Menu</h4><p>Let’s build our menu. The menu will be a simple bar, loaded from a file. Create another file, named src/menu.html:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0b3ab6d728dbcedcfdd3db6601fd22ae/href">https://medium.com/media/0b3ab6d728dbcedcfdd3db6601fd22ae/href</a></iframe><p>It doesn’t get much simpler than that! In src/main.rs , create a function to load it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3d632960326dbd633b0c1cfefc392dbc/href">https://medium.com/media/3d632960326dbd633b0c1cfefc392dbc/href</a></iframe><p>Again, this is quite simple: it loads the menu from disk and returns it as a string. Notice that it’s asynchronous — we’re using Tokio’s filesystem functions. This approach ensures that the function will quietly wait if there is any delay accessing the file — maybe because the server is busy.</p><h4>Loading a News Feed</h4><p>Now, let’s add some site content.</p><p>We’re going to pretend that we’re loading a news feed from a database. Instead of asking you to install a complete database system, we’ll store the current news feed in a JSON file. Create a file named src/news.json and paste some news into it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e3a4538e9e4fa8e53b23e5ea23547657/href">https://medium.com/media/e3a4538e9e4fa8e53b23e5ea23547657/href</a></iframe><p>This is a simple JSON file: it contains an array of objects, each of which contains a title and a summary.</p><p>Now go back to src/main.rs and add a function to asynchronously read this data:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2b4b2d2bd18de4349ac1ebe6be8f7294/href">https://medium.com/media/2b4b2d2bd18de4349ac1ebe6be8f7294/href</a></iframe><p>We start by defining a structure that matches our news-feed format. Decorating it with #[Deserialize] allows Rocket (which embeds Serde) to decode JSON into NewsItem structures.</p><p>The build_news() function loads the news-feed file, and calls Serde to decode it. It then iterates the news array, using map and format! to transform it into HTML. The HTML for all items is then concatenated together with fold.</p><p>Finally — the footer. We’re going to always return the same string, and since we aren’t waiting on anything else we’ll make it a regular function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/043f645962ddafd688bebf875243699c/href">https://medium.com/media/043f645962ddafd688bebf875243699c/href</a></iframe><p>Congratulations — you now have all of the elements required to run your webserver. Type cargo run and navigate to <a href="http://localhost:8000/.">http://localhost:8000/.</a> You should see your news site:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/694/1*UjFsCIbOLZKO5Y1aDtkvkg.png" /></figure><p>To recap, requesting this website:</p><ol><li>Your web browser sends a request to 127.0.0.1 on port 8000.</li><li>Rocket receives the TCP connection and parses it.</li><li>Since “/” matches the route for <em>index</em>, Rocket calls your index function and <em>awaits a response.</em></li><li>index calls fs::read_to_string to load the index.html template file and awaits a response.</li><li>index receives a response and calls build_menu (awaiting a response).</li><li>index receives the menu template and calls build_news (awaiting a response).</li><li>index combines the results, modifies the template and returns the HTML response.</li><li>Rocket re-awakens with the response and sends it to your web browser.</li></ol><p>This is a lot of steps — but it’s very efficient. Each task pauses when it isn’t needed, consuming very few resources. You could easily serve hundreds of thousands of customers with your exciting news!</p><h3>Improving Concurrency with Join</h3><p>You may have noticed that some parts of index could run in parallel. The menu and the news don’t depend upon each other. Why not wait for both at once — Tokio can divide tasks between threads (transparently), so you may get a performance increase.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0891e9178a5618d44d41c0058b939f93/href">https://medium.com/media/0891e9178a5618d44d41c0058b939f93/href</a></iframe><p>The join! macro executes all three futures (loading the template, building the menu and news feed) concurrently — and doesn’t wake up until all three have returned data.</p><h3>When Tasks Block</h3><p>All of the functions we’ve called have been async — they cleanly wait for another task to complete. Occasionally, you need to wait for a non asynchronous task — maybe a CPU bound task, or a device that doesn’t provide an asynchronous interface.</p><p>Directly calling <em>blocking</em> tasks inside your asymmetric function is a bad idea: the whole “future” pauses while it waits for a result. This can be very bad for performance; if you are running a single-threaded environment it can stall execution completely.</p><p>When you can’t avoid a blocking task, you can use Tokio’s spawn_blocking function as follows:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0ec17ddd6f215847d874f276d264d8c3/href">https://medium.com/media/0ec17ddd6f215847d874f276d264d8c3/href</a></iframe><p>Using spawn_blockingwill spin your task off into its own thread — and pause your future until the thread returns. This approach keeps the other tasks running smoothly while your function executes.</p><h3>Wrap Up</h3><p>We’ve reached the end of the “Fearless Concurrency with Rust” series. In these three articles, we’ve covered:</p><ul><li>Using Rust’s threading primitives.</li><li>Using Rust’s safety guarantees to avoid a bug that crept into similar C++ code.</li><li>Using Rayon to make CPU-bound multi-threading easy.</li><li>Using asynchronous execution in servers and other processes that spend most of their time waiting for other systems.</li></ul><p>Rust lives up to its promise of fearless concurrency and offers a variety of methods to fit your needs. Please share in the comments how you are using concurrency in Rust.</p><p><a href="https://medium.com/pragmatic-programmers/herbert-wolverson-fb4684adea44">Herbert Wolverson</a></p><p>Are you a Rust fan? You can save 35 percent on the ebook versions of Herbert’s books with promo code <strong>rust_2022 </strong>now through October 15, 2022. Promo codes are not valid on prior purchases.</p><ul><li><a href="https://pragprog.com/titles/hwrustbrain/rust-brain-teasers/">Rust Brain Teasers</a></li><li><a href="https://pragprog.com/titles/hwrust/hands-on-rust/">Hands-on Rust</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e23bad856087" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pragmatic-programmers/fearless-concurrency-with-rust-part-3-asynchronous-concurrency-e23bad856087">Fearless Concurrency with Rust: Part 3 — Asynchronous Concurrency</a> was originally published in <a href="https://medium.com/pragmatic-programmers">The Pragmatic Programmers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fearless Concurrency with Rust, Part 2]]></title>
            <link>https://medium.com/pragmatic-programmers/fearless-concurrency-with-rust-part-2-6cb215718ded?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/6cb215718ded</guid>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[threading]]></category>
            <category><![CDATA[rust-programming-language]]></category>
            <category><![CDATA[threads]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Thu, 07 Jul 2022 10:32:28 GMT</pubDate>
            <atom:updated>2022-07-07T10:32:28.105Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="spools of thread on rusty crate with Rayon label on crate" src="https://cdn-images-1.medium.com/max/1024/1*SiqoA2FoMCu0KDOtEapAIg.png" /><figcaption>Created using images from <a href="https://www.publicdomainpictures.net/">publicdomainimages.net</a> under <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0 Public Domain license</a></figcaption></figure><h4>Part II</h4><h3>Fearless Concurrency with Rust</h3><h4>Threading</h4><figure><img alt="https://pragprog.com/newsletter/" src="https://cdn-images-1.medium.com/max/1024/1*KvVW4vtyKwkcPUgF1SVFIA.png" /><figcaption><a href="https://pragprog.com/newsletter/">https://pragprog.com/newsletter/</a></figcaption></figure><p>In <a href="https://medium.com/p/683cef1acb6b">part 1 of this series</a>, we discussed how Rust uses lifetimes and the borrow-checker to save you from data races. We even compared a C++ program with a threading bug with an equivalent Rust program — and saw how Rust won’t let the buggy version compile.</p><p>In the second part of this series, we’re going to look at ways in which Rust can help with a common design pattern: breaking up a large block of calculations, diving them between CPUs, and combining the results. We’ll continue to use a deliberately inefficient function to find prime numbers in a set of inputs. This isn’t overly useful work, but it’s a good representation of common data-processing tasks. The function we’re using is the same as last time:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7e72f4da76c92b0031eb33a4cb24f453/href">https://medium.com/media/7e72f4da76c92b0031eb33a4cb24f453/href</a></iframe><p>For each of the strategies we consider, we’ll require our program to:</p><ul><li>Create a vector containing the numbers 2 through 2,000,000.</li><li>Filter the vector to contain only prime numbers, confirmed with the is_prime function.</li><li>Print the number of prime numbers it found and the time taken to perform the calculation.</li></ul><p>I’m running all of these on my work PC. It has a 12th generation Intel Core i7 with 12 physical cores (and 20 logical CPUs), 32 Gb RAM and fast M2 storage.</p><h3>Single-Threaded Workload</h3><p>As a baseline, we’ll start with a single-threaded version. We’re using Rust’s iterators to keep it as short and to the point as possible:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7d71de98f9e893077ded96819c0948c3/href">https://medium.com/media/7d71de98f9e893077ded96819c0948c3/href</a></iframe><p>Using a single core, the calculation takes 712 seconds in debug mode (cargo run) — and 89 seconds in release mode ( cargo run — release).</p><p>That serves as a good baseline, but we can definitely do better than that!</p><h3>Dividing and Threading with Native Rust</h3><p>Using only native Rust (no external dependencies), we can make use of some Rust features to help us divide the workload. Let’s hard-code the assumption that I have 12 CPUs (otherwise we’d have to use the num_cpus crate — or equivalent — to discover that in a portable way):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8e59deb43fd62015a35680f85dace720/href">https://medium.com/media/8e59deb43fd62015a35680f85dace720/href</a></iframe><p>This code starts by creating a vector of the numbers 2 through 2,000,000. It then uses chunks — a built-in function of Vec — to divide the candidates into 12 chunks. We can use into_iter() on the resulting chunks to iterate over each chunk.</p><p>chunk.to_owned() isn’t obvious; we “take ownership” of each chunk as we process it. This approach converts it from being a slice of references to candidates to a vector of actual numbers. In release mode, this is essentially free — the compiler optimizes away several memory copies. It’s still not as clear as I’d like.</p><p>Now that we have our own personal chunk — we spawn a thread that will return a Result&lt;Vec&lt;u32&gt;&gt; containing prime numbers from that chunk. We return the JoinHandle from each thread. A JoinHandle is a pointer to the thread that will contain the result when it finishes. You can call join on a thread to wait for it to finish.</p><p>At the end, we drain our vector of thread handles and combine the results. (Drain removes each item from the vector as it is processed. Since we won’t be reusing the vector, it’s a good way to avoid ownership issues).</p><p>This strategy offers a significant speed-up. It finishes in 123 seconds in debug mode and only 15 seconds in release mode.</p><h3>Using Rayon</h3><p>Rayon is a popular Rust crate that implements a lot of threading features. It offers a worker-thread pool, work stealing (an idle thread will take work from the pending queue), parallel iterators, and many other features to make multi-threading easy. The downside is that you are adding a dependency to your program.</p><p>You can enable Rayon by adding it to your program’s Cargo.toml file:</p><pre>[dependencies]<br>rayon = &quot;1.5&quot;</pre><p>The big advantage of using Rayon is that it greatly simplifies your code. You can make some tiny changes to the original single-threaded version and benefit from an immediate speed-up. Here’s the Rayon version:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4343d80d1bc0b047a6c1c2a23436fcf0/href">https://medium.com/media/4343d80d1bc0b047a6c1c2a23436fcf0/href</a></iframe><p>Notice that we’re importing two features from Rayon: IntoParallelIterator and ParallelIterator. These are required to transform a range 2..2_000_000 into a parallel iterator and to perform the iteration in parallel. We don’t divide our candidates into chunks or worry about thread joining — Rayon takes care of all of that.</p><p>Rayon also retains all of the safety guarantees you expect from Rust.</p><p>Best of all? It’s even faster. It completed in 72 seconds in debug mode, and 8 seconds in release mode.</p><h3>The Results</h3><p>Let’s compare the results of the three strategies we tested:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4d2de92c4c7a55232200e3a7ab655d56/href">https://medium.com/media/4d2de92c4c7a55232200e3a7ab655d56/href</a></iframe><p>In terms of complexity, the single-threaded version is shortest — followed by Rayon. The chunked version is more than twice the size of the single-threaded version.</p><p>Surprisingly, despite the added complexity — the chunk strategy is not the fastest. That prize goes to Rayon:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/586/1*hQf1d1YcVgoTYgUJfZD9wg.png" /></figure><p>Rayon is only a little faster, but combined with the simplicity of using the library, we can safely say that for iterator-based combinatorial data processing Rayon is the clear winner.</p><h3>Wrap-Up</h3><p>Dividing workloads into threads with native Rust is a little complicated, but works very well. It offers a good performance boost over a single-threaded model. At 47 lines of code (including comments), it’s a lot more complicated than the single-threaded model — but you can be certain that it is fast and safe.</p><p>If adding a dependency to Rayon is acceptable to you, you can easily combine the simplicity of the single-threaded model with the sheer horsepower of a full-featured concurrency model. It’s even faster than the native Rust version and retains all of the safety features you expect.</p><p>In the final part of this series, we’ll look at the <em>other</em> concurrency system built into Rust: asynchronous execution.</p><p><a href="https://medium.com/pragmatic-programmers/herbert-wolverson-fb4684adea44">Herbert Wolverson</a></p><p>Are you a Rust fan? You can save 35 percent on the ebook versions of Herbert’s books with promo code <strong>rust_2022 </strong>now through July 31, 2022. Promo codes are not valid on prior purchases.</p><ul><li><a href="https://pragprog.com/titles/hwrustbrain/rust-brain-teasers/">Rust Brain Teasers</a></li><li><a href="https://pragprog.com/titles/hwrust/hands-on-rust/">Hands-on Rust</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6cb215718ded" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pragmatic-programmers/fearless-concurrency-with-rust-part-2-6cb215718ded">Fearless Concurrency with Rust, Part 2</a> was originally published in <a href="https://medium.com/pragmatic-programmers">The Pragmatic Programmers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fearless Concurrency with Rust]]></title>
            <link>https://medium.com/pragmatic-programmers/fearless-concurrency-with-rust-683cef1acb6b?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/683cef1acb6b</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[concurrency]]></category>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[threads]]></category>
            <category><![CDATA[rust]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Tue, 07 Jun 2022 10:31:11 GMT</pubDate>
            <atom:updated>2022-06-07T10:31:11.929Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3sZDDtg3KoFpeSWaIPjg2g.jpeg" /><figcaption>Image by <a href="https://www.shutterstock.com/g/gunnar3000">Gunnar Pippel</a> on <a href="https://www.shutterstock.com/create/editor/CiQwNzE4NmM5OC04ODMyLTQyODAtOTQ1YS0yZmYxN2Q3MjFlZjA">Shutterstock</a></figcaption></figure><h4>PART I</h4><h4>Safety</h4><figure><img alt="https://pragprog.com/newsletter/" src="https://cdn-images-1.medium.com/max/1024/1*KvVW4vtyKwkcPUgF1SVFIA.png" /><figcaption><a href="https://pragprog.com/newsletter/">https://pragprog.com/newsletter/</a></figcaption></figure><p>One of Rust’s selling points is <a href="https://doc.rust-lang.org/book/ch16-00-concurrency.html">Fearless Concurrency</a>. Concurrent programming is often fraught with peril:</p><ul><li><em>Data races</em> can occur when multiple threads write to the same data without the protection of either an atomic type or a locking mechanism.</li><li><em>Lifetime</em> issues can occur when a thread outlives a variable declaration. The variable may be destroyed by the parent, while the child thread still relies on it.</li></ul><p>Let’s compare some Rust and C++ code, to see how Rust protects you from these issues.</p><h3>Finding Prime Numbers</h3><p>There are <em>many</em> ways to factorize a number and detect if it is prime. Some algorithms are very fast — but for this article we’re going to use a deliberately slow approach. A simple algorithm uses more CPU time, better demonstrating the benefits of multi-threading. We’ll use the following function to determine if a number is prime:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3b8d5baf3e9f3d830203ea207e6e999e/href">https://medium.com/media/3b8d5baf3e9f3d830203ea207e6e999e/href</a></iframe><p>is_prime iterates from 2 to half the number and ensures that <em>all</em> of the iterations return a remainder (the % operator) other than zero when the tested number is divided by the iterator.</p><p>To be sure that it works, here’s a quick unit test that checks a <a href="https://en.wikipedia.org/wiki/Prime_number">list of prime numbers under 100</a>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b5e4752307c4ce35c118127f659d39e1/href">https://medium.com/media/b5e4752307c4ce35c118127f659d39e1/href</a></iframe><p>Here’s an equivalent C++ function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c5fb1bc247d3b26f776fa6e82c0c7d81/href">https://medium.com/media/c5fb1bc247d3b26f776fa6e82c0c7d81/href</a></iframe><p>I kept it simple; range support isn’t in very many shipping C++ compilers yet — using an iota view from the C++20 standard would enable a similar iterator-based approach. The code is functionally equivalent, however.</p><h3>Single Threaded Prime Detection</h3><p>The following Rust program counts how many prime numbers it can find between 2 and 200,000:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d0e18eeedef85d7d201719b9ab854bd4/href">https://medium.com/media/d0e18eeedef85d7d201719b9ab854bd4/href</a></iframe><p>This program finds 17,984 prime numbers in the range 2 to 200,000.</p><p>An equivalent C++ program looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/77f62b743b7e1f8d3fa0fa1f8925dc72/href">https://medium.com/media/77f62b743b7e1f8d3fa0fa1f8925dc72/href</a></iframe><p>This program also finds 17,984 prime numbers. So far, so good. Let’s make a data race!</p><h3>Racing Data</h3><p>Looking to speed-up our prime counting, we eagerly fire up some C++ std::thread objects to divide our workload between two threads:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/95c14a660a4885f96232d5ff34e9495d/href">https://medium.com/media/95c14a660a4885f96232d5ff34e9495d/href</a></iframe><p>This program compiles and runs. Visual Studio (my compiler) doesn’t show any warnings. The code has split the workload in two, spawning two threads — each covering half of the prime counting.</p><p>Unfortunately, it doesn’t work. The first time I ran it, it counted <em>17,983</em> prime numbers. The second time, it counted only <em>17,981</em>! Threads are concurrently accessing count. Incrementing a variable is a three-stage process: you read the current value, add one to it, and store the result. There’s no guarantee that all of these steps have been completed independently of other threads — resulting in a data race.</p><p>Maybe a Rust version of the same code will work?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2ce85b4e277bafead3c9ae74e71b9a7d/href">https://medium.com/media/2ce85b4e277bafead3c9ae74e71b9a7d/href</a></iframe><p>The Rust version of the same program won’t compile. It gives two errors:</p><ul><li>counter may not be mutably borrowed more than once.</li><li>counter may outlive it’s borrowed value. A lifetime issue.</li></ul><p>Rust has detected that your program is unsafe and prevents you from creating code that inadvertently gives the wrong answer.</p><h3>Safe Multi-Threading</h3><p>Here’s a safe version in Rust that both compiles and gives the correct answer:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dececbb082c4ab9ed1f93c9fc4d7c2e3/href">https://medium.com/media/dececbb082c4ab9ed1f93c9fc4d7c2e3/href</a></iframe><p>There are three new concepts in this program:</p><ul><li>AtomicUSize is a special “atomic” type. <em>Atomic</em> types provide automatic protection against data-races. They are typically very fast, mapping directly to equivalent CPU instructions. Whenever you access an atomic type, you have to indicate the synchronization guarantee you need — in this case SeqCst provides the highest level of protection.</li><li>Arc is an “atomic reference counter”. When you wrap a type in an Arc, you can safely clone it and move the clones between threads. Each clone is a <em>pointer</em> to the contained data. Arc guarantees that the underlying data won’t be deleted until every reference is done using it.</li><li>The thread closures (inline functions) move their captured data. They are operating on clones of the counter Arc — so they all point to the same place.</li></ul><p>Combining these concepts has protected us against both data-race and lifetime issues:</p><ul><li>Rust’s borrow checker is happy because data is not borrowed between threads: the Arc is cloned, safely sharing a pointer to the counter data.</li><li>Rust’s data-race protection is satisfied that using an AtomicUsize cannot result in a data-race.</li></ul><p>The result is a fast program that gives the correct answer every time.</p><h3>Wrap-Up</h3><p>Rust’s fearless concurrency guarantees saved us from a data-race! C++ didn’t warn about the error, it just gave incorrect results. Rust saved the day, by refusing to compile the incorrect code. In a large program, this could have saved hours of painstaking debugging.</p><p>Rust’s Arc and AtomicUSize types make for complicated-looking code. In the next part of this series, I’ll show you ways to tame the complexity and create fast, multi-threaded code that remains easy to read.</p><p><a href="https://medium.com/pragmatic-programmers/herbert-wolverson-fb4684adea44">Herbert Wolverson</a></p><p>Are you a Rust fan? You can save 35 percent on the ebook versions of Herbert’s books with promo code <strong>rust_2022 </strong>now through May 30, 2022. Promo codes are not valid on prior purchases.</p><ul><li><a href="https://pragprog.com/titles/hwrustbrain/rust-brain-teasers/">Rust Brain Teasers</a></li><li><a href="https://pragprog.com/titles/hwrust/hands-on-rust/">Hands-on Rust</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=683cef1acb6b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pragmatic-programmers/fearless-concurrency-with-rust-683cef1acb6b">Fearless Concurrency with Rust</a> was originally published in <a href="https://medium.com/pragmatic-programmers">The Pragmatic Programmers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s New in Rust Game Development?]]></title>
            <link>https://medium.com/pragmatic-programmers/whats-new-in-rust-game-development-28f1d4a46ddd?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/28f1d4a46ddd</guid>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[rustlang]]></category>
            <category><![CDATA[language]]></category>
            <category><![CDATA[godot]]></category>
            <category><![CDATA[game-development]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Wed, 27 Apr 2022 10:32:05 GMT</pubDate>
            <atom:updated>2022-04-27T10:32:05.436Z</atom:updated>
            <content:encoded><![CDATA[<h4>Game Engines, Godot, and More</h4><figure><img alt="https://pragprog.com/newsletter/" src="https://cdn-images-1.medium.com/max/1024/1*KvVW4vtyKwkcPUgF1SVFIA.png" /><figcaption><a href="https://pragprog.com/newsletter/">https://pragprog.com/newsletter/</a></figcaption></figure><p>Last year, I outlined a few options for <a href="https://medium.com/p/31147f7b6096">Game Development in Rust</a>. Rust is a fast-moving ecosystem; new and exciting options become available all the time. In this article, we’ll take a look at some of what’s new in Rust game development since the last article.</p><h3><strong>Why Use Rust for Game Development?</strong></h3><p>Rust is making inroads into the game development world, and some of its strengths are becoming clear. Rust addresses a number of <em>pain points</em> from other languages:</p><ul><li>Rust is a <em>systems language</em> — it runs close to the metal, compiling to fast, native code.</li><li>Rust has no garbage collector — so your game won’t pause unexpectedly while the system cleans up your memory.</li><li>Rust makes memory management easy — many common bugs (use after free, dangling pointers, many overflows) are caught by the compiler.</li><li>Rust offers a consistent build interface and a consistent package user interface.</li><li>Rust interoperates seamlessly with other languages via <a href="https://en.wikipedia.org/wiki/Foreign_function_interface">FFI</a>.</li><li>Rust offers <em>fearless concurrency</em> — data races trigger a compiler error, and thread control is built into the language. It’s easy to take advantage of every core in your CPU. With Bevy and similar engines, your program automatically threads your game logic.</li></ul><p>Rust offers a solid foundation for game development — seen in the rapid evolution of new game engines that make use of these advantages.</p><h3><strong>Rust Game Engines</strong></h3><p>There’s some exciting news in the Rust game engine world. Let’s start with Fyrox, a powerful 3D engine.</p><h4><strong>Fyrox</strong></h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FN8kmZ9aBtZs%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DN8kmZ9aBtZs&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FN8kmZ9aBtZs%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/f661c71963953b7db4dc3a7678277a5a/href">https://medium.com/media/f661c71963953b7db4dc3a7678277a5a/href</a></iframe><p>Formerly known as RG3D, <em>Fyrox </em>is a rapidly developing 3D engine. It includes most of the features you expect from a modern 3D engine: an editor, scripting, lightmaps, scene-graphs, serialization, audio and more. It started as the engine for the author’s first-person shooter game — but now includes examples for making roleplaying games and more.</p><p>Another popular engine in Rust is <em>Macroquad</em>, focused on simple 2D game development.</p><h4><a href="https://github.com/not-fl3/macroquad"><strong>Macroquad</strong></a></h4><p>Macroquad’s big selling point is that it is simple, efficient and minimal. Macroquad isn’t opinionated: you can store your game data however you like. The engine includes everything you need to make 2D games. It includes optional platformer physics and blazing fast sprite rendering.</p><p><a href="https://github.com/fishfight/FishFight">Fish Fight</a> is an open source platformer game, written with Rust and Macroquad.</p><figure><img alt="Fish Fight, a game made with macroquad" src="https://cdn-images-1.medium.com/max/600/1*PSaozB3Ce0UhVDPokK1Ufg.gif" /><figcaption>Fish Fight, an open source platformer written with Macroquad.</figcaption></figure><h4><a href="https://github.com/EmbarkStudios/kajiya"><strong>Kajiya</strong></a></h4><p>Kajiya isn’t a complete game engine yet, but it’s pushing the bounds of what you can render in Rust. Using RTX, Kajiya offers global illumination and beautiful rendering. If you’re interested in the nuts and bolts of cutting-edge game development, Kajiya is a great place to look.</p><figure><img alt="Kajiya Ruins" src="https://cdn-images-1.medium.com/max/1024/0*J05gA8VKMofydEX5.png" /><figcaption>Kajiya’s global illumination system renders beautiful scenes.</figcaption></figure><h4><a href="https://bevyengine.org/"><strong>Bevy 0.6</strong></a></h4><p>The Bevy engine has released a new version! Bevy is a data-driven game framework. Everything is stored in a fast, easy-to-use entity component system. It features great 2D rendering, increasingly powerful 3D rendering, audio and a powerful plugin system for extending the base engine.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*eLKG9lp5WrmNzty1" /><figcaption>A simple helicopter game I created with Bevy. It’s only 350 lines of code.</figcaption></figure><p>Bevy 0.6 includes a lot of changes. In particular, you no longer need to add .system to the end of every system when you are building your scheduler. The 3D engine now supports better, faster lighting with full shadows. Many bugs have been fixed. Bevy is moving towards a more regular release schedule. <a href="https://bevyengine.org/news/bevy-0-6/">The full list of improvements is huge</a>.</p><h3><strong>Rust in Godot</strong></h3><p>Rust’s interoperability with other languages (via FFI) is proving to be a killer feature. In the business world, Rust is seamlessly sliding into existing workflows — replacing the dangerous parts with safe, high-performance code. In the game world, Rust’s FFI support makes it easy to work with existing game engines.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/680/0*xsphDt6niynQ-0bs" /><figcaption>Some Godot games that use Rust.</figcaption></figure><p>The <a href="https://godot-rust.github.io/">Godot-Rust</a> plugin makes Rust a first-class citizen of the Godot infrastructure. Easily write heavy-duty scripting in Rust and attach it to your project in the Godot editor. Ideal for projects that require heavy computation behind the scenes, while still using Godot’s excellent framework.</p><h3><strong>More About Rust Game Development in 2022</strong></h3><p>I recently gave a talk about Rust Game Development to the <a href="https://www.meetup.com/rust-wurzburg-meetup-group/">Rust Wurzburg Meetup</a>, which you can watch here:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FUPO8hPp9MLo%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DUPO8hPp9MLo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FUPO8hPp9MLo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/5669eef02fd2d497fb712eb8c116a73e/href">https://medium.com/media/5669eef02fd2d497fb712eb8c116a73e/href</a></iframe><p>Are you a Rust fan? You can save 35 percent on the ebook versions of Herbert’s books with promo code <strong>rust_2022 </strong>now through May 30, 2022. Promo codes are not valid on prior purchases.</p><ul><li><a href="https://pragprog.com/titles/hwrustbrain/rust-brain-teasers/">Rust Brain Teasers</a></li><li><a href="https://pragprog.com/titles/hwrust/hands-on-rust/">Hands-on Rust</a></li></ul><h4>Articles by Herbert Wolverson:</h4><ul><li><a href="https://medium.com/pragmatic-programmers/how-long-is-a-string-c25a086afe31">How Long Is a String?</a></li><li><a href="https://medium.com/pragmatic-programmers/rustle-5c15d1c153a1">Rustle</a></li><li><a href="https://medium.com/pragmatic-programmers/five-reasons-i-love-rust-ce9c756f4de7">Five Reasons I Love Rust</a></li><li><a href="https://medium.com/pragmatic-programmers/run-your-rust-games-in-a-browser-ceea86b04616">Run Your Rust Games in a Browser</a></li><li><a href="https://medium.com/pragmatic-programmers/game-development-with-rust-31147f7b6096">Game Development with Rust</a></li><li><a href="https://medium.com/pragmatic-programmers/rust-structure-packing-6d8978e3c99e">Rust Structure Packing</a></li><li><a href="https://medium.com/pragmatic-programmers/flappy-dragon-rust-647e91a34dd4">Hands-on Rust Bonus Content</a></li><li><a href="https://medium.com/pragmatic-programmers/trying-out-the-rust-bevy-engine-e97c5c950504">Trying Out the Rust Bevy Engine</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=28f1d4a46ddd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pragmatic-programmers/whats-new-in-rust-game-development-28f1d4a46ddd">What’s New in Rust Game Development?</a> was originally published in <a href="https://medium.com/pragmatic-programmers">The Pragmatic Programmers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How Long Is a String?]]></title>
            <link>https://medium.com/pragmatic-programmers/how-long-is-a-string-c25a086afe31?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/c25a086afe31</guid>
            <category><![CDATA[rust-programming-language]]></category>
            <category><![CDATA[language]]></category>
            <category><![CDATA[string]]></category>
            <category><![CDATA[brain-teaser]]></category>
            <category><![CDATA[hwrust]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Wed, 23 Mar 2022 10:31:04 GMT</pubDate>
            <atom:updated>2022-03-23T10:31:04.907Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oj4oCgmQ0mCOAQSjBYGS1Q.jpeg" /><figcaption>Image by <a href="https://www.shutterstock.com/g/giedra+fine">giedre vaitekune</a> on <a href="https://www.shutterstock.com/image-photo/colorful-cotton-thread-balls-isolated-on-785789947">Shutterstock</a></figcaption></figure><h4>A Rust Brain Teaser</h4><figure><img alt="https://pragprog.com/newsletter/" src="https://cdn-images-1.medium.com/max/1024/1*KvVW4vtyKwkcPUgF1SVFIA.png" /><figcaption><a href="https://pragprog.com/newsletter/">https://pragprog.com/newsletter/</a></figcaption></figure><blockquote>Guess the output of the following program:</blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/90525efccd4a3e4380ac6fdaadb26bf4/href">https://medium.com/media/90525efccd4a3e4380ac6fdaadb26bf4/href</a></iframe><blockquote>Try to guess what the output is before moving to the next section.</blockquote><p>The program will display the following output:</p><pre>Halló heimur is 13 characters long.</pre><h3><strong>Discussion</strong></h3><p>Your eyes aren’t deceiving you — “Halló heimur” contains 12 characters (including the space). Let’s step back and take a look at how Rust’s String type works. The internal struct definition of a String is quite straightforward:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d980fed81c0bb30394b90ffa473a1c13/href">https://medium.com/media/d980fed81c0bb30394b90ffa473a1c13/href</a></iframe><p>Strings are just a vector of bytes ( u8), representing Unicode characters in an encoding named UTF-8. Rust automatically translates your string to UTF-8. The encoding looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/906/1*EmKWrPu879n3iE3_mAIWGQ.png" /></figure><p>Your original string, “Halló heimur” consists of 11 ASCII characters (including the space) and one “Latin-1 Supplement” character: the ó. ASCII characters require 1 byte to encode, Latin supplements require two bytes.</p><p>Rust’s string encoding is smart enough to not store extra zeroes for each Unicode character. If it did, String would be a vector of <em>char </em>types. Rust’s char is exactly 4 bytes long — the <em>maximum </em>size of a <a href="https://doc.rust-lang.org/std/primitive.char.html#representation">single Unicode character</a>. Char variables don’t represent a single ASCII character; instead, they represent a <em>Unicode scalar value</em>. The scalar value can represent a single glyph or modification to another glyph.</p><h4><strong>String Length</strong></h4><p>String.len() counts the number of bytes in the string’s backing vector. If a String was storing every character as a char, you’d expect Halló heimur to occupy 48 bytes of memory. Rust’s String isn’t storing characters; it’s storing a byte array representing just the bytes needed to output the stored text.</p><p>Not all UTF-8 characters require all 4 bytes to render. For example, a space requires only 1 byte (0x20) , while most Latin Extension characters use 2 bytes. The first byte ( 0xC3) indicates that the character uses the Latin Extension character region, and the second byte ( 0xB3 for ó) identifies the character.</p><p>The string Halló heimur contains 11 ASCII characters — each using 1 byte of memory — occupies 11 bytes. Add two bytes for the “ó” and your string occupies 13 bytes of memory.</p><h4><strong>Counting Characters</strong></h4><p>You can correctly count the characters in Halló heimur with the following code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b3a3635395057a0df3caf0395bd46435/href">https://medium.com/media/b3a3635395057a0df3caf0395bd46435/href</a></iframe><p>When you call my_str.chars() , you’re requesting an iterator that returns each element of the string represented as a char. Rust correctly deduces that there are a total of 12 glyphs — or Unicode scalar values — making up the string. The iterator passes each of them to your consumer as a 4-byte char. Even if a glyph only requires 1 or 2 bytes of memory, Rust will allocate all 4 bytes for the char type. Traversing the iterator uses very little extra memory. If you call collect() on the iterator — to create a vector of char data — the vector will consume 40 bytes of memory.</p><p>Use my_str.chars() to access individual characters in a String. It’s an iterator, so you can use nth, for_each and other iterator functions to find what you’re looking for. For example, you can access the 4th character in a string with my_str.chars().nth(4).</p><h4><strong>Impact of UTF-8 Sizing</strong></h4><p>Unicode string sizing can be confusing at times, which can lead to surprising results in your code. You need to be aware of the distinction between characters and bytes:</p><ul><li>When you’re validating string length, know what counts and what doesn’t. For example, if you only accept usernames that are 10 characters or less, you need to decide if you mean glyphs or bytes.</li><li>When storing strings in databases, you need to remember to allocate enough space for non-English character set strings.</li><li>When transmitting or receiving information to/from a remote API, you need to agree on a length standard for encoding strings in transit.</li><li>If you’re writing a program for a memory constrained system, parsing Unicode string character by character can consume a <em>lot </em>more memory than you expected. The string love: ❤ is 7 characters long, requires 12 bytes of storage in a String — and 32 bytes of memory when processed as individual characters. This may seem like a small amount of memory, but if your reader enters the entirety of <em>War and Peace</em> into your program’s input box, per-character parsing may require more resources than you expected.</li><li>When accessing individual characters in a string, it’s much safer to use chars as opposed to directly accessing the byte array. Characters are aware of Unicode boundaries — bytes are not. Printing the first 6 bytes of “Können” will only print “Könne”. Printing the first 6 characters will output the entire word.</li></ul><h4><strong>Further Reading</strong></h4><ul><li><a href="https://doc.rust-lang.org/std/primitive.char.html">Characters</a></li><li><a href="https://doc.rust-lang.org/std/string/struct.String.html#method.len">String Length</a></li><li><a href="https://www.compart.com/en/unicode/">Unicode Symbol Reference</a></li><li><a href="https://en.wikipedia.org/wiki/UTF-8">Wikipedia UTF-8</a></li><li><a href="https://doc.rust-lang.org/src/alloc/string.rs.html">String Source Code</a></li></ul><p>You’ll find this puzzle and more in <em>Rust Brain Teasers</em> from The Pragmatic Bookshelf. You can save 35 percent on the ebook versions of Herbert’s books with promo code <strong>rust_2022 </strong>now through April 30, 2022. Promo codes are not valid on prior purchases.</p><ul><li><a href="https://pragprog.com/titles/hwrustbrain/rust-brain-teasers/">Rust Brain Teasers</a></li><li><a href="https://pragprog.com/titles/hwrust/hands-on-rust/">Hands-on Rust</a></li></ul><h4>Articles by Herbert Wolverson:</h4><ul><li><a href="https://medium.com/pragmatic-programmers/rustle-5c15d1c153a1">Rustle</a></li><li><a href="https://medium.com/pragmatic-programmers/five-reasons-i-love-rust-ce9c756f4de7">Five Reasons I Love Rust</a></li><li><a href="https://medium.com/pragmatic-programmers/run-your-rust-games-in-a-browser-ceea86b04616">Run Your Rust Games in a Browser</a></li><li><a href="https://medium.com/pragmatic-programmers/game-development-with-rust-31147f7b6096">Game Development with Rust</a></li><li><a href="https://medium.com/pragmatic-programmers/rust-structure-packing-6d8978e3c99e">Rust Structure Packing</a></li><li><a href="https://medium.com/pragmatic-programmers/flappy-dragon-rust-647e91a34dd4">Hands-on Rust Bonus Content</a></li><li><a href="https://medium.com/pragmatic-programmers/trying-out-the-rust-bevy-engine-e97c5c950504">Trying Out the Rust Bevy Engine</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c25a086afe31" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pragmatic-programmers/how-long-is-a-string-c25a086afe31">How Long Is a String?</a> was originally published in <a href="https://medium.com/pragmatic-programmers">The Pragmatic Programmers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rustle]]></title>
            <link>https://medium.com/pragmatic-programmers/rustle-5c15d1c153a1?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/5c15d1c153a1</guid>
            <category><![CDATA[game-development]]></category>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[wordle]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[rust-programming-language]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Thu, 24 Feb 2022 11:34:10 GMT</pubDate>
            <atom:updated>2022-02-24T11:34:10.134Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kOhNOhhiQ8bV-O98d_e-jA.png" /></figure><h4>Build a Wordle Clone in Rust</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BbJT2UyhVRU1USDMcBxaUQ.png" /><figcaption><a href="https://pragprog.com/newsletter/">https://pragprog.com/newsletter/</a></figcaption></figure><p>If you’re on social media, you’ve probably seen lots of Wordle results. Wordle is a simple, addictive game — and many people wish they could play more often. Let’s indulge our word-guessing cravings and build <em>Rustle</em>: a Wordle clone written in Rust.</p><h3>Getting Started</h3><p>To get started, we’ll create a new project and set up some dependencies.</p><h4>Create a New Project</h4><p>Open a terminal/command prompt, and cd to your preferred directory for creating new Rust projects. Enter the following to create a new project:</p><pre>cargo new rustle</pre><p>Cargo will build an empty “Hello, World!” project for you.</p><h4>Set Up Some Dependencies</h4><p><em>Rustle</em> will require two dependencies:</p><ul><li><a href="https://crates.io/crates/bracket-random"><strong>bracket-random</strong></a> will be used to generate random numbers. It’s a friendly wrapper over the rand ecosystem.</li><li><a href="https://crates.io/crates/colored"><strong>colored</strong></a> will be used to print terminal text in multiple colors. Colored makes it easy to print colorful text on your terminal. For example &quot;this is blue&quot;.blue() will automatically add the ANSI commands to the string to render the string in blue — and correctly restore your default color afterward.</li></ul><p>In your newly created rustle project, open Cargo.toml and add these dependencies:</p><pre>[dependencies]<br>colored = &quot;2.0&quot;<br>bracket-random = &quot;0.8&quot;</pre><p>Let’s make these dependencies available within our program. Open src/main.rs and add the following to the top:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ca0791f2f491b238e5a919d9f1f07d34/href">https://medium.com/media/ca0791f2f491b238e5a919d9f1f07d34/href</a></iframe><p>You can now access the colored’s commands (such as red()) directly by name. RandomNumberGenerator is available without qualifying it with a full path. We’ve also included HashSet from the Rust standard library — we’ll need it later.</p><h3>Build a Word List</h3><p>There are lots of word lists for games available for free, online. We’ll use one commonly found in a lot of different Scrabble-like games: <a href="https://www.wordgamedictionary.com/twl06/download/twl06.txt">https://www.wordgamedictionary.com/twl06/download/twl06.txt</a></p><p>Download the words file, and save it as src/words.txtin your project directory.</p><p>Take a quick look at the file:</p><pre>TWL06 Scrabble Word List</pre><pre>aa<br>aah<br>aahed<br>aahing<br>aahs<br>(continues, there are 178693 lines!)</pre><p>Notice a few things:</p><ul><li>Not all of the words are five letters long</li><li>The top of the file contains a heading and an empty line</li><li>The words are all in lower-case</li></ul><p>All of that’s ok — there are plenty of valid words in there, and we’ll filter the words when we load them.</p><p>Let’s start by embedding the word list into our Rust program. Open src/main.rs. At the top of the file, add:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ed1a047ec536e2c877f3a757a43c96e6/href">https://medium.com/media/ed1a047ec536e2c877f3a757a43c96e6/href</a></iframe><p>This line creates a <strong>constant</strong> — a variable that cannot change. It is loaded with the <a href="https://doc.rust-lang.org/std/macro.include_str.html">include_str!</a> macro (built into Rust). include_str! loads the named file at compile-time, and embeds it into your source code. This step lets you ship the resulting executable file without also having to include the text file.</p><h4><strong>Sanitizing Input</strong></h4><p>Next, we need to create a function named sanitize_word. It’s never a good idea to trust user input (whether typed or from a word list), so we’ll perform a few steps to ensure that a string is a valid Rustle word:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/350dd99df7621f32c82cb0f61a98fd6e/href">https://medium.com/media/350dd99df7621f32c82cb0f61a98fd6e/href</a></iframe><p>This function operates as a <em>function chain — </em>each function reads the results of the previous function, gradually building a result:</p><ol><li><a href="https://doc.rust-lang.org/std/string/struct.String.html#method.trim">trim()</a><strong> </strong>removes any spaces and non-printing characters (such as \n indicating the end of a line). It’s always a good idea to trim input — you never know what hidden data may be in there!</li><li><a href="https://doc.rust-lang.org/std/string/struct.String.html#method.to_uppercase">to_uppercase()</a><strong> </strong>converts the word to capital letters (U.S. English).</li><li><a href="https://doc.rust-lang.org/std/string/struct.String.html#method.chars">chars()</a><strong> </strong>creates an iterator over the string, returning each character in turn. Rust strings may contain Unicode, so it isn’t guaranteed that each character is of a fixed length. For that reason, it’s preferred to iterate over chars() rather than accessing the underlying data directly.</li><li>We call filter with a test that each character <a href="https://doc.rust-lang.org/std/primitive.char.html#method.is_ascii_alphabetic">is_ascii_alphabetic</a>. This step ensures that if some Kanji, Cyrillic, numbers of other characters have slipped into the input — they will be ignored.</li><li>Finally we collect the results back into a String and return it.</li></ol><p>Now that we can sanitize potential words, let’s read them into a word list.</p><h4><strong>Building a Word List</strong></h4><p>It’s possible that you would prefer a Wordle-like game that uses a different length of word. Let’s support that! Next to the const you just created in src/main.rs, create a new constant specifying the desired word length:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/71d21402420987145d326b0a659979fc/href">https://medium.com/media/71d21402420987145d326b0a659979fc/href</a></iframe><p>Let’s make a function that examines every line in the word.txt file and returns a list of possible words in a vector:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c85e994b921acbe06492b7604e217ccc/href">https://medium.com/media/c85e994b921acbe06492b7604e217ccc/href</a></iframe><p>This function also operates as a <em>function chain</em>: each line takes the result of the previous line and operates on it:</p><ol><li>We start with ALL_WORDS — the entire words.txt file.</li><li><a href="https://doc.rust-lang.org/stable/std/str/struct.Split.html">Split</a> creates an iterator over the string, divided by a delimiter. We’ve picked \n — the newline marker. Subsequent calls are iterating over each line in the words.txt file.</li><li>We use <a href="https://doc.rust-lang.org/std/iter/struct.Skip.html">skip </a>to pass over the title and empty line at the beginning of the file.</li><li><a href="https://doc.rust-lang.org/std/iter/struct.Map.html">Map </a>is used to transform data. Calling map(sanitize_word) calls sanitize_word on every word we’re iterating. This step ensures that they are valid words.</li><li>We then filter with a closure (inline function). Filter retains entries for whom the closure returns true — in this case, if the sanitized word length equals our WORD_LENGTH constant.</li><li>Finally, collect places all of the remaining words into a vector of strings. Rust is able to deduce the type of vector Vec&lt;String&gt; from the function signature.</li></ol><p>This function builds an entire list of valid words. If you’re sticking with the default of 5, it will build a list of 8,938 possible words.</p><h3><strong>Customize Your Rustle Game</strong></h3><p>You may not want to play strictly by the Wordle rules. Maybe you’d like more guesses or words of a different length. Let’s accommodate this feature by adding a few constants to define the game parameters:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1ec245d3e12bd14a91d8ae690d17ae44/href">https://medium.com/media/1ec245d3e12bd14a91d8ae690d17ae44/href</a></iframe><p>You can change these values and recompile the game to play Wordle according to your own rules.</p><h4><strong>Building a RustleGame Type</strong></h4><p>We’ll encapsulate much of the Rustle game inside its own type. Let’s start by defining the type itself, which needs to hold the data we’ll need for the game logic:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8b5389b3614e1c610da9942953d09eed/href">https://medium.com/media/8b5389b3614e1c610da9942953d09eed/href</a></iframe><p>This is a pretty straightforward structure. It contains the dictionary (available words), the chosen word, a set of guessed letters, and a list of all of the guesses the player has tried so far.</p><h4><strong>Setting Up the Game</strong></h4><p>Let’s create a constructor for RustleGame that sets up a dictionary and selects a word. You’ve already written the functions required to make this work; this step wraps them and sets up the RustleGame state:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7c5031de39dd0a97c60581d9a24396eb/href">https://medium.com/media/7c5031de39dd0a97c60581d9a24396eb/href</a></iframe><p>This function creates a RandomNumberGenerator from bracket-random. It then builds the dictionary, using the word_listfunction you created earlier. A word is randomly selected from the dictionary and placed into the word variable.</p><h4><strong>Displaying Guesses</strong></h4><p>One of the joys of Worlde is the clear, attractive set of colored blocks that display your progress as you try to guess the chosen word. Some simple rules are applied to guesses:</p><ul><li>Letters that are both in the chosen word, and in the correct location are displayed in green.</li><li>Letters that are in the word, but are not in the correct place are displayed in yellow.</li><li>Letters that aren’t in the word are printed in grey and added to the list of letters you don’t need.</li></ul><p>The following function (part of RustleGame) accomplishes this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/35dea893c99fc618dd7f77c6910a8642/href">https://medium.com/media/35dea893c99fc618dd7f77c6910a8642/href</a></iframe><p>This function starts by iterating all of the stored guesses (from self.guesses). It uses enumerate to add numbering, and each display line starts with “1:” to indicate the guess number.</p><p>Each guess is then broken into characters with char, and each character is evaluated. If the word is in the right place (checked by using nth against the selected word), it prints in green. If it is in the word but not in the right place (evaluated with any), it prints in yellow. Otherwise, it prints in regular console colors.</p><p>Letters that aren’t in the target word are added to guessed_letters. Because this is a HashSet, you don’t need to worry about duplicates: the set stores a given value only once.</p><h4><strong>Printing the List of Wasted Letters</strong></h4><p>Wordle helps you out by showing you which letters you’ve used that aren’t in the target word. Since we’re storing these in guessed_letters, we can do the same. Add this function to RustleGame&#39;s implementation:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ad7f4986c2785674d89d6265a78f7969/href">https://medium.com/media/ad7f4986c2785674d89d6265a78f7969/href</a></iframe><p>This function starts by checking if there are any invalid letters. If there aren’t, it does nothing — there’s no need to display an empty list. Otherwise, it prints a list of letters from the guessed_letters set.</p><h4><strong>Asking the User to Make a Guess</strong></h4><p>Let’s create a function that asks the user to make a guess at the word. It needs to check that a guess is of a valid length and in the dictionary. Add the following to RustleGame&#39;s implementation:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6b2b91adf1d3e1b675b79582a1a8dda6/href">https://medium.com/media/6b2b91adf1d3e1b675b79582a1a8dda6/href</a></iframe><p>The function begins by prompting the user to enter a word of WORD_LENGTH letters. It’s always a good idea to prompt the user before waiting for input; otherwise, they may sit and stare at the program unsure of what to do.</p><p>Then the function calls the display_invalid_letters function we created above. We’re not constraining the user’s ability to reuse letters, but this should give them a useful hint.</p><p>Next, we loop on valid_guess. We’ll set the variable to true when a guess is of the right length and in the dictionary. We use stdin().read_line to read a guess from the terminal and immediately call sanitize_word on it. Finally, we check that the sanitized word is of the correct length — and in the dictionary. If those are true, we set valid_guess to true and continue; otherwise, we ask the user to try again.</p><h4><strong>Did We Win?</strong></h4><p>Our last function in RustleGamewill determine if the game is over:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0f8c6f55175d0f664484c0b4c811443c/href">https://medium.com/media/0f8c6f55175d0f664484c0b4c811443c/href</a></iframe><p>The is_game_over function returns true if the game is over, and false if it should continue. It checks to see if the most recent guess is correct, and congratulates the player if they won. If the player has run out of tries, it ends the game with a message telling the player the correct word. Otherwise, it returns false.</p><h4><strong>The Game Loop</strong></h4><p>Finally, let’s make our main function glue all of this together:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0cafd7e30c5045685fded23c717f9d21/href">https://medium.com/media/0cafd7e30c5045685fded23c717f9d21/href</a></iframe><p>We use a loop and break out of it if the game is over. The loop is running the functions we’ve built: it displays the guess board, asks for a guess, and checks to see if the game is over.</p><p>Run the game with cargo run and you can play Rustle!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/465/1*2vt5t6xkpukPV40FD6GL9Q.png" /></figure><p>Not bad for 120 lines of code! This game is a good example of how Rust’s iterator function and function chaining can help you create a fun game with very little code.</p><p>The full source code for the game is:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/89b72fdfe64bbedbcc21620bb15f79f6/href">https://medium.com/media/89b72fdfe64bbedbcc21620bb15f79f6/href</a></iframe><blockquote><strong><em>🧩 Have fun playing Rustle!</em></strong></blockquote><p>If you enjoyed this article and want to learn more about Rust, pick up Herbert Wolverson’s books from The Pragmatic Bookshelf. You can save 35 percent with promo code <strong>rust_2022 </strong>now through March 31, 2022. Promo codes are not valid on prior purchases.</p><ul><li><a href="https://pragprog.com/titles/hwrust/hands-on-rust/">Hands-on Rust</a></li><li><a href="https://pragprog.com/titles/hwrustbrain/rust-brain-teasers/">Rust Brain Teasers</a></li></ul><h4>Articles by Herbert Wolverson:</h4><ul><li><a href="https://medium.com/pragmatic-programmers/five-reasons-i-love-rust-ce9c756f4de7">Five Reasons I Love Rust</a></li><li><a href="https://medium.com/pragmatic-programmers/run-your-rust-games-in-a-browser-ceea86b04616">Run Your Rust Games in a Browser</a></li><li><a href="https://medium.com/pragmatic-programmers/game-development-with-rust-31147f7b6096">Game Development with Rust</a></li><li><a href="https://medium.com/pragmatic-programmers/rust-structure-packing-6d8978e3c99e">Rust Structure Packing</a></li><li><a href="https://medium.com/pragmatic-programmers/flappy-dragon-rust-647e91a34dd4">Hands-on Rust Bonus Content</a></li><li><a href="https://medium.com/pragmatic-programmers/trying-out-the-rust-bevy-engine-e97c5c950504">Trying Out the Rust Bevy Engine</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5c15d1c153a1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pragmatic-programmers/rustle-5c15d1c153a1">Rustle</a> was originally published in <a href="https://medium.com/pragmatic-programmers">The Pragmatic Programmers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Five Reasons I Love Rust]]></title>
            <link>https://medium.com/pragmatic-programmers/five-reasons-i-love-rust-ce9c756f4de7?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/ce9c756f4de7</guid>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[language]]></category>
            <category><![CDATA[concurrency]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[iterators]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Wed, 19 Jan 2022 11:32:47 GMT</pubDate>
            <atom:updated>2022-01-19T11:32:47.959Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xgDfY63OTCN4wCMs" /><figcaption>Photo by <a href="https://unsplash.com/@sunitalap?utm_source=medium&amp;utm_medium=referral">Zsolt Palatinus</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h4>A Language That Addresses Pain Points of Modern Development</h4><p><strong>📚 Connect with us. </strong><em>Want to hear what’s new at The Pragmatic Bookshelf? </em><a href="https://pragprog.com/newsletter/"><em>Sign up for our newsletter</em></a><em>. You’ll be the first to know about author speaking engagements, books in beta, new books in print, and promo codes that give you discounts of up to 40 percent.</em></p><p>I began my Rust journey after spending years writing C++. After finishing a particularly difficult project, I went looking for a solution to that project’s pain points. I’d heard about Rust, and tried using it to make some simple games. Several <a href="https://github.com/thebracket/">open source projects</a>, <a href="http://bfnightly.bracketproductions.com/rustbook/">a tutorial</a> and <a href="https://pragprog.com/search/?q=wolverson">two books</a> later — I haven’t looked back.</p><p>Rust is built by developers, for developers — and works hard to provide both a consistent, useful systems language and a development ecosystem that addresses the pain points of modern development.</p><h3><strong>One: Dependency Management</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*4tMtpmBy4F60RJHuvx8c6w.jpeg" /></figure><p>C and C++ have many solutions for managing dependencies — <em>Vcpkg</em>, <em>Conan</em>, <em>Hunter</em>, and so on. All have their perks — but mixing and matching between them becomes a chore. In particular, sharing a project with others can require that recipients be willing to take the time to set up your favorite package manager — or manually install dependencies.</p><p>Rust’s <em>Crates</em> system provides a unified package management system across platforms. You can add dependencies as lines in your project’s <em>Cargo.toml</em> file — and the system does the rest:</p><pre>[dependencies]<br>wgpu = &quot;0.12&quot;</pre><p>This line downloads wgpu, a full-featured graphics system that supports DirectX, Vulkan, Metal, and WebGPU. It works on Mac, Windows, Linux, and other platforms.</p><p>A few other things that can make Rust dependency management great:</p><ul><li>Dependencies are statically linked — no DLL or library packages to ship/install with your project.</li><li>Crates (packages) can compile C/C++ libraries and make them available to your Rust program.</li><li>Semantic versioning is enforced, and you can easily <em>pin </em>your dependencies — and not worry about an update breaking your code.</li><li>Your dependencies don’t have to come from the Rust <em>Crates</em> ecosystem. Cargo integrates with filesystem paths, git repositories, <em>vendored</em> dependency libraries, and more.</li></ul><p>Rust makes it easy to stop re-inventing the wheel and benefit from premade packages in your projects. Rust also makes it easy to keep your dependencies up-to-date.</p><h3><strong>Two: Easy and Consistent Build Tooling</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*za1V9WbmHwTS3Oj38rZoBg.jpeg" /></figure><p>Another common complaint among C++ developers is the lack of a standardized build system. Many projects use <em>CMake</em> — which is very powerful, and quite intimidating.</p><p>Other projects use <em>autotools</em>, <em>make</em>, <em>ninja</em>, <em>msbuild</em>, <em>meson</em>, and so on. C++ has a plethora of choices, and everyone has their favorite. The C++ ecosystem works but can make switching platforms or collaborating with other developers painful.</p><p>Rust’s <em>Cargo</em> provides a powerful, consistent build tool:</p><ul><li>cargo new lets you create new application or library projects. It even defaults to setting up a <em>git</em> repository with a <em>.gitignore</em> file ready to use.</li><li>cargo build compiles your project. You can specify --release to enable optimizations.</li><li>cargo run runs your application. Again, --release enables optimizations.</li><li>cargo check performs a quick build, finding errors.</li></ul><p>Cargo’s build system revolves around a <em>Cargo.toml </em>manifest for your project. This is the same file that handles dependencies — the build system is highly integrated. Here’s an example that includes the complete Bevy game engine:</p><pre>[package]<br>name = &quot;bevy_mesh_example&quot;<br>version = &quot;0.1.0&quot;<br>edition = &quot;2021&quot;</pre><pre>[dependencies]<br>bevy = &quot;0.5&quot;</pre><p>Despite its simplicity, Cargo builds can be very finely controlled. You can gate dependencies behind <em>feature flags</em>, customize your build based on target platform, and <em>patch </em>dependencies to use source from Github or other repositories. Here’s an example of a dependency that compiles only if the target platform isn’t Web Assembly:</p><pre>[target.&#39;cfg(not(any(target_arch = &quot;wasm32&quot;)))&#39;.dependencies]<br>glutin = {version = &quot;0.27.0&quot;, optional = true }</pre><p>Coming from <em>CMake</em>, <em>Cargo</em> was a breath of fresh air. It’s easy to get started — and the features you need to ship a complex, cross-platform library are included out of the box. Cargo can even handle cross-compilation to other architectures.</p><h3><strong>Three: Safety First</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*lW24oPVr6YoYWVVD45wYQA.jpeg" /></figure><p>Rust turns several classes of C/C++ bugs into compilation errors:</p><ul><li>Rust doesn’t have <em>null pointers</em>. You can wrap values in <em>Option</em> types if they may or may not exist, but if a variable promises to point somewhere — it will. Say goodbye to null-pointer exceptions/crashes.</li><li>Rust tracks ownership of variables. <em>Use after move</em> bugs are impossible in safe Rust. <em>Dangling pointers</em> — where you’ve handed out a reference to an object and later deleted it — are also compilation errors.</li><li>Rust protects against <em>data races</em> by enforcing synchronization across threads.</li><li>Rust enforces <em>RAII</em> (Resource Acquisition is Initialization) automatically. A structure that creates data will free it when it is destroyed — unless you explicitly say otherwise. Memory leaks aren’t impossible (there are even commands for creating them, should you <em>need</em> to release memory/resources without deallocating them) — but the default is safety.</li><li>Rust <em>can</em> be used to create potentially-dangerous code. This possibility is inevitable: you may need to interact directly with some hardware, may need to work with APIs from a less-safe language, or may need to use a mechanism that isn’t provably safe. Rust code can avoid many of the safety checks when wrapped in unsafe{ .. } tags. This tag is a good thing: you aren’t sacrificing potential usability, but you can isolate the potentially risky code to self-contained — and well-labeled — areas of code.</li></ul><p>Coming from C++, I spent my first week with Rust cursing the <em>borrow checker </em>— the mechanism that enforces many of these safety features. After getting used to arranging my code to be <em>borrow-checker friendly</em> — I realized that the code was often clearer for it. Now, I instinctively find myself writing C++ with Rust idioms. Learning Rust has made my C++ safer!</p><h3><strong>Four: Fearless Concurrency</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*urItGkxQ8UT5kbnG_jaocQ.jpeg" /></figure><p>Rust promises <em>fearless concurrency</em>, promising to help you unleash the power of your CPU. Part of this capability comes from data-race protection: Rust enforces synchronization (and provides great synchronization primitives to use), making the most common threading bugs into compiler errors. For example, multiple threads that write to a shared variable are possible in both C++ and Rust. Rust will fail to compile if you don’t protect the shared object with an appropriate locking mechanism.</p><p>Rust also provides a great ecosystem for concurrent programming:</p><ul><li>The <a href="https://github.com/rayon-rs/rayon">Rayon </a>crate provides a work-stealing thread pool with support for job-based scheduling. Rayon offers great support for parallel iterators that can turn normal iterator-based code into multi-threaded performance monsters.</li><li><a href="https://github.com/tokio-rs/tokio">Tokio</a> and <a href="https://github.com/async-rs/async-std">Async-Std</a> provide very high-performance <em>promise/future</em> based asynchronous support for powerful servers.</li><li>Many game libraries, such as <a href="https://github.com/amethyst/legion">Legion</a> and <a href="https://github.com/bevyengine/bevy">Bevy</a>, integrate Rust’s first-class multi-threading into their Entity-Component Systems architecture. I wrote my first Rust game without realizing that I’d enabled multi-threading support!</li></ul><blockquote><em>🔮 Rust concurrency is a large topic — I’ll publish an article examining Rust’s fearless concurrency claims in the near future.</em></blockquote><h3><strong>Five: First-Class Iterators</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*X-bnwclFeGb-oWmP3ZDlIw.jpeg" /></figure><p>Iterators are Rust’s great, unsung hero.</p><p>Similar to <em>LINQ</em> in C#, or the new C++ <em>Ranges</em>, iterators make it easy to ingest large amount of data — filter, map, and process it — and output it in the form you need.</p><p>Unlike iterators in some other languages, Rust’s iterators are deeply embedded into the language. The following code snippets do the same thing:</p><pre>// Use a for loop<br>for i in my_collection.iter() { .. }</pre><pre>// Use for_each<br>my_collection.iter().for_each(|i| .. }</pre><p>Add <em>Rayon</em> to the mix, and you can automatically add parallel processing (and benefit from the compiler telling you if you forgot to lock a shared variable):</p><pre>my_collection.par_iter().for_each(|i| .. )</pre><p>Iterators are designed to be <em>chained</em> together. For example:</p><pre>let bug_summaries : Vec&lt;BugSummary&gt; = all_bug_reports.iter()<br>     .filter(|i| i.type == BugReport)<br>     .map(|i| BugSummary(i))<br>     .collect();</pre><p>There are a <a href="https://doc.rust-lang.org/std/iter/trait.Iterator.html">lot of iterator functions</a> available out of the box — enough to handle the majority of processing needs. Count, sum, map, fold, zip iterators (combining two data streams), reverse iterators —they’re all there. If you need more, Rust makes it easy to create your own iterators.</p><h3><strong>Wrap-Up</strong></h3><p>Rust is a very productive language. The Rust ecosystem makes it easy to work with dependencies and consistently build projects across platforms. The language protects you from the most common types of memory bugs and makes it easy to unleash the full power of your multi-core CPU. Iterators make crunching large amounts of data a breeze. Rust deserves <a href="https://www.infoworld.com/article/3546337/rust-language-tops-stack-overflow-survey.html">StackOverflow users’ votes for “Most Loved” language</a>.</p><blockquote><strong>6️⃣ Bonus perk six: </strong>the Rust community — they are a helpful, welcoming bunch. I was overwhelmed by their willingness to assist me while I made my first steps into Rust-land.</blockquote><blockquote><em>📣 Add your voice to the story. Tell everyone what you love about Rust in the comments.</em></blockquote><p>If you enjoyed this article and want to learn more about Rust, pick up Herbert Wolverson’s book from The Pragmatic Bookshelf. You can save 35 percent with promo code <strong>rust_2022 </strong>now through March 1, 2022. Promo codes are not valid on prior purchases.</p><p><a href="https://pragprog.com/titles/hwrust/hands-on-rust/">Hands-on Rust</a></p><h4>Also by Herbert Wolverson:</h4><ul><li><a href="https://medium.com/pragmatic-programmers/run-your-rust-games-in-a-browser-ceea86b04616">Run Your Rust Games in a Browser</a></li><li><a href="https://pragprog.com/titles/hwrustbrain/rust-brain-teasers/">Rust Brain Teasers</a></li><li><a href="https://medium.com/pragmatic-programmers/game-development-with-rust-31147f7b6096">Game Development with Rust</a></li><li><a href="https://medium.com/pragmatic-programmers/rust-structure-packing-6d8978e3c99e">Rust Structure Packing</a></li><li><a href="https://medium.com/pragmatic-programmers/flappy-dragon-rust-647e91a34dd4">Hands-on Rust Bonus Content</a></li><li><a href="https://medium.com/pragmatic-programmers/trying-out-the-rust-bevy-engine-e97c5c950504">Trying Out the Rust Bevy Engine</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ce9c756f4de7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pragmatic-programmers/five-reasons-i-love-rust-ce9c756f4de7">Five Reasons I Love Rust</a> was originally published in <a href="https://medium.com/pragmatic-programmers">The Pragmatic Programmers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Run Your Rust Games in a Browser]]></title>
            <link>https://medium.com/pragmatic-programmers/run-your-rust-games-in-a-browser-ceea86b04616?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/ceea86b04616</guid>
            <category><![CDATA[language]]></category>
            <category><![CDATA[webassembly]]></category>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[gamedev]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Mon, 29 Nov 2021 11:32:29 GMT</pubDate>
            <atom:updated>2021-11-29T11:32:29.397Z</atom:updated>
            <content:encoded><![CDATA[<h4>Bonus Content from Hands-on Rust</h4><p><strong>📚 Connect with us. </strong><em>Want to hear what’s new at The Pragmatic Bookshelf? </em><a href="https://pragprog.com/newsletter/"><em>Sign up for our newsletter</em></a><em>. You’ll be the first to know about author speaking engagements, books in beta, new books in print, and promo codes that give you discounts of up to 40 percent.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/457/1*mxm1vcVfq5vubqgyNqu22Q.jpeg" /><figcaption>Image by <a href="https://www.shutterstock.com/g/vectorbang">Vectors Bang</a> on <a href="https://www.shutterstock.com/image-vector/dragon-cartoon-vector-cute-dragonfly-dino-767802043">Shutterstock</a></figcaption></figure><p>One of the great things about using Rust and bracket-lib is that you can compile your games for the web.</p><p>Rust natively supports compiling to WebAssembly (WASM).</p><p>With a little bit of automated work to map WebAssembly bindings to native JavaScript, you can run your games in your browser.</p><h4><em>🐉</em> Here’s <a href="https://bfnightly.bracketproductions.com/flappy_bonus/">Flappy Dragon in a Browser</a> (Requires Chrome, Firefox, or Edge).</h4><h3>What Is WebAssembly?</h3><p>WebAssembly began life as <a href="https://emscripten.org/">Emscripten</a>, a project to build C++ for the web. Emscripten compiled your C++ programs into a binary format readable by JavaScript. A simple JavaScript run-time then ran your compiled code in the browser. Emscripten could wrap your C/C++ functions in a JavaScript header, allowing you to call high-performance functions from inside JavaScript. You could also use Emscripten to write full games.</p><p>Browser developers realized that Emscripten had the potential to extend the capability of browser apps and added back-end code to make WebAssembly run even faster. After a few rounds of development, WebAssembly was formalized as a compilation target. <a href="https://llvm.org/">LLVM</a> included it as a back-end, and Rust was one of the first platforms to provide first-class WASM support.</p><p>WASM does come with limitations:</p><ul><li>Threading works differently in a web browser and was largely disabled in response to the Specter line of vulnerabilities. So you can’t take advantage of the multi-threading built into Legion (and similar ECS systems). Your game will run in a single thread.</li><li>Not every browser runs WASM well — it works great in Chrome and Firefox, but not so well in Safari.</li><li>Large games can take a while to download.</li><li>WASM doesn’t have a native filesystem, so loading assets from your web server is difficult. You can alleviate this issue by embedding your assets into your program.</li><li>You need a web server. The server can be running locally, but most browsers refuse to execute WASM programs loaded locally with file: links.</li></ul><p>So with those caveats in mind, let’s get started making your Rust games work in your web browser.</p><h3>Making Rust Games Work in a Browser</h3><p>Making Rust Games work in a browser requires several steps. We’ll need to do the following:</p><ul><li>Update bracket-lib</li><li>Install the WASM toolchain</li><li>Install the wasm-bindgen program</li><li>Compile</li><li>Embed assets for filesystem dependencies</li><li>Build and bind</li><li>Create a webpage</li></ul><h4>Update Bracket-Lib</h4><p>The latest version of bracket-lib includes some changes to make WebAssembly programs run better. Update your dependency in Cargo.toml to read:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/47e5850bc969409631025f050a165093/href">https://medium.com/media/47e5850bc969409631025f050a165093/href</a></iframe><p>Now run cargo update to update your crates.</p><h4>Install the WASM Toolchain</h4><p>Rust’s cargo system natively supports cross-compilation. Cross-compilation allows you to compile programs for a platform other than the one you are currently using. For example, you can make Linux builds of your game without leaving Windows. WASM is supported as another platform, so you cross-compile your programs into WASM format. The official name of the WASM platform is: wasm32-unknown-unknown.</p><p>The Rust install tool (rustup) can install toolchains for you. Install wasm support on your computer with the following command:</p><pre>rustup target <strong>add</strong> wasm32-unknown-unknown</pre><p>Rust will download and install the current wasm32-unknown-unknown toolchain support for you.</p><h4>Install Bindgen</h4><p>Compiling to WebAssembly isn’t quite enough to make your programs work in your browser. You also need some JavaScript to connect your WASM program to the browser’s execution engine. You could create this by hand, but it’s really tedious. Instead, the wasm-bindgen program can do the work for you.</p><blockquote>Note that when you update your Rust setup, you’ll want to repeat this process to get the newest wasm-bindgen tool.</blockquote><p>You can install bindgen with the following command:</p><pre>cargo install wasm-bindgen-cli</pre><h4>Compile Your Programs</h4><p>You can now compile your programs to WASM with the following command:</p><pre>cargo build --target wasm32-unknown-unknown --release</pre><p>This step will download all of your dependencies, and compile them — alongside your program — into WASM format. The binaries will be optimized and almost ready to use. You still have a couple of steps remaining: handling filesystem dependencies and making some HTML to actually run your program in a browser.</p><h4>Embed Assets for Filesystem Dependencies</h4><p>WASM doesn’t provide direct support for your filesystem. Overall, that’s a good thing — you don’t want random programs on the Internet gaining access to your private files! It does make life a little more difficult when you need to load resources to support your program. bracket-lib helps get around this by providing a kind of embedding system: you can embed resources directly into your program, including them at compilation time. This process makes compilation take longer (and produces larger binaries), but it removes the need to create a web-based asset loading system.</p><p>bracket-lib automatically embeds terminal8x8 and vga8x16 fonts for you. The basic bracket-lib demos will work unchanged because of this, as will the ASCII version of Flappy Dragon. However, you probably need more than the built-in font files! You can add fonts with a two-step process.</p><p>In your main.rs file, outside of the main function, you can embed resources with the embedded_resource! macro provided by bracket-lib. This macro is a thin wrapper over the built-in include_bytes! macro. The path you provide <em>must</em> be the path Cargo will see when it runs the build. For example, the following line of code embeds flappy32.png from the FlappyBonus project:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/343b3e3b645993993777c9b64e5840c3/href">https://medium.com/media/343b3e3b645993993777c9b64e5840c3/href</a></iframe><p>This step includes your file in the program’s compiled output. The last step is to tell bracket-lib to include the file as a resource. At the top of your main.rs function, you need to <em>link</em> the resource (this step adds it to bracket-lib’s font system). Remove any .. from your path: this step uses the final path stored in the resource build. For example, to link the flappy32.png file we embedded a moment ago you would use:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cd280cb35868d86012c753a1f11d697d/href">https://medium.com/media/cd280cb35868d86012c753a1f11d697d/href</a></iframe><h4>Build and Bind</h4><p>Now that your asset embedding is in place, build your project:</p><pre>cargo build --target wasm32-unknown-unknown --release</pre><p>Now create a directory named wasm-help (off of your project directory, next to src and in the same directory as Cargo.toml). You don’t have to name the directory that, but the examples in this article will assume that you did so. It’s time to create the JavaScript linking your program to the web browser. Run the following command (you may need to adjust the path to match your target directory if you are using workspaces):</p><pre>wasm-bindgen target\wasm32-unknown-unknown\release\flappy_bonus.wasm --out-dir .\wasm_help --<strong>no</strong>-modules --<strong>no</strong>-typescript</pre><p>If you look in your wasm-help directory, you’ll see that some files have appeared:</p><ul><li>flappy_bonus.js which contains JavaScript bindings for your program.</li><li>flappy_bonus_bg.wasm which contains your WASM compiled code.</li></ul><p>All that remains is to create a webpage to execute your program.</p><h4>Create a Webpage</h4><p>I typically copy/paste the following skeletal HTML into a file named index.html in the wasm-help directory and edit the text to match the game name:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/82305ea61562a19f35fc4799424906c1/href">https://medium.com/media/82305ea61562a19f35fc4799424906c1/href</a></iframe><p>This file loads the JavaScript file created for you and loads your WASM once the page has finished downloading. This step creates a sort of canvas on which the game can render. Upload your wasm-help directory to a web server (even a local one), and you can play your game in a browser.</p><h3>Preparing the Hands-on Rust Dungeon Crawler — WASM Edition</h3><p>The Dungeon Crawler from <em>Hands-on Rust</em> requires a few more changes: Legion needs to be put into single-threaded mode; you need to embed your tile graphics; and the later chapters that use data-driven definitions need to load the data from embedded resources.</p><p>We’ll work on the loot_tables example to get the finished game onto the web.</p><h4><strong>Make Legion Single-Threaded</strong></h4><p>Open your Cargo.toml file and find the dependency for Legion. Replace it with the following:</p><pre>legion = { version = &quot;=0.3.1&quot;, default-features = <strong>false</strong>, features = [&quot;wasm-bindgen&quot;, &quot;codegen&quot;] }</pre><p>This code disables Legion’s multi-threading and enables compatibility with wasm-bindgen.</p><h4><strong>Embed Tile Graphics</strong></h4><p>Just like you did with Flappy, you need to embed the graphics files. In main.rs (above fn main()) include the following:</p><pre>embedded_resource!(TILE_FONT, &quot;../resources/dungeonfont.png&quot;);</pre><p>At the top of fn main() include:</p><pre>link_resource!(TILE_FONT, &quot;resources/dungeonfont.png&quot;);</pre><p>Otherwise, your main function is the same:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/863875d08ab9c3dedbfdc66e37ebe1b8/href">https://medium.com/media/863875d08ab9c3dedbfdc66e37ebe1b8/href</a></iframe><p>Notice how the function is using terminal8x8but you don’t link it? The image is embedded by default in bracket-lib.</p><h4><strong>Load Data Files</strong></h4><p>In the <em>Loot</em> chapter of <em>Hands-on Rust</em>, you learn to use TOML files to define your data. Loading the definitions from disk offers great flexibility, but isn’t very WASM friendly — you need to embed the file in your program. Fortunately, Rust provides an include_bytes! macro to embed files in your code. You can combine this with a from_bytes function from the RON deserializer to include the file as part of your WASM build.</p><p>Open src/spawner/template.rs and replace the load() function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d6cfdbed58ff2145495cea290e679b54/href">https://medium.com/media/d6cfdbed58ff2145495cea290e679b54/href</a></iframe><p>The template.ron file will now be embedded in your WASM file, and the reader will load it from there.</p><h4><strong>Build the Dungeon Crawler</strong></h4><p>Next, you need to follow the same steps you used for Flappy. Create a wasm-help directory and add an index.html file to it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ec3fcc2407e9a22435ccda60dbf8f174/href">https://medium.com/media/ec3fcc2407e9a22435ccda60dbf8f174/href</a></iframe><p>Then build your WASM file:</p><pre>cargo build --target wasm32-unknown-unknown --release</pre><p>Now you can publish your wasm_help directory to your web server.</p><p>Here’s the <a href="https://bfnightly.bracketproductions.com/loot_tables/">Loot Tables</a> example from <a href="https://pragprog.com/titles/hwrust/hands-on-rust/"><em>Hands-on Rust</em></a>, running in your browser:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*V1OMOruK5OvTEaDq.jpg" /></figure><h3>Wrapping Up</h3><p>WebAssembly is a great way to publish your games on the web. Rust has all the tools you need, and bracket-lib is designed to help you with the process. Now you can publish your game, too.</p><p>🏓 Be sure to send me a link if you publish your game to the web—I’d love to see what you come up with.</p><p>If you enjoyed this article and want to learn more about Rust, pickup Herbert Wolverson’s book from The Pragmatic Bookshelf:</p><p><a href="https://pragprog.com/titles/hwrust/hands-on-rust/">Hands-on Rust</a></p><h4>Also by Herbert Wolverson:</h4><ul><li><a href="https://pragprog.com/titles/hwrustbrain/rust-brain-teasers/">Rust Brain Teasers</a></li><li><a href="https://medium.com/pragmatic-programmers/game-development-with-rust-31147f7b6096">Game Development with Rust</a></li><li><a href="https://medium.com/pragmatic-programmers/rust-structure-packing-6d8978e3c99e">Rust Structure Packing</a></li><li><a href="https://medium.com/pragmatic-programmers/flappy-dragon-rust-647e91a34dd4">Hands-on Rust Bonus Content</a></li><li><a href="https://medium.com/pragmatic-programmers/trying-out-the-rust-bevy-engine-e97c5c950504">Trying Out the Rust Bevy Engine</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ceea86b04616" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pragmatic-programmers/run-your-rust-games-in-a-browser-ceea86b04616">Run Your Rust Games in a Browser</a> was originally published in <a href="https://medium.com/pragmatic-programmers">The Pragmatic Programmers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Trying Out the Rust Bevy Engine]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/pragmatic-programmers/trying-out-the-rust-bevy-engine-e97c5c950504?source=rss-1e6a85607f68------2"><img src="https://cdn-images-1.medium.com/max/2000/1*kNnEv5dPhL4U-PTVYMEUxg.png" width="2000"></a></p><p class="medium-feed-snippet">Kick the Tires with a Space Invaders Game</p><p class="medium-feed-link"><a href="https://medium.com/pragmatic-programmers/trying-out-the-rust-bevy-engine-e97c5c950504?source=rss-1e6a85607f68------2">Continue reading on The Pragmatic Programmers »</a></p></div>]]></description>
            <link>https://medium.com/pragmatic-programmers/trying-out-the-rust-bevy-engine-e97c5c950504?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/e97c5c950504</guid>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[language]]></category>
            <category><![CDATA[games]]></category>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[bevy]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Thu, 19 Aug 2021 10:32:40 GMT</pubDate>
            <atom:updated>2021-08-19T10:32:40.326Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Hands-on Rust Bonus Content]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/pragmatic-programmers/flappy-dragon-rust-647e91a34dd4?source=rss-1e6a85607f68------2"><img src="https://cdn-images-1.medium.com/max/750/0*ktRpwiqb2xp1Ry4q.jpg" width="750"></a></p><p class="medium-feed-snippet">From Flappy Dragon to Flappy Bonus</p><p class="medium-feed-link"><a href="https://medium.com/pragmatic-programmers/flappy-dragon-rust-647e91a34dd4?source=rss-1e6a85607f68------2">Continue reading on The Pragmatic Programmers »</a></p></div>]]></description>
            <link>https://medium.com/pragmatic-programmers/flappy-dragon-rust-647e91a34dd4?source=rss-1e6a85607f68------2</link>
            <guid isPermaLink="false">https://medium.com/p/647e91a34dd4</guid>
            <category><![CDATA[games]]></category>
            <category><![CDATA[hwrust]]></category>
            <category><![CDATA[articles]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[language]]></category>
            <dc:creator><![CDATA[Herbert Wolverson]]></dc:creator>
            <pubDate>Wed, 28 Jul 2021 10:33:26 GMT</pubDate>
            <atom:updated>2021-07-28T10:33:26.192Z</atom:updated>
        </item>
    </channel>
</rss>