<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jordan Barrett</title>
    <description>The latest articles on Forem by Jordan Barrett (@barrettj12).</description>
    <link>https://forem.com/barrettj12</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3649699%2Ff4f1e72b-d1d5-49ae-94ea-2c0d7b9e98df.jpg</url>
      <title>Forem: Jordan Barrett</title>
      <link>https://forem.com/barrettj12</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/barrettj12"/>
    <language>en</language>
    <item>
      <title>What I learned from my first week in Rust</title>
      <dc:creator>Jordan Barrett</dc:creator>
      <pubDate>Sat, 06 Dec 2025 23:25:28 +0000</pubDate>
      <link>https://forem.com/barrettj12/what-i-learned-from-my-first-week-in-rust-3hkf</link>
      <guid>https://forem.com/barrettj12/what-i-learned-from-my-first-week-in-rust-3hkf</guid>
      <description>&lt;p&gt;Rust is a modern programming language with unique memory safety features that make it particularly suitable for systems programming. Its first stable release (1.0) was in 2015, and since then it's been gradually gaining popularity, especially for low-level programming and performance-critical applications. I've been wanting to learn Rust for a while, and this week I finally took the leap. In this post, I'll talk about how I learnt Rust, the distinctive features it has that separate it from the languages I'm most familiar with (Go, Python, JavaScript), and a simple project I built in order to solidify my understanding of Rust.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to learn Rust
&lt;/h2&gt;

&lt;p&gt;Some frequently cited resources for learning Rust are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://doc.rust-lang.org/stable/book/" rel="noopener noreferrer"&gt;The Rust Programming Language&lt;/a&gt; - the official Rust book, which covers the language pretty comprehensively&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rustlings.rust-lang.org/" rel="noopener noreferrer"&gt;Rustlings&lt;/a&gt; - a collection of exercises which help you learn Rust by fixing small code snippets&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://doc.rust-lang.org/stable/rust-by-example/" rel="noopener noreferrer"&gt;Rust by Example&lt;/a&gt; - interactive, runnable code examples with explanations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I personally found Rust by Example the most helpful, as it meshed well with my hands-on learning style. It reminded me of the "&lt;a href="https://go.dev/tour/" rel="noopener noreferrer"&gt;Tour of Go&lt;/a&gt;", which was the primary resource I used to learn Go back in the day. However, I encourage you to pick the resource that works best for your own personal learning style.&lt;/p&gt;

&lt;p&gt;If you prefer video resources, I also found &lt;a href="https://www.youtube.com/watch?v=BpPEoZW5IiY" rel="noopener noreferrer"&gt;freeCodeCamp's Rust course on YouTube&lt;/a&gt; to be a good resource, although I only watched a small part of it.&lt;/p&gt;

&lt;p&gt;I also used ChatGPT extensively to explain concepts in-depth and help me understand compiler errors, refactor code, etc. Especially at the learning stage, the key is to not just let AI write the code for you - make sure your brain processes everything it says and that you understand it fully. Remember that AI can hallucinate too! So take everything it says with a grain of salt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Distinctive features of Rust
&lt;/h2&gt;

&lt;p&gt;Coming from a background in Go, Python, and JavaScript, several features of Rust stood out to me:&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax
&lt;/h3&gt;

&lt;p&gt;Rust uses a double colon &lt;code&gt;::&lt;/code&gt; as a path separator for modules, namespaces, etc, unlike the dot &lt;code&gt;.&lt;/code&gt; used in Go/Python/JS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ownership
&lt;/h3&gt;

&lt;p&gt;This is a concept that is pretty much unique to Rust. Each &lt;em&gt;value&lt;/em&gt; has exactly one &lt;em&gt;owner&lt;/em&gt;, and the value is &lt;em&gt;dropped&lt;/em&gt; when the owner goes out of scope. For example, if we have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then &lt;code&gt;s&lt;/code&gt; is the owner of the value &lt;code&gt;String::from("hello")&lt;/code&gt;. If we then go&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then &lt;code&gt;s2&lt;/code&gt; takes over ownership of this value from &lt;code&gt;s&lt;/code&gt; - as a result, trying to reuse the variable &lt;code&gt;s&lt;/code&gt; after this point will raise a compilation error.&lt;/p&gt;

&lt;p&gt;Passing a variable into a function call will also transfer the ownership over to that function. At the end of that function, the variable will go out of scope and the value will be dropped.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;takes_ownership&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// ownership moves into the function&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// ❌ ERROR: s is no longer valid here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;takes_ownership&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Got: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// value goes out of scope here → String is dropped&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returning a value from a function also transfers the ownership to the outer calling function.&lt;/p&gt;

&lt;p&gt;The whole point of ownership is to guarantee memory safety in Rust - it removes the need for a garbage collector, and prevents problems such as memory leaks and dangling pointers. To avoid transferring ownership, you can "borrow" a value instead. This is essentially done by passing in a reference to the variable rather than the variable itself. For example, if we have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then ownership of &lt;code&gt;s&lt;/code&gt; is NOT transferred over to &lt;code&gt;foo&lt;/code&gt;, and as a result, we can still use the variable &lt;code&gt;s&lt;/code&gt; after the call to &lt;code&gt;foo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By default, when we pass a reference into &lt;code&gt;foo&lt;/code&gt;, we are not allowed to modify the data it points to. If we need to do this, we can use a &lt;em&gt;mutable reference&lt;/em&gt; instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust lets you have any number of immutable references to a variable at any one time, or at most one mutable reference, but you can't mix and match. This allows Rust to prevent data races at compile time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error handling
&lt;/h3&gt;

&lt;p&gt;In Rust, errors ultimately have to be handled explicitly, but Rust provides some nice syntactic sugar to make this easy. The &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; type represents something that could be either a value of type &lt;code&gt;T&lt;/code&gt; or an error of type &lt;code&gt;E&lt;/code&gt;; for example, a function with signature&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IOError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can return either a &lt;code&gt;String&lt;/code&gt; or an &lt;code&gt;IOError&lt;/code&gt;. The &lt;code&gt;?&lt;/code&gt; operator is the most common way to handle errors, and it propagates the error up to the calling function. For example, if we have this function which calls &lt;code&gt;foo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;IOError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it acts as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;foo&lt;/code&gt; returns a non-error value of type &lt;code&gt;T&lt;/code&gt;, this will be assigned to the variable &lt;code&gt;data&lt;/code&gt;, and execution of &lt;code&gt;bar&lt;/code&gt; will continue as normal.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;foo&lt;/code&gt; returns an error, execution of &lt;code&gt;bar&lt;/code&gt; will stop immediately and it will propagate the error up to the caller.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;?&lt;/code&gt; operator can be a bit confusing at first, but once you understand how to use it, it's really quite a nice tool that can save you a lot of boilerplate. I'm a Go programmer, and although I appreciate that Go also handles errors explicitly, I still find it kind of annoying to have to do this dance every time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At least Rust's &lt;code&gt;?&lt;/code&gt; gives you a nice way to avoid that and condense it down into a single line.&lt;/p&gt;

&lt;h3&gt;
  
  
  Macros
&lt;/h3&gt;

&lt;p&gt;Macros are a powerful feature of Rust that allow you to do &lt;em&gt;metaprogramming&lt;/em&gt; - basically, macros are pieces of code that are expanded by the compiler to generate other pieces of code. In practice, they look a lot like functions but are actually a lot more powerful. Macros are denoted by a &lt;code&gt;!&lt;/code&gt; after the name, e.g. &lt;code&gt;my_macro!(args)&lt;/code&gt;. In fact, Rust's built-in &lt;code&gt;println!&lt;/code&gt; utility is actually a macro.&lt;/p&gt;

&lt;p&gt;There are several different types of macros, but the most common type is defined using &lt;code&gt;macro_rules!&lt;/code&gt;. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;add_one&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$x:expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;add_one!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At compile-time, the &lt;code&gt;add_one!&lt;/code&gt; macro will be expanded by the compiler, so that &lt;code&gt;main&lt;/code&gt; will be transformed into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Traits
&lt;/h3&gt;

&lt;p&gt;Traits in Rust are a lot like interfaces in Go or other OOP languages. Essentially, a trait defines a contract of behaviour via a collection of methods, and then a type can implement that trait by defining implementations of each of the methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;Greet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Greet&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, my name is {}!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building a simple HTTP server in Rust
&lt;/h2&gt;

&lt;p&gt;To test my knowledge of Rust, I set myself a small challenge of writing a basic HTTP server implementation. You can see the complete code &lt;a href="https://github.com/barrettj12/rust-server/blob/66264365b11db1bf530d5fcdcdbfdade10f7eb5c/src/main.rs" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first thing we need to do is start a TCP listener:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost:0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"listening on {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="nf"&gt;.local_addr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Port 0 doesn't actually exist - it just means that the OS will automatically choose a free port for us. Theoretically, &lt;code&gt;TcpListener::bind&lt;/code&gt; can return an error, so we use the &lt;code&gt;?&lt;/code&gt; operator to propagate the error upwards. We then print the listener's local address to the console so that we know what port was chosen.&lt;/p&gt;

&lt;p&gt;Now, we need to wait for incoming TCP connections on the listener, and handle each one in turn. A simple way to do this is loop over &lt;code&gt;listener.incoming()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="nf"&gt;.incoming&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For each connection, we pass it to a &lt;code&gt;handle&lt;/code&gt; function which is responsible for reading the HTTP request and writing a response. The &lt;code&gt;Ok(())&lt;/code&gt; line should never be reached - it's just needed to make the compiler happy.&lt;/p&gt;

&lt;p&gt;So what does the &lt;code&gt;handle&lt;/code&gt; function look like? The first thing we need to do is read the incoming HTTP request from the stream.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BufReader&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;BufReader&lt;/code&gt; is a buffered reader which allows more efficient reading from the stream. Here we pass in a mutable reference to &lt;code&gt;conn&lt;/code&gt; - this allows the &lt;code&gt;BufReader&lt;/code&gt; to read from the stream without passing ownership of &lt;code&gt;conn&lt;/code&gt; into the &lt;code&gt;BufReader&lt;/code&gt;, because we will need &lt;code&gt;conn&lt;/code&gt; later to write the response.&lt;/p&gt;

&lt;p&gt;Next, we loop over the reader's &lt;code&gt;.lines()&lt;/code&gt; method to read the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line_res&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.lines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line_res&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This is the blank line between headers and body&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are just logging the request to the console using &lt;code&gt;println!&lt;/code&gt;. In reality, we should probably be parsing each line and storing the headers, but in this case, we don't care what the request is, we're just going to return the same response every time. Every HTTP request includes an empty line between the headers and body, so when we reach an empty line, we know that we've read all the headers, so we can break the loop. The next thing to do would be to read the body (using the results of the &lt;code&gt;Content-Length&lt;/code&gt; header), but for this simple example, I chose to just ignore it.&lt;/p&gt;

&lt;p&gt;The next thing to do is to generate the response and write it to the connection. For future extensibility, I chose to represent the response using a struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ResponseParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;http_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reason_phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I defined a utility function that accepts a string and generates a response struct with status code 200 (OK) using that string as the body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;construct_ok_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ResponseParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ResponseParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"1.1"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;reason_phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"OK"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"text/plain"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"Content-Length"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="nf"&gt;.as_bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we have a separate &lt;code&gt;marshal_response&lt;/code&gt; function which accepts a &lt;code&gt;ResponseParams&lt;/code&gt; struct and generates the HTTP response using those params. This basically just uses &lt;code&gt;format!&lt;/code&gt; to generate a string using the parameters.&lt;/p&gt;

&lt;p&gt;Finally, we just need to write the marshalled response to the connection stream:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;marshal_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response_params&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nf"&gt;.as_bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with that, we are done with this connection - we can call &lt;code&gt;Ok(())&lt;/code&gt; to return from the &lt;code&gt;handle&lt;/code&gt; function, and let the server handle the next request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Points of confusion
&lt;/h3&gt;

&lt;p&gt;Writing this server definitely gave me some practical experience with Rust and helped me internalise the concepts I had learned. However, I am still left with a few doubts. For one, there are multiple string types, and I am still a bit confused about whether I should use &lt;code&gt;&amp;amp;str&lt;/code&gt; or &lt;code&gt;String&lt;/code&gt; in a given scenario. (There's another string type as well - &lt;code&gt;&amp;amp;'static str&lt;/code&gt;). Conceptually, I understand the difference (value vs reference type), but it's still tricky to tell which one I should use as an argument to X function, or as the type of a struct field.&lt;/p&gt;

&lt;p&gt;I also found I had to use &lt;code&gt;.to_string()&lt;/code&gt; a lot (e.g. see the &lt;code&gt;construct_ok_response&lt;/code&gt; method above), and I found this to be kind of unsightly. I'm not sure if this is a sign that I'm using the incorrect string type, or if it's just something that I have to accept about using Rust.&lt;/p&gt;

&lt;p&gt;I hope to address these doubts and gain more insight on them as I continue learning Rust.&lt;/p&gt;

&lt;h3&gt;
  
  
  Possible improvements
&lt;/h3&gt;

&lt;p&gt;The HTTP server that I wrote here is extremely simple - there are many improvements I would have to make for it to be production-ready. Since this is just a toy project, it's unlikely that I will actually make these improvements - I'm sure there are already highly-optimised general purpose Rust HTTP server implementations out there, and there's no point reinventing the wheel here. However, I've at least thought of several ways that I could improve it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow specifying the port on the command line via a &lt;code&gt;--port&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;Currently, we process incoming connections sequentially - to improve server capacity, we should make the &lt;code&gt;handle&lt;/code&gt; function async and accept connections concurrently. For example, we could process each incoming connection in a different thread.&lt;/li&gt;
&lt;li&gt;When reading the response, we should actually parse it and extract the request path, method, headers, etc. Furthermore, we should actually read the request body as well. We could put all of this into a &lt;code&gt;Request&lt;/code&gt; struct.&lt;/li&gt;
&lt;li&gt;If we wanted to serve different responses based on the request, we could inspect the generated &lt;code&gt;Request&lt;/code&gt; struct and discriminate e.g. based on the URL path.&lt;/li&gt;
&lt;li&gt;We could define more utility methods to generate different kinds of responses (e.g. 404).&lt;/li&gt;
&lt;li&gt;Error handling could be done more carefully - for simplicity, I just used &lt;code&gt;?&lt;/code&gt; everywhere, but there are certain cases where we should probably be more careful (e.g. not propagating &lt;code&gt;handle&lt;/code&gt; errors for a single connection up to the main loop).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;marshal_response&lt;/code&gt; could be replaced by an implementation of &lt;code&gt;std::fmt::Display&lt;/code&gt; on the &lt;code&gt;ResponseParams&lt;/code&gt; struct - this might be a more idiomatic Rust way of doing it.&lt;/li&gt;
&lt;li&gt;We could implement a "handler registry" pattern, similar to what's done by Go's &lt;code&gt;http.HandleFunc&lt;/code&gt;. At the start, we register various paths and point each one to a separate handler function. Then, when a request comes in, the server matches the request to the registered paths and determines which handler to use.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Well, that just about sums up my first week in Rust - what I learned and what I built. It's definitely quite different to the other languages I'm familiar with, and writing in Rust forces you to think in a different way to e.g. writing in Go. However, I think that's ultimately a good thing, as this leads you to writing programs that are more performant and memory-safe. Overall, I enjoyed the experience, and I'm proud of what I learned in just a few days. I look forward to continuing my Rust journey in the next few weeks, diving into more complex features of Rust and building upon my understanding.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>todayilearned</category>
      <category>programming</category>
      <category>systems</category>
    </item>
  </channel>
</rss>
