mirror of
https://github.com/bspeice/speice.io
synced 2024-11-14 22:18:10 -05:00
187 lines
78 KiB
HTML
187 lines
78 KiB
HTML
|
<!doctype html><html lang=en dir=ltr class="blog-wrapper blog-post-page plugin-blog plugin-id-default" data-has-hydrated=false><meta charset=UTF-8><meta name=generator content="Docusaurus v3.6.0"><title data-rh=true>A Rustic re-podcasting server | The Old Speice Guy</title><meta data-rh=true name=viewport content="width=device-width,initial-scale=1.0"><meta data-rh=true name=twitter:card content=summary_large_image><meta data-rh=true property=og:url content=https://speice.io/2016/10/rustic-repodcasting><meta data-rh=true property=og:locale content=en><meta data-rh=true name=docusaurus_locale content=en><meta data-rh=true name=docusaurus_tag content=default><meta data-rh=true name=docsearch:language content=en><meta data-rh=true name=docsearch:docusaurus_tag content=default><meta data-rh=true property=og:title content="A Rustic re-podcasting server | The Old Speice Guy"><meta data-rh=true name=description content="Learning Rust by fire (it sounds better than learning by corrosion)"><meta data-rh=true property=og:description content="Learning Rust by fire (it sounds better than learning by corrosion)"><meta data-rh=true property=og:type content=article><meta data-rh=true property=article:published_time content=2016-10-22T12:00:00.000Z><link data-rh=true rel=icon href=/img/favicon.ico><link data-rh=true rel=canonical href=https://speice.io/2016/10/rustic-repodcasting><link data-rh=true rel=alternate href=https://speice.io/2016/10/rustic-repodcasting hreflang=en><link data-rh=true rel=alternate href=https://speice.io/2016/10/rustic-repodcasting hreflang=x-default><script data-rh=true type=application/ld+json>{"@context":"https://schema.org","@id":"https://speice.io/2016/10/rustic-repodcasting","@type":"BlogPosting","author":{"@type":"Person","name":"Bradlee Speice"},"dateModified":"2024-11-06T03:32:56.000Z","datePublished":"2016-10-22T12:00:00.000Z","description":"Learning Rust by fire (it sounds better than learning by corrosion)","headline":"A Rustic re-podcasting server","isPartOf":{"@id":"https://speice.io/","@type":"Blog","name":"Blog"},"keywords":[],"mainEntityOfPage":"https://speice.io/2016/10/rustic-repodcasting","name":"A Rustic re-podcasting server","url":"https://speice.io/2016/10/rustic-repodcasting"}</script><link rel=alternate type=application/rss+xml href=/rss.xml title="The Old Speice Guy RSS Feed"><link rel=alternate type=application/atom+xml href=/atom.xml title="The Old Speice Guy Atom Feed"><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css integrity=sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM crossorigin><link rel=stylesheet href=/assets/css/styles.ae6ff4a3.css><script src=/assets/js/runtime~main.751b419d.js defer></script><script src=/assets/js/main.62ce6156.js defer></script><body class=navigation-with-keyboard><script>!function(){var t,e=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();t=null!==e?e:"light",document.documentElement.setAttribute("data-theme",t)}(),function(){try{for(var[t,e]of new URLSearchParams(window.location.search).entries())if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id=__docusaurus><div role=region aria-label="Skip to main content"><a class=skipToContent_fXgn href=#__docusaurus_skipToContent_fallback>Skip to main content</a></div><nav aria-label=Main class="navbar navbar--fixed-top"><div class=navbar__inner><div class=navbar__items><button aria-label="Toggle navigation bar" aria-expanded=false class="navbar__toggle clean-btn" type=button><svg width=30 height=30 viewBox="0 0 30 30" aria-hidden=true><path stroke=currentColor stroke-linecap=round stroke-miterlimit=10 stroke-width=2 d="M4 7h22M4 15h22M4 23h22"/></svg></button><a class=navbar__brand href=/><div class=navbar__logo><img src=/img/logo.svg alt="Sierpinski Gasket" class="themedComponent_mlkZ themedComponent--light_NVdE"><img
|
|||
|
<p>I listen to a lot of Drum and Bass music, because it's beautiful music. And
|
|||
|
there's a particular site, <a href=http://bassdrive.com/ target=_blank rel="noopener noreferrer">Bassdrive.com</a> that hosts
|
|||
|
a lot of great content. Specifically, the
|
|||
|
<a href=http://archives.bassdrivearchive.com/ target=_blank rel="noopener noreferrer">archives</a> section of the site has a
|
|||
|
list of the past shows that you can download and listen to. The issue is, it's
|
|||
|
just a <a href=http://archives.bassdrivearchive.com/6%20-%20Saturday/Electronic%20Warfare%20-%20The%20Overfiend/ target=_blank rel="noopener noreferrer">giant list of links to download</a>. I'd really like
|
|||
|
this in a podcast format to take with me on the road, etc.</p>
|
|||
|
<p>So I wrote the <a href=https://github.com/bspeice/elektricity target=_blank rel="noopener noreferrer">elektricity</a> web
|
|||
|
application to actually accomplish all that. Whenever you request a feed, it
|
|||
|
goes out to Bassdrive, processes all the links on a page, and serves up some
|
|||
|
fresh, tasty RSS to satisfy your ears. I hosted it on Heroku using the free
|
|||
|
tier because it's really not resource-intensive at all.</p>
|
|||
|
<p><strong>The issue so far</strong> is that I keep running out of free tier hours during a
|
|||
|
month because my podcasting application likes to have a server scan for new
|
|||
|
episodes constantly. Not sure why it's doing that, but I don't have a whole
|
|||
|
lot of control over it. It's a phenomenal application otherwise.</p>
|
|||
|
<p><strong>My (over-engineered) solution</strong>: Re-write the application using the
|
|||
|
<a href=https://www.rust-lang.org/en-US/ target=_blank rel="noopener noreferrer">Rust</a> programming language. I'd like to run
|
|||
|
this on a small hacker board I own, and doing this in Rust would allow me to
|
|||
|
easily cross-compile it. Plus, I've been very interested in the Rust language
|
|||
|
for a while and this would be a great opportunity to really learn it well.
|
|||
|
The code is available <a href=https://github.com/bspeice/nutone target=_blank rel="noopener noreferrer">here</a> as development
|
|||
|
progresses.</p>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=the-setup>The Setup<a href=#the-setup class=hash-link aria-label="Direct link to The Setup" title="Direct link to The Setup"></a></h2>
|
|||
|
<p>We'll be using the <a href=http://ironframework.io/ target=_blank rel="noopener noreferrer">iron</a> library to handle the
|
|||
|
server, and <a href=http://hyper.rs/ target=_blank rel="noopener noreferrer">hyper</a> to fetch the data we need from elsewhere
|
|||
|
on the interwebs. <a href=http://doc.servo.org/html5ever/index.html target=_blank rel="noopener noreferrer">HTML5Ever</a> allows
|
|||
|
us to ingest the content that will be coming from Bassdrive, and finally,
|
|||
|
output is done with <a href=http://sunng87.github.io/handlebars-rust/handlebars/index.html target=_blank rel="noopener noreferrer">handlebars-rust</a>.</p>
|
|||
|
<p>It will ultimately be interesting to see how much more work must be done to
|
|||
|
actually get this working over another language like Python. Coming from a
|
|||
|
dynamic state of mind it's super easy to just chain stuff together, ship it out,
|
|||
|
and call it a day. I think I'm going to end up getting much dirtier trying to
|
|||
|
write all of this out.</p>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=issue-1-strings>Issue 1: Strings<a href=#issue-1-strings class=hash-link aria-label="Direct link to Issue 1: Strings" title="Direct link to Issue 1: Strings"></a></h2>
|
|||
|
<p>Strings in Rust are hard. I acknowledge Python can get away with some things
|
|||
|
that make strings super easy (and Python 3 has gotten better at cracking down
|
|||
|
on some bad cases, <code>str <-> bytes</code> specifically), but Rust is hard.</p>
|
|||
|
<p>Let's take for example the <code>404</code> error handler I'm trying to write. The result
|
|||
|
should be incredibly simple: All I want is to echo back
|
|||
|
<code>Didn't find URL: <url></code>. Shouldn't be that hard right? In Python I'd just do
|
|||
|
something like:</p>
|
|||
|
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">def</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">echo_handler</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">request</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"You're visiting: {}"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token builtin" style="color:hsl(119, 34%, 47%)">format</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">request</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">uri</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>And we'd call it a day. Rust isn't so simple. Let's start with the trivial
|
|||
|
examples people post online:</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(221, 87%, 60%)">hello_world</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">-></span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IronResult</span><span class="token operator" style="color:hsl(221, 87%, 60%)"><</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token operator" style="color:hsl(221, 87%, 60%)">></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token function" style="color:hsl(221, 87%, 60%)">with</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token namespace">status</span><span class="token namespace punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"You found the server!"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Doesn't look too bad right? In fact, it's essentially the same as the Python
|
|||
|
version! All we need to do is just send back a string of some form. So, we
|
|||
|
look up the documentation for <a href=http://ironframework.io/doc/iron/request/struct.Request.html target=_blank rel="noopener noreferrer"><code>Request</code></a> and see a <code>url</code> field that will contain
|
|||
|
what we want. Let's try the first iteration:</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(221, 87%, 60%)">hello_world</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">-></span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IronResult</span><span class="token operator" style="color:hsl(221, 87%, 60%)"><</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token operator" style="color:hsl(221, 87%, 60%)">></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token function" style="color:hsl(221, 87%, 60%)">with</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token namespace">status</span><span class="token namespace punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"You found the URL: "</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">url</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Which yields the error:</p>
|
|||
|
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> error[E0369]: binary operation `+` cannot be applied to type `&'static str`</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>OK, what's going on here? Time to start Googling for <a href="https://www.google.com/#q=concatenate+strings+in+rust" target=_blank rel="noopener noreferrer">"concatenate strings in Rust"</a>. That's what we
|
|||
|
want to do right? Concatenate a static string and the URL.</p>
|
|||
|
<p>After Googling, we come across a helpful <a href=https://doc.rust-lang.org/std/macro.concat!.html target=_blank rel="noopener noreferrer"><code>concat!</code></a> macro that looks really nice! Let's try that one:</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(221, 87%, 60%)">hello_world</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">-></span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IronResult</span><span class="token operator" style="color:hsl(221, 87%, 60%)"><</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token operator" style="color:hsl(221, 87%, 60%)">></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token function" style="color:hsl(221, 87%, 60%)">with</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token namespace">status</span><span class="token namespace punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(5, 74%, 59%)">concat!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"You found the URL: "</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">url</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=curre
|
|||
|
<p>And the error:</p>
|
|||
|
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> error: expected a literal</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Turns out Rust actually blows up because the <code>concat!</code> macro expects us to know
|
|||
|
at compile time what <code>req.url</code> is. Which, in my outsider opinion, is a bit
|
|||
|
strange. <code>println!</code> and <code>format!</code>, etc., all handle values they don't know at
|
|||
|
compile time. Why can't <code>concat!</code>? By any means, we need a new plan of attack.
|
|||
|
How about we try formatting strings?</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(221, 87%, 60%)">hello_world</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">-></span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IronResult</span><span class="token operator" style="color:hsl(221, 87%, 60%)"><</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token operator" style="color:hsl(221, 87%, 60%)">></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token function" style="color:hsl(221, 87%, 60%)">with</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token namespace">status</span><span class="token namespace punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(5, 74%, 59%)">format!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"You found the URL: {}"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">url</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=cur
|
|||
|
<p>And at long last, it works. Onwards!</p>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=issue-2-fighting-with-the-borrow-checker>Issue 2: Fighting with the borrow checker<a href=#issue-2-fighting-with-the-borrow-checker class=hash-link aria-label="Direct link to Issue 2: Fighting with the borrow checker" title="Direct link to Issue 2: Fighting with the borrow checker"></a></h2>
|
|||
|
<p>Rust's single coolest feature is how the compiler can guarantee safety in your
|
|||
|
program. As long as you don't use <code>unsafe</code> pointers in Rust, you're guaranteed
|
|||
|
safety. And not having truly manual memory management is really cool; I'm
|
|||
|
totally OK with never having to write <code>malloc()</code> again.</p>
|
|||
|
<p>That said, even <a href=https://doc.rust-lang.org/book/ownership.html target=_blank rel="noopener noreferrer">the Rust documentation</a> makes a specific note:</p>
|
|||
|
<blockquote>
|
|||
|
<p>Many new users to Rust experience something we like to call
|
|||
|
‘fighting with the borrow checker’, where the Rust compiler refuses to
|
|||
|
compile a program that the author thinks is valid.</p>
|
|||
|
</blockquote>
|
|||
|
<p>If you have to put it in the documentation, it's not a helpful note:
|
|||
|
it's hazing.</p>
|
|||
|
<p>So now that we have a handler which works with information from the request, we
|
|||
|
want to start making something that looks like an actual web application.
|
|||
|
The router provided by <code>iron</code> isn't terribly difficult so I won't cover it.
|
|||
|
Instead, the thing that had me stumped for a couple hours was trying to
|
|||
|
dynamically create routes.</p>
|
|||
|
<p>The unfortunate thing with Rust (in my limited experience at the moment) is that
|
|||
|
there is a severe lack of non-trivial examples. Using the router is easy when
|
|||
|
you want to give an example of a static function. But how do you you start
|
|||
|
working on things that are a bit more complex?</p>
|
|||
|
<p>We're going to cover that here. Our first try: creating a function which returns
|
|||
|
other functions. This is a principle called <a href=http://stackoverflow.com/a/36321/1454178 target=_blank rel="noopener noreferrer">currying</a>. We set up a function that allows us to keep some data in scope
|
|||
|
for another function to come later.</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(221, 87%, 60%)">build_handler</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">String</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">-></span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Fn</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">-></span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IronResult</span><span class="token operator" style="color:hsl(221, 87%, 60%)"><</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token operator" style="color:hsl(221, 87%, 60%)">></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(119, 34%, 47%)">|</span><span class="token closure-params">_</span><span class="token closure-params punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token closure-params"> </span><span class="token closure-params operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token closure-params keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token closure-params"> </span><span class="token closure-params class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(119, 34%, 47%)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token function" style="color:hsl(221, 87%, 60%)">with</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token namespace">status</span><span class="token namespace punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="co
|
|||
|
<p>We've simply set up a function that returns another anonymous function with the
|
|||
|
<code>message</code> parameter scoped in. If you compile this, you get not 1, not 2, but 5
|
|||
|
new errors. 4 of them are the same though:</p>
|
|||
|
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> error[E0277]: the trait bound `for<'r, 'r, 'r> std::ops::Fn(&'r mut iron::Request<'r, 'r>) -> std::result::Result<iron::Response, iron::IronError> + 'static: std::marker::Sized` is not satisfied</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>...oookay. I for one, am not going to spend time trying to figure out what's
|
|||
|
going on there.</p>
|
|||
|
<p>And it is here that I will save the audience many hours of frustrated effort.
|
|||
|
At this point, I decided to switch from <code>iron</code> to pure <code>hyper</code> since using
|
|||
|
<code>hyper</code> would give me a much simpler API. All I would have to do is build a
|
|||
|
function that took two parameters as input, and we're done. That said, it
|
|||
|
ultimately posed many more issues because I started getting into a weird fight
|
|||
|
with the <code>'static</code> <a href=https://doc.rust-lang.org/book/lifetimes.html target=_blank rel="noopener noreferrer">lifetime</a>
|
|||
|
and being a Rust newbie I just gave up on trying to understand it.</p>
|
|||
|
<p>Instead, we will abandon (mostly) the curried function attempt, and instead
|
|||
|
take advantage of something Rust actually intends us to use: <code>struct</code> and
|
|||
|
<code>trait</code>.</p>
|
|||
|
<p>Remember when I talked about a lack of non-trivial examples on the Internet?
|
|||
|
This is what I was talking about. I could only find <em>one</em> example of this
|
|||
|
available online, and it was incredibly complex and contained code we honestly
|
|||
|
don't need or care about. There was no documentation of how to build routes that
|
|||
|
didn't use static functions, etc. But, I'm assuming you don't really care about
|
|||
|
my whining, so let's get to it.</p>
|
|||
|
<p>The <code>iron</code> documentation mentions the <a href=http://ironframework.io/doc/iron/middleware/trait.Handler.html target=_blank rel="noopener noreferrer"><code>Handler</code></a> trait as being something we can implement.
|
|||
|
Does the function signature for that <code>handle()</code> method look familiar? It's what
|
|||
|
we've been working with so far.</p>
|
|||
|
<p>The principle is that we need to define a new <code>struct</code> to hold our data, then
|
|||
|
implement that <code>handle()</code> method to return the result. Something that looks
|
|||
|
like this might do:</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(35, 99%, 36%)">EchoHandler</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> message</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">String</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain" style=display:inline-block></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Handler</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">EchoHandler</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(221, 87%, 60%)">handle</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">self</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> _</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">-></span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IronResult</span><span class="token operator" style="color:hsl(221, 87%, 60%)"><</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token operator" style="color:hsl(221, 87%, 60%)">></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)"
|
|||
|
<p>We attempt to build a struct, and give its <code>handle</code> method off to the router
|
|||
|
so the router knows what to do.</p>
|
|||
|
<p>You guessed it, more errors:</p>
|
|||
|
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> error: attempted to take value of method `handle` on type `EchoHandler`</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Now, the Rust compiler is actually a really nice fellow, and offers us help:</p>
|
|||
|
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> help: maybe a `()` to call it is missing? If not, try an anonymous function</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>We definitely don't want to call that function, so maybe try an anonymous
|
|||
|
function as it recommends?</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain">router</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">get</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"/"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(119, 34%, 47%)">|</span><span class="token closure-params">req</span><span class="token closure-params punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token closure-params"> </span><span class="token closure-params operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token closure-params keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token closure-params"> </span><span class="token closure-params class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(119, 34%, 47%)">|</span><span class="token plain"> echo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">handle</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"index"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Another error:</p>
|
|||
|
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> error[E0373]: closure may outlive the current function, but it borrows `echo`, which is owned by the current function</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Another helpful message:</p>
|
|||
|
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> help: to force the closure to take ownership of `echo` (and any other referenced variables), use the `move` keyword</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>We're getting closer though! Let's implement this change:</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain">router</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">get</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"/"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(119, 34%, 47%)">|</span><span class="token closure-params">req</span><span class="token closure-params punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token closure-params"> </span><span class="token closure-params operator" style="color:hsl(221, 87%, 60%)">&</span><span class="token closure-params keyword" style="color:hsl(301, 63%, 40%)">mut</span><span class="token closure-params"> </span><span class="token closure-params class-name" style="color:hsl(35, 99%, 36%)">Request</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(119, 34%, 47%)">|</span><span class="token plain"> echo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">handle</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"index"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>And here's where things get strange:</p>
|
|||
|
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> error[E0507]: cannot move out of borrowed content</span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> --> src/main.rs:18:40</span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> |</span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> 18 | Ok(Response::with((status::Ok, self.message)))</span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> | ^^^^ cannot move out of borrowed content</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Now, this took me another couple hours to figure out. I'm going to explain it,
|
|||
|
but <strong>keep this in mind: Rust only allows one reference at a time</strong> (exceptions
|
|||
|
apply of course).</p>
|
|||
|
<p>When we attempt to use <code>self.message</code> as it has been created in the earlier
|
|||
|
<code>struct</code>, we essentially are trying to give it away to another piece of code.
|
|||
|
Rust's semantics then state that <em>we may no longer access it</em> unless it is
|
|||
|
returned to us (which <code>iron</code>'s code does not do). There are two ways to fix
|
|||
|
this:</p>
|
|||
|
<ol>
|
|||
|
<li>Only give away references (i.e. <code>&self.message</code> instead of <code>self.message</code>)
|
|||
|
instead of transferring ownership</li>
|
|||
|
<li>Make a copy of the underlying value which will be safe to give away</li>
|
|||
|
</ol>
|
|||
|
<p>I didn't know these were the two options originally, so I hope this helps the
|
|||
|
audience out. Because <code>iron</code> won't accept a reference, we are forced into the
|
|||
|
second option: making a copy. To do so, we just need to change the function
|
|||
|
to look like this:</p>
|
|||
|
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Response</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token function" style="color:hsl(221, 87%, 60%)">with</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token namespace">status</span><span class="token namespace punctuation" style="color:hsl(119, 34%, 47%)">::</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Ok</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">self</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">clone</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Not so bad, huh? My only complaint is that it took so long to figure out exactly
|
|||
|
what was going on.</p>
|
|||
|
<p>And now we have a small server that we can configure dynamically. At long last.</p>
|
|||
|
<blockquote>
|
|||
|
<p>Final sidenote: You can actually do this without anonymous functions. Just
|
|||
|
change the router line to:
|
|||
|
<code>router.get("/", echo, "index");</code></p>
|
|||
|
<p>Rust's type system seems to figure out that we want to use the <code>handle()</code> method.</p>
|
|||
|
</blockquote>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=conclusion>Conclusion<a href=#conclusion class=hash-link aria-label="Direct link to Conclusion" title="Direct link to Conclusion"></a></h2>
|
|||
|
<p>After a good long days' work, we now have the routing functionality set up on
|
|||
|
our application. We should be able to scale this pretty well in the future:
|
|||
|
the RSS content we need to deliver in the future can be treated as a string, so
|
|||
|
the building blocks are in place.</p>
|
|||
|
<p>There are two important things I learned starting with Rust today:</p>
|
|||
|
<ol>
|
|||
|
<li>Rust is a new language, and while the code is high-quality, the mindshare is coming.</li>
|
|||
|
<li>I'm a terrible programmer.</li>
|
|||
|
</ol>
|
|||
|
<p>Number 1 is pretty obvious and not surprising to anyone. Number two caught me
|
|||
|
off guard. I've gotten used to having either a garbage collector (Java, Python,
|
|||
|
etc.) or playing a little fast and loose with scoping rules (C, C++). You don't
|
|||
|
have to worry about object lifetime there. With Rust, it's forcing me to fully
|
|||
|
understand and use well the memory in my applications. In the final mistake I
|
|||
|
fixed (using <code>.clone()</code>) I would have been fine in C++ to just give away that
|
|||
|
reference and never use it again. I wouldn't have run into a "use-after-free"
|
|||
|
error, but I would have potentially been leaking memory. Rust forced me to be
|
|||
|
incredibly precise about how I use it.</p>
|
|||
|
<p>All said I'm excited for using Rust more. I think it's super cool, it's just
|
|||
|
going to take me a lot longer to do this than I originally thought.</div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Blog post page navigation"><a class="pagination-nav__link pagination-nav__link--prev" href=/2016/06/event-studies-and-earnings-releases><div class=pagination-nav__sublabel>Older post</div><div class=pagination-nav__label>Event studies and earnings releases</div></a><a class="pagination-nav__link pagination-nav__link--next" href=/2016/11/pca-audio-compression><div class=pagination-nav__sublabel>Newer post</div><div class=pagination-nav__label>PCA audio compression</div></a></nav></main><div class="col col--2"><div class="tableOfContents_bqdL thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href=#the-setup class="table-of-contents__link toc-highlight">The Setup</a><li><a href=#issue-1-strings class="table-of-contents__link toc-highlight">Issue 1: Strings</a><li><a href=#issue-2-fighting-with-the-borrow-checker class="table-of-contents__link toc-highlight">Issue 2: Fighting with the borrow checker</a><li><a href=#conclusion class="table-of-contents__link toc-highlight">Conclusion</a></ul></div></div></div></div></div><footer class=footer><div class="container container-fluid"><div class="footer__bottom text--center"><div class=footer__copyright>Copyright © 2024 Bradlee Speice</div></div></div></footer></div>
|