<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Michael-F-Bryan</title>
    <link>https://adventures.michaelfbryan.com/</link>
    <description>Recent content on Michael-F-Bryan</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Mon, 28 Jul 2025 18:28:01 +0800</lastBuildDate>
    <atom:link href="https://adventures.michaelfbryan.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Obsidian Tricks: Daily Notes</title>
      <link>https://adventures.michaelfbryan.com/posts/obsidian-tricks/daily-notes/</link>
      <pubDate>Mon, 28 Jul 2025 12:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/obsidian-tricks/daily-notes/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;re new to Personal Knowledge Management, let me share something that took me years to fully appreciate: &lt;strong&gt;daily notes are the secret sauce that transforms a collection of random notes into a living, breathing knowledge system&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s the thing most people miss when they start with PKM—it&amp;rsquo;s not about having perfect notes, it&amp;rsquo;s about &lt;strong&gt;connecting your notes to real moments in time&lt;/strong&gt;. Daily notes do exactly that. They&amp;rsquo;re like having a personal assistant who remembers not just what happened, but &lt;strong&gt;when&lt;/strong&gt; it happened and &lt;strong&gt;who&lt;/strong&gt; was involved.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Obsidian Tricks: Entity Notes</title>
      <link>https://adventures.michaelfbryan.com/posts/obsidian-tricks/entity-notes/</link>
      <pubDate>Wed, 23 Jul 2025 12:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/obsidian-tricks/entity-notes/</guid>
      <description>&lt;p&gt;An entity is a person, place, or organization that you want to track in your &lt;em&gt;Second Brain&lt;/em&gt;. By creating separate notes in your &lt;em&gt;Obsidian&lt;/em&gt; vault for each entity and using the power of backlinks, you can create a rich, interconnected knowledge base.&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-power-of-backlinks&#34;&gt;&#xA;  The Power of Backlinks&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#the-power-of-backlinks&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h3&gt;&#xA;&lt;p&gt;When you create a dedicated note for an entity like &lt;code&gt;[[Michael Bryan]]&lt;/code&gt; or &lt;code&gt;[[Wasmer]]&lt;/code&gt;, every time you mention that entity in any other note, Obsidian automatically creates a backlink. This creates a &lt;strong&gt;dynamic, interconnected web of knowledge&lt;/strong&gt; that reveals patterns and connections you might not have noticed otherwise.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Obsidian Tricks: The Summary Callout</title>
      <link>https://adventures.michaelfbryan.com/posts/obsidian-tricks/summary-callout/</link>
      <pubDate>Sat, 19 Jul 2025 22:36:07 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/obsidian-tricks/summary-callout/</guid>
      <description>&lt;div class=&#34;notices note&#34; &gt;&#xA;    &lt;p&gt;The &lt;a href=&#34;https://help.obsidian.md/callouts#Supported&amp;#43;types&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;[!summary]&lt;/code&gt; callout&lt;/a&gt; is a crucial component of an &lt;em&gt;Atomic Note&lt;/em&gt;, serving as a concise overview that captures the essence of the note&amp;rsquo;s content. This section at the beginning of each note helps readers quickly grasp the main concept and decide whether to read further.&lt;/p&gt;&#xA;&lt;p&gt;Feel free to use this article as a prompt to generate your own summary callout 😉&lt;/p&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;purpose-and-structure&#34;&gt;&#xA;  Purpose and Structure&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#purpose-and-structure&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Quick Overview:&lt;/strong&gt; Provides readers with essential information without requiring them to read the entire note&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Placement:&lt;/strong&gt; Always at the top of the note, after &lt;em&gt;Front Matter&lt;/em&gt; (if present)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Format:&lt;/strong&gt; Uses the blockquote syntax with callout type: &lt;code&gt;&amp;gt; [!summary]&lt;/code&gt; (variations like &lt;code&gt;[!SUMMARY]&lt;/code&gt; or &lt;code&gt;[!Summary]&lt;/code&gt; are acceptable)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Length:&lt;/strong&gt; Typically 1-3 sentences or 3-5 bullet points for complex topics&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;content-guidelines&#34;&gt;&#xA;  Content Guidelines&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#content-guidelines&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Focus:&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Capture the core idea without including supporting details&lt;/li&gt;&#xA;&lt;li&gt;Answer &amp;ldquo;What is it?&amp;rdquo; and &amp;ldquo;Why is it important?&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;Include key relationships to other concepts when relevant&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Style:&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Clear, direct, and professional tone&lt;/li&gt;&#xA;&lt;li&gt;Active voice and present tense&lt;/li&gt;&#xA;&lt;li&gt;Avoid jargon unless essential to the concept&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Links:&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Include essential &lt;code&gt;[[wiki-links]]&lt;/code&gt; to related core concepts&lt;/li&gt;&#xA;&lt;li&gt;Don&amp;rsquo;t overload with links - only the most relevant ones&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Formatting:&lt;/strong&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Use emphasis (&lt;em&gt;italics&lt;/em&gt; or &lt;strong&gt;bold&lt;/strong&gt;) for critical terms&lt;/li&gt;&#xA;&lt;li&gt;Include code snippets in backticks for technical terms&lt;/li&gt;&#xA;&lt;li&gt;Break complex summaries into bullet points for readability&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;context-specific-patterns&#34;&gt;&#xA;  Context-Specific Patterns&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#context-specific-patterns&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;technical-concepts&#34;&gt;&#xA;  Technical Concepts&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#technical-concepts&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;aliases: Access Tokens&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;[!SUMMARY]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;A token, typically in the [[JSON Web Tokens|JWT]] format, issued by a server&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;when the user logs in that lets users make secure calls to an API server.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User tokens can be used by client applications to access protected resources on&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;a server on behalf of a user.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anyone that holds an access token can use it. As such, you need a way to&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;minimize the fallout from a compromised access token. One method is to issue&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tokens that have a short lifespan.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Here is an example access token that might be issued by [[Auth0]]:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;```json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&lt;/span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;iss&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://YOUR_DOMAIN/&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;sub&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;auth0|123456&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;aud&amp;#34;&lt;/span&gt;: [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;my-api-identifier&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://YOUR_DOMAIN/userinfo&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;azp&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;YOUR_CLIENT_ID&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;exp&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1489179954&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;iat&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1489143954&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scope&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;openid profile email address phone read:appointments&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;```&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;entities&#34;&gt;&#xA;  Entities&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#entities&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h3&gt;&#xA;&lt;p&gt;From my note on &lt;em&gt;Anduril Industries&lt;/em&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing Technical Content That Actually Helps People</title>
      <link>https://adventures.michaelfbryan.com/posts/writing-technical-content/</link>
      <pubDate>Wed, 16 Jul 2025 10:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/writing-technical-content/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been writing technical content for years, and I&amp;rsquo;ll be honest - I never really thought about &lt;em&gt;how&lt;/em&gt; I was writing it. I just wrote the way I think and communicate naturally. Kind of like a stream-of-consciousness documentary of my problem-solving process.&lt;/p&gt;&#xA;&lt;p&gt;Then I started getting feedback that surprised me. People would say things like &amp;ldquo;Your explanations actually make sense&amp;rdquo; or &amp;ldquo;I finally understand this concept after reading your article.&amp;rdquo; At first, I figured they were just being nice. But it kept happening.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How I Work</title>
      <link>https://adventures.michaelfbryan.com/posts/how-i-work/</link>
      <pubDate>Mon, 14 Jul 2025 12:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/how-i-work/</guid>
      <description>&lt;p&gt;I thought it might be helpful to write down some of the core principles and values that guide my professional life. If you are a colleague, friend, potential employer, or just curious, this might be a good place to start.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;notices tip&#34; &gt;&#xA;    &lt;p&gt;Give me ownership, trust my judgement, keep communication open, and let me focus on building things properly.&lt;/p&gt;&#xA;&lt;p&gt;In return, you’ll get high-quality work, honest feedback, and a teammate who’ll go the extra mile when it matters.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Link Time Dependency Injection</title>
      <link>https://adventures.michaelfbryan.com/posts/the-linker-trick/</link>
      <pubDate>Sun, 30 Mar 2025 12:59:58 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/the-linker-trick/</guid>
      <description>&lt;p&gt;Have you ever been in a situation where, because of how the code is structured, it&amp;rsquo;s practically impossible to inject a dependency into the component that needs it? Even global variables - ubiquitously reviled for their ability to do &amp;ldquo;spooky action at a distance&amp;rdquo; - weren&amp;rsquo;t spooky enough.&lt;/p&gt;&#xA;&lt;p&gt;In this article, I&amp;rsquo;ll share a technique I discovered while working on a WebAssembly-based CAD package that allows for dependency injection at link time. This technique is particularly useful when traditional dependency injection methods aren&amp;rsquo;t available or practical.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reboot Friendly Projects - Building Systems That Let You Disappear (and Come Back)</title>
      <link>https://adventures.michaelfbryan.com/posts/reboot-friendly-projects/</link>
      <pubDate>Sat, 29 Mar 2025 12:59:58 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/reboot-friendly-projects/</guid>
      <description>&lt;p&gt;You get an idea. You get excited. You start building.&lt;/p&gt;&#xA;&lt;p&gt;Then one day — you stop.&lt;/p&gt;&#xA;&lt;p&gt;No dramatic reason. No catastrophic failure. Just&amp;hellip; gone. You forget about it. Or you can&amp;rsquo;t bear to look at it. Or you move on. And when you do want to come back, you can&amp;rsquo;t remember what anything meant or why you even cared.&lt;/p&gt;&#xA;&lt;p&gt;This isn&amp;rsquo;t a lack of discipline. It&amp;rsquo;s just a natural part of working on long-term or creative projects.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Embracing a New Chapter: My Farewell to Wasmer and the Journey Ahead</title>
      <link>https://adventures.michaelfbryan.com/posts/farewell-wasmer/</link>
      <pubDate>Tue, 30 Jan 2024 17:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/farewell-wasmer/</guid>
      <description>&lt;h2 id=&#34;introduction&#34;&gt;&#xA;  Introduction&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#introduction&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;My journey at Wasmer has been a profound chapter in my life, filled with both incredible achievements and challenging moments. It&amp;rsquo;s time for me to share an important decision about my career and the path I&amp;rsquo;m choosing to embark on.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-journey-at-wasmer&#34;&gt;&#xA;  The Journey at Wasmer&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#the-journey-at-wasmer&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Wasmer, though a small company, has enabled us to achieve some pretty impressive feats together.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GitHub Actions can&#39;t access private repos? Here&#39;s how to fix it</title>
      <link>https://adventures.michaelfbryan.com/posts/configuring-cargo-auth-in-github-actions/</link>
      <pubDate>Tue, 13 Sep 2022 12:01:45 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/configuring-cargo-auth-in-github-actions/</guid>
      <description>&lt;p&gt;When developing locally, you can add a private GitHub repository to your Rust&#xA;crate as a &lt;a href=&#34;https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-dependencies-from-git-repositories&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;git&lt;/code&gt; dependency&lt;/a&gt; and &lt;code&gt;cargo&lt;/code&gt; should be able to retrieve it&#xA;just fine.&lt;/p&gt;&#xA;&lt;p&gt;However, when you push your changes to GitHub and run CI, GitHub Actions can&#xA;run into authentication issues when trying to build your crate.&lt;/p&gt;&#xA;&lt;p&gt;This is the error message I was fighting for a good part of today:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cargo check --workspace --verbose --locked&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Updating git repository &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;https://github.com/Michael-F-Bryan/my-secret-repo.git&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Running &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;git fetch --force --update-head-ok &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://github.com/Michael-F-Bryan/my-secret-repo.git&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;+HEAD:refs/remotes/origin/HEAD&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Error: failed to get &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;internal-crate&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt; as a dependency of package &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;some-crate v0.1.4 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;/home/runner/work/some-crate/some-crate/crates/cli&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Caused by:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; failed to load source &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; dependency &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;internal-crate&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Caused by:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; Unable to update https://github.com/Michael-F-Bryan/my-secret-repo.git&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Caused by:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; failed to clone into: /home/runner/.cargo/git/db/my-secret-repo-20c1af0756e23bf7&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Caused by:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; process didn&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;t exit successfully: `git fetch --force --update-head-ok &amp;#39;&lt;/span&gt;https://github.com/Michael-F-Bryan/my-secret-repo.git&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt;+HEAD:refs/remotes/origin/HEAD&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;` (exit status: 128)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; --- stderr&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; fatal: could not read Username for &amp;#39;&lt;/span&gt;https://github.com&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;: No such device or address&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Error: The process &amp;#39;&lt;/span&gt;/home/runner/.cargo/bin/cargo&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;&lt;/span&gt; failed with exit code &lt;span style=&#34;color:#ae81ff&#34;&gt;101&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cargo can&amp;rsquo;t check out my private repository!&lt;/p&gt;</description>
    </item>
    <item>
      <title>Announcing Cargo WAPM</title>
      <link>https://adventures.michaelfbryan.com/posts/announcing-cargo-wapm/</link>
      <pubDate>Sun, 07 Aug 2022 16:14:07 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/announcing-cargo-wapm/</guid>
      <description>&lt;p&gt;While at Hammer of the Gods, we wrote &lt;em&gt;a lot&lt;/em&gt; of Rust code that gets compiled to&#xA;WebAssembly for use in our containerization technology, Rune.&lt;/p&gt;&#xA;&lt;p&gt;We have over 30 different processing blocks (chunks of code that can be used in&#xA;a data processing pipeline) and as you can imagine, publishing and versioning&#xA;each of WebAssembly module manually isn&amp;rsquo;t practical. For that, we lean on the&#xA;&lt;a href=&#34;https://wapm.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;WebAssembly Package Manager&lt;/a&gt; to do all the heavy lifting.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bringing include_dir Into the Modern Era</title>
      <link>https://adventures.michaelfbryan.com/posts/bringing-include_dir-into-the-modern-era/</link>
      <pubDate>Thu, 06 Jan 2022 09:57:09 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/bringing-include_dir-into-the-modern-era/</guid>
      <description>&lt;p&gt;Way back in mid-2017 I created &lt;a href=&#34;https://crates.io/crates/include-dir&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;a crate called &lt;code&gt;include_dir&lt;/code&gt;&lt;/a&gt; with&#xA;a single goal in mind - give users an &lt;code&gt;include_dir!()&lt;/code&gt; macro that lets them&#xA;embed an entire directory in their binary.&lt;/p&gt;&#xA;&lt;p&gt;By most metrics, we&amp;rsquo;ve been doing phenomenally well. The crate has received a&#xA;fair amount of engagement on GitHub via pull requests and issues, and it has had&#xA;over 1 million downloads and 127 direct dependents published to crates.io alone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Common Newbie Mistakes and Bad Practices in Rust: Bad Habits</title>
      <link>https://adventures.michaelfbryan.com/posts/rust-best-practices/bad-habits/</link>
      <pubDate>Mon, 27 Sep 2021 18:30:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/rust-best-practices/bad-habits/</guid>
      <description>&lt;p&gt;When you are coming to Rust from another language you bring all your previous&#xA;experiences with you.&lt;/p&gt;&#xA;&lt;p&gt;Often this is awesome because it means you aren&amp;rsquo;t learning programming from&#xA;scratch! However, you can also bring along bad habits which can lead you down&#xA;the wrong rabbit hole or make you write bad code.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;notices note&#34; &gt;&#xA;    &lt;p&gt;The code written in this article is available on the Rust Playground using the&#xA;various &lt;a href=&#34;https://play.rust-lang.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;(playground)&lt;/a&gt; links dotted throughout. Feel free to browse&#xA;through and steal code or inspiration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Daily Rust: Iterators</title>
      <link>https://adventures.michaelfbryan.com/posts/daily/iterators/</link>
      <pubDate>Tue, 24 Aug 2021 03:55:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/daily/iterators/</guid>
      <description>&lt;p&gt;Iterators are part of Rust&amp;rsquo;s secret sauce. They power things from the humble&#xA;for-loop to the elegant iterator chain, but have you ever stopped to think how&#xA;they work?&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s find out more about Rust&amp;rsquo;s iterators by implementing our own versions of&#xA;common iterators and reading the standard library&amp;rsquo;s source code.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;notices info&#34; &gt;&#xA;    &lt;p&gt;The code written in this article is available on the Rust Playground using the&#xA;various &lt;a href=&#34;https://play.rust-lang.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;(playground)&lt;/a&gt; links dotted throughout. Feel free to browse&#xA;through and steal code or inspiration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Daily Rust: Slice Patterns</title>
      <link>https://adventures.michaelfbryan.com/posts/daily/slice-patterns/</link>
      <pubDate>Sat, 14 Aug 2021 00:00:00 +0000</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/daily/slice-patterns/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://blog.rust-lang.org/2018/05/10/Rust-1.26.html#basic-slice-patterns&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Rust 1.26&lt;/a&gt; introduced a nifty little feature called &lt;em&gt;Basic Slice&#xA;Patterns&lt;/em&gt; which lets you pattern match on slices with a known length. Later on&#xA;in &lt;a href=&#34;https://blog.rust-lang.org/2020/03/12/Rust-1.42.html#subslice-patterns&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Rust 1.42&lt;/a&gt;, this was extended to allow using &lt;code&gt;..&lt;/code&gt; to match on&#xA;&amp;ldquo;everything else&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;As features go this may seem like a small addition, but it gives developers an&#xA;opportunity to write much more expressive code.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;notices note&#34; &gt;&#xA;    &lt;p&gt;The code written in this article is available in the various playground links&#xA;dotted throughout. Feel free to browse through and steal code or inspiration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deserializing Binary Data Files in Rust</title>
      <link>https://adventures.michaelfbryan.com/posts/deserializing-binary-data-files/</link>
      <pubDate>Sun, 20 Jun 2021 00:30:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/deserializing-binary-data-files/</guid>
      <description>&lt;p&gt;The other day, someone on the Rust user forums posted &lt;a href=&#34;https://users.rust-lang.org/t/deserializing-a-dat-binary-file-created-in-cpp/61263&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;a question&lt;/a&gt;&#xA;that really nerd-sniped me. They had data generated by a C++ program and were&#xA;wanting to load it into a Rust program, but when asked what format the data was&#xA;in the author didn&amp;rsquo;t provide some something like a JSON schema or Protobuf file,&#xA;instead they just got the definition for a C struct.&lt;/p&gt;&#xA;&lt;p&gt;A common method for &amp;ldquo;serializing&amp;rdquo; data in C is to create a struct and directly&#xA;write its bytes into a file, the &amp;ldquo;deserializing&amp;rdquo; is just a case of reading the&#xA;data out of the file and interpreting it as your type. This technique is&#xA;actually kinda genius when you think about it, it makes no intermediate copies&#xA;or heap allocations because the OS&amp;rsquo;s &lt;code&gt;read()&lt;/code&gt; function will literally write your&#xA;data to its destination, and there are no extra dependencies or complicated&#xA;serialization frameworks involved.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Parsing PDF Documents in Rust</title>
      <link>https://adventures.michaelfbryan.com/posts/parsing-pdfs-in-rust/</link>
      <pubDate>Sun, 31 Jan 2021 21:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/parsing-pdfs-in-rust/</guid>
      <description>&lt;p&gt;In my spare time I&amp;rsquo;m a volunteer with my state&amp;rsquo;s emergency services and we&#xA;have our own web app for managing unit-specific things like attendance, vehicle&#xA;checks, newsletters, on-call rosters, and so on.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s actually a really useful tool, but there is one feature that really&#xA;annoys me&amp;hellip; The list of member contact details is only available as a PDF&#xA;and not a format that can be imported into your phone&amp;rsquo;s contacts.&lt;/p&gt;</description>
    </item>
    <item>
      <title>FFI-Safe Polymorphism: Thin Trait Objects</title>
      <link>https://adventures.michaelfbryan.com/posts/ffi-safe-polymorphism-in-rust/</link>
      <pubDate>Wed, 16 Dec 2020 02:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/ffi-safe-polymorphism-in-rust/</guid>
      <description>&lt;p&gt;A while ago someone &lt;a href=&#34;https://users.rust-lang.org/t/ffi-c-file-and-good-rust-wrapper-equivalent-type/52050&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;posted a question&lt;/a&gt; on the Rust User Forums&#xA;asking how to achieve polymorphism in a C API and while lots of good&#xA;suggestions were made, I&amp;rsquo;d like to explore my take on things.&lt;/p&gt;&#xA;&lt;p&gt;As a recap, Rust provides two mechanisms for letting you write code which will&#xA;work with multiple types. These are&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Static Dispatch&lt;/strong&gt;, where the compiler will generate multiple copies of the&#xA;function, tailor-made for each type and resolved at compile time, and&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Dynamic Dispatch&lt;/strong&gt;, where we use an extra level of indirection to only&#xA;resolve the actual implementation at runtime&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;While both mechanisms are extremely powerful and can cover almost all of your&#xA;needs in normal Rust code, they both have one drawback&amp;hellip; The actual&#xA;mechanisms used are (deliberately) unspecified and not safe for FFI.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How I Translate Feature Requests into Code</title>
      <link>https://adventures.michaelfbryan.com/posts/turning-feature-requests-into-code/</link>
      <pubDate>Wed, 02 Dec 2020 16:10:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/turning-feature-requests-into-code/</guid>
      <description>&lt;p&gt;As part of my previous job I worked on a CAD/CAM package, and a very common&#xA;task would be to take a vague feature description, rephrase it as a more&#xA;formal software problem, then use computational geometry algorithms to turn&#xA;it into code which can be integrated into the overall application.&lt;/p&gt;&#xA;&lt;p&gt;I eventually got quite good at this, so I&amp;rsquo;m going to write down the system I&#xA;came up with. This process works especially well for larger features which&#xA;add new functionality with minimal coupling to existing code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Geometric Constraint Solvers Part 1: Algebraic Expressions</title>
      <link>https://adventures.michaelfbryan.com/posts/constraints-part-1-expressions/</link>
      <pubDate>Wed, 15 Jul 2020 00:40:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/constraints-part-1-expressions/</guid>
      <description>&lt;p&gt;A really powerful tool in Computer Aided Design (CAD) is the ability to apply&#xA;&lt;em&gt;&amp;ldquo;constraints&amp;rdquo;&lt;/em&gt; to your drawing. Constraints are a really powerful tool,&#xA;allowing the drafter to declare how parts of their drawing are related, then&#xA;letting the CAD program figure out how parameters can be manipulated in such&#xA;a way that&lt;/p&gt;&#xA;&lt;p&gt;You can think of a constraint as some sort of mathematical relationship between&#xA;two or more parameters.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing Non-Trivial Macros in Rust</title>
      <link>https://adventures.michaelfbryan.com/posts/non-trivial-macros/</link>
      <pubDate>Sun, 21 Jun 2020 01:15:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/non-trivial-macros/</guid>
      <description>&lt;p&gt;Macros in Rust tend to have a reputation for being complex and magical, the&#xA;likes which only seasoned wizards like &lt;a href=&#34;https://github.com/dtolnay&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;@dtolnay&lt;/code&gt;&lt;/a&gt; can hope to&#xA;understand, let alone master.&lt;/p&gt;&#xA;&lt;p&gt;Rust&amp;rsquo;s declarative macros provide a mechanism for pattern matching on&#xA;arbitrary syntax to generate valid Rust code at compile time. I use them all&#xA;the time for simple search/replace style operations like generating tests&#xA;that have a lot of boilerplate, or straightforward trait implementations for&#xA;a large number of types.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rust Closures in FFI</title>
      <link>https://adventures.michaelfbryan.com/posts/rust-closures-in-ffi/</link>
      <pubDate>Tue, 12 May 2020 22:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/rust-closures-in-ffi/</guid>
      <description>&lt;p&gt;Every now and then when using native libraries from Rust you&amp;rsquo;ll be asked to&#xA;pass a callback across the FFI boundary. The reasons are varied, but often&#xA;this might be done to notify the caller when &amp;ldquo;interesting&amp;rdquo; things happen, for&#xA;injecting logic (see the &lt;a href=&#34;https://sourcemaking.com/design_patterns/strategy&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Strategy Pattern&lt;/a&gt;), or to handle the&#xA;result of an asynchronous operation.&lt;/p&gt;&#xA;&lt;p&gt;If this were normal Rust, we&amp;rsquo;d just accept a closure (e.g. a&#xA;&lt;code&gt;Box&amp;lt;dyn Fn(...)&amp;gt;&lt;/code&gt; or by being generic over any function-like type) and be&#xA;done with it. However, when working with other languages you are reduced to&#xA;the lowest common denominator, a the C language (or more specifically, the&#xA;ABI and machine code in general) doesn&amp;rsquo;t understand generics or Rust&amp;rsquo;s &amp;ldquo;fat&amp;rdquo;&#xA;pointers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creating a Robust, Reusable Link-Checker</title>
      <link>https://adventures.michaelfbryan.com/posts/linkchecker/</link>
      <pubDate>Sat, 02 May 2020 19:20:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/linkchecker/</guid>
      <description>&lt;p&gt;With over 68,842 downloads, one of my most successful Rust projects is a&#xA;nondescript little program called &lt;a href=&#34;https://github.com/Michael-F-Bryan/mdbook-linkcheck&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;mdbook-linkcheck&lt;/a&gt;. This&#xA;is a link-checker for &lt;a href=&#34;https://github.com/rust-lang/mdBook&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;mdbook&lt;/a&gt;, the tool powering a lot of&#xA;documentation in the Rust community, including &lt;a href=&#34;https://doc.rust-lang.org/book/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;em&gt;The Rust Programming&#xA;Language&lt;/em&gt;&lt;/a&gt; and &lt;a href=&#34;https://rustc-dev-guide.rust-lang.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;em&gt;The Rustc Dev Book&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;As an example of what it looks like, I recently found &lt;a href=&#34;https://github.com/rust-lang/chalk/pull/408/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;a couple&lt;/a&gt;&#xA;broken links in &lt;a href=&#34;https://rust-lang.github.io/chalk/book/html/index.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;the documentation&lt;/a&gt; for Chalk. When the tool&#xA;detects broken links in your markdown it&amp;rsquo;ll emit error messages that point&#xA;you at the place the link is defined and explain what the issue is.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How I Reverse Engineered the LastPass CLI Tool</title>
      <link>https://adventures.michaelfbryan.com/posts/lastpass/</link>
      <pubDate>Tue, 14 Apr 2020 22:40:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/lastpass/</guid>
      <description>&lt;p&gt;A couple days ago I was writing an install script for &lt;a href=&#34;https://github.com/Michael-F-Bryan/dotfiles&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;my dotfiles&lt;/a&gt;&#xA;and reached a point where I wanted to grab some secrets (my SSH keys) from my&#xA;LastPass vault and copy them to the file system.&lt;/p&gt;&#xA;&lt;p&gt;This is easy enough to do using the browser plugin, or even when working with&#xA;their &lt;a href=&#34;https://github.com/lastpass/lastpass-cli&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;command line tool (&lt;code&gt;lpass&lt;/code&gt;)&lt;/a&gt; in an interactive way, but&#xA;I found there was no way to ask &lt;code&gt;lpass&lt;/code&gt; which files are attached to a secret,&#xA;and get the output in a machine readable format.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reflections on What Motivates a Person</title>
      <link>https://adventures.michaelfbryan.com/posts/motivation/</link>
      <pubDate>Sun, 05 Apr 2020 19:15:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/motivation/</guid>
      <description>&lt;p&gt;Motivation is a funny thing.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m someone who&amp;rsquo;s productivity levels change wildly depending on my&#xA;motivation levels. When I work on something which I&amp;rsquo;m passionate about or&#xA;which interests me on an intellectual level (e.g. computational geometry or&#xA;systems programming), I&amp;rsquo;m routinely 5-10x more productive than my peers.&lt;/p&gt;&#xA;&lt;p&gt;However, if I&amp;rsquo;m working on something which is less personally interesting&#xA;(e.g. tracking down GUI bugs or creating yet another CRUD app) I&amp;rsquo;ll tend to&#xA;drag my feet and not work as hard.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Line Simplification with Ramer–Douglas–Peucker</title>
      <link>https://adventures.michaelfbryan.com/posts/line-simplification/</link>
      <pubDate>Sun, 23 Feb 2020 21:56:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/line-simplification/</guid>
      <description>&lt;p&gt;The other day I needed to do a fairly routine graphical operation, to&#xA;&amp;ldquo;simplify&amp;rdquo; a polyline with many points into a simpler polyline which has&#xA;roughly the same shape plus or minus some &lt;code&gt;tolerance&lt;/code&gt; factor.&lt;/p&gt;&#xA;&lt;p&gt;My actual use case was in sending linear movements to a CNC machine. Drawings&#xA;are defined using floating point numbers and can be &amp;ldquo;accurate&amp;rdquo; to about 7-15&#xA;decimal places (depending on if you use floats or doubles) but when you take&#xA;the machine&amp;rsquo;s mechanical tolerances and material effects into account the&#xA;final cut is only really accurate to about 1 decimal place (0.1 mm). If I&#xA;were to simplify the path with a tolerance of, say, 0.05 mm I could massively&#xA;reduce the number of points sent to the machine (which reduces the amount of&#xA;data sent, buffer sizes, communications overhead, etc.) with minimal effect&#xA;on the accuracy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Pragmatic Approach To Global State</title>
      <link>https://adventures.michaelfbryan.com/posts/pragmatic-global-state/</link>
      <pubDate>Mon, 17 Feb 2020 22:22:47 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/pragmatic-global-state/</guid>
      <description>&lt;p&gt;One of the first things I learned when programming professionally is that&#xA;&lt;em&gt;global variables are bad&lt;/em&gt;. We all take it for granted that it&amp;rsquo;s bad practice&#xA;to write code that relies heavily on global state but the other day I was&#xA;working with a 3rd party native library, and it reminded &lt;em&gt;why&lt;/em&gt; these best&#xA;practices come about.&lt;/p&gt;&#xA;&lt;p&gt;There are a couple factors which made this particular library&amp;rsquo;s use of global&#xA;mutable state rather ugly to work with,&lt;/p&gt;</description>
    </item>
    <item>
      <title>I Made A Thing: Markedit</title>
      <link>https://adventures.michaelfbryan.com/posts/markedit/</link>
      <pubDate>Sun, 09 Feb 2020 04:40:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/markedit/</guid>
      <description>&lt;p&gt;A couple days ago I released &lt;a href=&#34;https://crates.io/crates/markedit&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;markedit&lt;/a&gt;, a small crate for editing&#xA;unstructured markdown documents. This is a useful enough library that I&#xA;thought I&amp;rsquo;d explain the main ideas behind it and potential use cases.&lt;/p&gt;&#xA;&lt;p&gt;This originally came about when I was at work, preparing our application&amp;rsquo;s&#xA;change log before a release for the umpteenth time (we&amp;rsquo;ve found the &lt;a href=&#34;https://keepachangelog.com/en/1.0.0/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;keep a&#xA;changelog&lt;/a&gt; format really useful) and on the drive home I started thinking&#xA;of ways to automate things.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creating Interactive Applications While Maintaining Your Sanity</title>
      <link>https://adventures.michaelfbryan.com/posts/implementing-interactive-applications/</link>
      <pubDate>Thu, 06 Feb 2020 23:43:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/implementing-interactive-applications/</guid>
      <description>&lt;p&gt;One of the primary reasons computers are so ubiquitous in modern society is&#xA;their ability to let humans and software cooperate to achieve a desired goal.&#xA;That is, to be interactive.&lt;/p&gt;&#xA;&lt;p&gt;Creating interactive applications can be pretty annoying for a programmer.&#xA;Unlike a computer which is predictable and will blindly follow any&#xA;instructions given to it,&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Humans are unpredictable. They like to press buttons and push features further&#xA;than they were originally intended&lt;/li&gt;&#xA;&lt;li&gt;Humans have a habit of asking for special cases (&lt;em&gt;&amp;ldquo;Feature X works really&#xA;well, but when I click on this triangle while holding shift and tilting my&#xA;head at an angle, it should really do Y instead. It&amp;rsquo;s not a big feature, can&#xA;you just add?&amp;rdquo;&lt;/em&gt;)&lt;/li&gt;&#xA;&lt;li&gt;Humans often don&amp;rsquo;t know what they want, meaning even if you implement&#xA;something exactly as described to you users will still complain about it not&#xA;doing the right thing&lt;/li&gt;&#xA;&lt;li&gt;The real world is messy, and letting users interact with your program is a&#xA;really effective way of mixing the messy outside world with the nice&#xA;structured world inside a computer&lt;/li&gt;&#xA;&lt;li&gt;Also, users are the ones funding your pay check so you should probably try&#xA;to keep them happy 😁&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The ideas and concepts shown in this article aren&amp;rsquo;t overly advanced. In fact,&#xA;if you&amp;rsquo;ve been programming for a couple months (especially if it&amp;rsquo;s part of a&#xA;formal Computer Science program) you&amp;rsquo;re probably already familiar with them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Words Are Hard - An Essay on Communicating With Non-Programmers</title>
      <link>https://adventures.michaelfbryan.com/posts/words-are-hard/</link>
      <pubDate>Mon, 27 Jan 2020 10:20:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/words-are-hard/</guid>
      <description>&lt;p&gt;There&amp;rsquo;s a well-known saying about the hard problems in computer science, of&#xA;which I think this is my favourite variant,&lt;/p&gt;&#xA;&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.&lt;/p&gt;&amp;mdash; Leon Bambrick (@secretGeek) &lt;a href=&#34;https://twitter.com/secretGeek/status/7269997868?ref_src=twsrc%5Etfw&#34;&gt;January 1, 2010&lt;/a&gt;&lt;/blockquote&gt;&#xA;&lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&#xA;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve been writing software long enough to be burned by all three at some&#xA;point, but as someone working in a small business who represents the software&#xA;side of our product and is constantly rubbing shoulders with non-programmers,&#xA;I believe the ability to correctly communicate an idea or concept in a way&#xA;that others can understand (i.e. to name things) is by far the most&#xA;important.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Thought Experiment: Using the ECS Pattern Outside of Game Engines</title>
      <link>https://adventures.michaelfbryan.com/posts/ecs-outside-of-games/</link>
      <pubDate>Sat, 28 Dec 2019 00:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/ecs-outside-of-games/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s been about 6 months since I watched Catherine West&amp;rsquo;s excellent &lt;a href=&#34;https://www.youtube.com/watch?v=aKLntZcp27M&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Using&#xA;Rust for Game Development&lt;/a&gt; sent me down the &lt;em&gt;Entity-Component-System&lt;/em&gt;&#xA;(ECS) rabbit hole, and I thought I&amp;rsquo;d share some of my findings.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been meaning to write about this for quite a while now but it took a&#xA;while to put my thoughts into a cohesive article without throwing massive&#xA;walls of code at you.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;notices note&#34; &gt;&#xA;    &lt;p&gt;This article is mainly focused around the high-level decisions you make when&#xA;designing a project, so there won&amp;rsquo;t be as much code as normal. That said, all&#xA;code written in this article is available &lt;a href=&#34;https://github.com/Michael-F-Bryan/arcs&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;on GitHub&lt;/a&gt;. Feel free to&#xA;browse through and steal code or inspiration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>WebAssembly as a Platform for Abstraction</title>
      <link>https://adventures.michaelfbryan.com/posts/wasm-as-a-platform-for-abstraction/</link>
      <pubDate>Sun, 15 Dec 2019 11:55:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/wasm-as-a-platform-for-abstraction/</guid>
      <description>&lt;p&gt;In a project I&amp;rsquo;ve been playing around with recently, we&amp;rsquo;ve encountered the&#xA;dilemma where you want to make it easy for users to write their own&#xA;application logic using the system but at the same time want to keep that logic&#xA;decoupled from the implementation details of whatever platform the&#xA;application is running on.&lt;/p&gt;&#xA;&lt;p&gt;If you&amp;rsquo;ve been programming for any amount of time your immediate reaction is&#xA;probably &lt;em&gt;&amp;ldquo;why bother mentioning this, doesn&amp;rsquo;t it just fall out of good&#xA;library design?&amp;rdquo;&lt;/em&gt;, and normally I would totally agree with you, except I&#xA;forgot to mention a couple of important details&amp;hellip;&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to RiiR</title>
      <link>https://adventures.michaelfbryan.com/posts/how-to-riir/</link>
      <pubDate>Mon, 02 Dec 2019 01:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/how-to-riir/</guid>
      <description>&lt;p&gt;In &lt;a href=&#34;https://adventures.michaelfbryan.com/posts/how-not-to-riir/&#34; &gt;a previous article&lt;/a&gt; we&amp;rsquo;ve talked about how you can avoid&#xA;rewriting a library in Rust when you don&amp;rsquo;t need to. But what about the times&#xA;when you really &lt;em&gt;do&lt;/em&gt; need to?&lt;/p&gt;&#xA;&lt;p&gt;In most languages you&amp;rsquo;d need to rewrite the entire library from the ground&#xA;up, waiting until the port is almost finished before you can start seeing&#xA;results. These sorts of ports tend to be quite expensive and error-prone, and&#xA;often they&amp;rsquo;ll fail midway and you&amp;rsquo;ll have nothing to show for your effort.&#xA;&lt;em&gt;Joel Spolsky&lt;/em&gt; does a much better job of explaining this than I ever could, see&#xA;&lt;a href=&#34;https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;his article on why full rewrites are a bad idea&lt;/a&gt; for more.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Implementing ArrayVec Using Const Generics</title>
      <link>https://adventures.michaelfbryan.com/posts/const-arrayvec/</link>
      <pubDate>Fri, 15 Nov 2019 00:57:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/const-arrayvec/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve ever done much embedded programming in Rust, you&amp;rsquo;ve most probably run&#xA;across the &lt;a href=&#34;https://crates.io/crates/arrayvec&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;arrayvec&lt;/code&gt;&lt;/a&gt; crate before. It&amp;rsquo;s awesome. The main purpose&#xA;of the crate is to provide the &lt;code&gt;ArrayVec&lt;/code&gt; type, which is essentially like&#xA;&lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; from the standard library, but backed by an array instead of some&#xA;memory on the heap.&lt;/p&gt;&#xA;&lt;p&gt;One of the problems I ran into while writing the &lt;em&gt;Motion Planning&lt;/em&gt; chapter of my&#xA;&lt;a href=&#34;http://adventures.michaelfbryan.com/tags/adventures-in-motion-control/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Adventures in Motion Control&lt;/a&gt; was deciding how far ahead my motion&#xA;planner should plan.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Audio Processing for Dummies</title>
      <link>https://adventures.michaelfbryan.com/posts/audio-processing-for-dummies/</link>
      <pubDate>Sun, 27 Oct 2019 23:34:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/audio-processing-for-dummies/</guid>
      <description>&lt;p&gt;In my spare time I&amp;rsquo;m an emergency services volunteer, and one of the tasks our&#xA;unit has is to run the radio network and keep track of what&amp;rsquo;s happening. This&#xA;can be a pretty stressful job, especially when there&amp;rsquo;s lots of radio traffic,&#xA;and it&amp;rsquo;s not unusual to miss words or entire transmissions.&lt;/p&gt;&#xA;&lt;p&gt;To help with a personal project that could make the job easier I&amp;rsquo;d like to&#xA;implement a basic component of audio processing, the &lt;a href=&#34;https://en.wikipedia.org/wiki/Noise_gate&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Noise Gate&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to not RiiR</title>
      <link>https://adventures.michaelfbryan.com/posts/how-not-to-riir/</link>
      <pubDate>Sun, 20 Oct 2019 19:45:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/how-not-to-riir/</guid>
      <description>&lt;p&gt;Once you get past the growing pains of the &lt;em&gt;Borrow Checker&lt;/em&gt; and realise Rust&#xA;gives you the power to do things which would be unheard of (or just plain&#xA;dangerous) in other languages, the temptation to &lt;a href=&#34;https://transitiontech.ca/random/RIIR&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;em&gt;Rewrite it in Rust&lt;/em&gt;&lt;/a&gt;&#xA;can be quite strong. However at best, the temptation to &lt;em&gt;RiiR&lt;/em&gt; is unproductive&#xA;(unnecessary duplication of effort), and at worst it can promote the creation&#xA;of buggy software (why would &lt;em&gt;you&lt;/em&gt; be better equipped to write a library for&#xA;some domain-specific purpose than the original author?).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Working With G-Code</title>
      <link>https://adventures.michaelfbryan.com/posts/working-with-gcode/</link>
      <pubDate>Fri, 18 Oct 2019 00:05:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/working-with-gcode/</guid>
      <description>&lt;p&gt;As mentioned in &lt;a href=&#34;https://adventures.michaelfbryan.com/posts/wiring-up-communication/#the-next-step&#34; &gt;the previous post&lt;/a&gt; there are a handful of tasks&#xA;which may be tackled next, but only one of them really allows us to make progress&#xA;towards our goal of implementing the simulated firmware for a 3D Printer.&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s send the motion controller some g-code.&lt;/p&gt;&#xA;&lt;h2 id=&#34;creating-message-types&#34;&gt;&#xA;  Creating Message types&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#creating-message-types&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;If we want to send g-code programs between the frontend and backend we&amp;rsquo;ll need&#xA;to make a couple message definitions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wiring Up Communication</title>
      <link>https://adventures.michaelfbryan.com/posts/wiring-up-communication/</link>
      <pubDate>Thu, 10 Oct 2019 22:58:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/wiring-up-communication/</guid>
      <description>&lt;p&gt;As we mentioned &lt;a href=&#34;https://adventures.michaelfbryan.com/posts/a-better-frontend/#the-next-step&#34; &gt;in the last AiMC post&lt;/a&gt;, the next task is to wire up&#xA;communications between the simulator&amp;rsquo;s backend and frontend.&lt;/p&gt;&#xA;&lt;p&gt;As a general rule, our frontend will have two communication regimes:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;When something happens (e.g. a button is pressed or a job starts sending),&#xA;the frontend will send a batch of messages to the backend and interpret the&#xA;response&lt;/li&gt;&#xA;&lt;li&gt;The frontend will continually poll the backend&amp;rsquo;s state in the background&#xA;(e.g. at 10Hz)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;As it is, the &lt;code&gt;Browser&lt;/code&gt; in our WASM code already provides a method for&#xA;sending data to the frontend (&lt;a href=&#34;https://michael-f-bryan.github.io/adventures-in-motion-control/aimc_sim/struct.Browser.html#method.send_data&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;Browser::send_data()&lt;/code&gt;&lt;/a&gt;) and&#xA;receiving data from the frontend (&lt;a href=&#34;https://michael-f-bryan.github.io/adventures-in-motion-control/aimc_sim/struct.App.html#method.on_data_received&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;App::on_data_received()&lt;/code&gt;&lt;/a&gt;) so&#xA;we shouldn&amp;rsquo;t need to write any Rust code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Plugins in Rust</title>
      <link>https://adventures.michaelfbryan.com/posts/plugins-in-rust/</link>
      <pubDate>Mon, 30 Sep 2019 22:04:58 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/plugins-in-rust/</guid>
      <description>&lt;p&gt;Imagine you are implementing a calculator application and want users to be able&#xA;to extend the application with their own functionality. For example, imagine a&#xA;user wants to provide a &lt;code&gt;random()&lt;/code&gt; function that generates &lt;em&gt;true&lt;/em&gt; random numbers&#xA;using &lt;a href=&#34;https://random.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;random.org&lt;/a&gt; instead of the pseudo-random numbers that a crate like&#xA;&lt;a href=&#34;https://crates.io/crates/rand&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;rand&lt;/a&gt; would provide.&lt;/p&gt;&#xA;&lt;p&gt;The Rust language gives you a lot of really powerful tools for adding&#xA;flexibility and extensibility to your applications (e.g. traits, enums,&#xA;macros), but all of these happen at compile time. Unfortunately, to get the&#xA;flexibility that we&amp;rsquo;re looking we&amp;rsquo;ll need to be able to add new functionality at&#xA;runtime.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Better Frontend</title>
      <link>https://adventures.michaelfbryan.com/posts/a-better-frontend/</link>
      <pubDate>Fri, 27 Sep 2019 03:47:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/a-better-frontend/</guid>
      <description>&lt;p&gt;Now we&amp;rsquo;ve got a half-usable motion controller, we need a graphical way for&#xA;humans to interact with it. The controller runs in a browser, which makes&#xA;&lt;a href=&#34;https://vuejs.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Vue&lt;/a&gt; a perfect candidate for the UI.&lt;/p&gt;&#xA;&lt;h2 id=&#34;adding-vue-to-the-frontend&#34;&gt;&#xA;  Adding Vue to the Frontend&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#adding-vue-to-the-frontend&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Now, we don&amp;rsquo;t actually have much frontend code (47 lines of JavaScript to be&#xA;exact) so it&amp;rsquo;s actually easier to delete the existing &lt;code&gt;frontend&lt;/code&gt; and use the&#xA;&lt;a href=&#34;https://cli.vuejs.org/guide/installation.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;vue&lt;/code&gt; CLI tool&lt;/a&gt; to create a new one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Initial Motion System</title>
      <link>https://adventures.michaelfbryan.com/posts/initial-motion-system/</link>
      <pubDate>Wed, 18 Sep 2019 20:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/initial-motion-system/</guid>
      <description>&lt;p&gt;Now we&amp;rsquo;ve got &lt;a href=&#34;https://adventures.michaelfbryan.com/posts/simple-automation-sequences/#the-next-step&#34; &gt;some simple automation&lt;/a&gt; code, lets start a proper&#xA;&lt;em&gt;Motion&lt;/em&gt; system.&lt;/p&gt;&#xA;&lt;p&gt;Most &lt;em&gt;Motion&lt;/em&gt; systems are designed around a &lt;em&gt;&amp;ldquo;control mode&amp;rdquo;&lt;/em&gt;, a fancy term for&#xA;&lt;em&gt;&amp;ldquo;what is the machine doing right now?&amp;rdquo;&lt;/em&gt; Common control modes are:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;Idle&lt;/code&gt; - the default control mode, machines revert to &lt;code&gt;Idle&lt;/code&gt; whenever they&amp;rsquo;re&#xA;not doing anything&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;Automation&lt;/code&gt; - running an automation sequence&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;Recipe&lt;/code&gt; - executing a job (a set of instructions for how to execute a job&#xA;and the motion parameters that should be used is often referred to as a&#xA;&lt;em&gt;Recipe&lt;/em&gt;)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;Manual&lt;/code&gt; - manual movement, where velocity may be controlled via a handset&#xA;or the user invokes a &lt;em&gt;&amp;ldquo;jog to position&amp;rdquo;&lt;/em&gt; function&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;There are several ways to transition between control modes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Simple Automation Sequences</title>
      <link>https://adventures.michaelfbryan.com/posts/simple-automation-sequences/</link>
      <pubDate>Sat, 14 Sep 2019 23:55:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/simple-automation-sequences/</guid>
      <description>&lt;p&gt;Now we can communicate with the outside world, let&amp;rsquo;s start interacting with the&#xA;&amp;ldquo;hardware&amp;rdquo; attached to our motion controller. This will be the beginning of our&#xA;&lt;em&gt;Motion&lt;/em&gt; system.&lt;/p&gt;&#xA;&lt;p&gt;The simplest way to interact with the world is by executing a pre-defined&#xA;routine, and one of the simplest useful routines is to move all axes to the&#xA;home position.&lt;/p&gt;&#xA;&lt;h2 id=&#34;system-inputs-and-outputs&#34;&gt;&#xA;  System Inputs and Outputs&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#system-inputs-and-outputs&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;From our &lt;a href=&#34;https://adventures.michaelfbryan.com/posts/announcing-adventures-in-motion-control/#identifying-requirements-and-subsystems&#34; &gt;initial requirements gathering&lt;/a&gt; we know that our 3D&#xA;printer will have three linear axes (X, Y, and Z), with limit switches at the&#xA;ends of each axis. This gives our new &lt;em&gt;Motion&lt;/em&gt; system six inputs to deal with.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Communications System: Part 2</title>
      <link>https://adventures.michaelfbryan.com/posts/comms-part-2/</link>
      <pubDate>Sun, 08 Sep 2019 01:20:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/comms-part-2/</guid>
      <description>&lt;p&gt;Now we have a mechanism for transferring bytes from the frontend to the&#xA;simulator and back again, we need to translate those bytes into higher-level&#xA;messages. Luckily each [&lt;code&gt;anpp::Packet&lt;/code&gt;] contains an &lt;a href=&#34;https://docs.rs/anpp/1.0.1/anpp/struct.Packet.html#method.id&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;ID&lt;/code&gt; field&lt;/a&gt; that&#xA;is designed specifically for this purpose.&lt;/p&gt;&#xA;&lt;p&gt;That lets us do something like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// (not real code)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;enum&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Message&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;a&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Ping,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    StatusCheck,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ProgramChunk {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        chunk_number: &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        body: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;a&lt;/span&gt; [&lt;span style=&#34;color:#66d9ef&#34;&gt;u8&lt;/span&gt;],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;..&lt;/span&gt;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;UnknownMessageError&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;parse_packet&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;a&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(pkt: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Packet&lt;/span&gt;) -&amp;gt; Result&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;Message&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;a&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;, UnknownMessageError&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;match&lt;/span&gt; pkt.id() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; Ok(Message::Ping),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; Ok(Message::StatusCheck),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; Ok(&lt;span style=&#34;color:#f92672&#34;&gt;..&lt;/span&gt;.),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        _ &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; Err(UnknownMessageError),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The top-level &lt;code&gt;App&lt;/code&gt; can handle messages by routing them to the appropriate&#xA;system and invoking a message handler.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Communications System: Part 1</title>
      <link>https://adventures.michaelfbryan.com/posts/comms-part-1/</link>
      <pubDate>Fri, 06 Sep 2019 23:00:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/comms-part-1/</guid>
      <description>&lt;h2 id=&#34;prelude&#34;&gt;&#xA;  Prelude&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#prelude&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The &lt;em&gt;Communications&lt;/em&gt; system is arguably one of the most important parts of&#xA;our simulator. After all, it&amp;rsquo;s kinda hard to debug a program when you can&amp;rsquo;t&#xA;ask it why something isn&amp;rsquo;t working.&lt;/p&gt;&#xA;&lt;p&gt;The user will interact with our simulated motion controller via a single&#xA;&lt;em&gt;Serial Port&lt;/em&gt;, which we&amp;rsquo;ll be modelling as a simple thing which sends and&#xA;receives bytes. Serial ports are a fairly old technology, and have several&#xA;drawbacks compared to the Ethernet and TCP protocols that most programmers&#xA;are familiar with.&lt;/p&gt;</description>
    </item>
    <item>
      <title>FPS Counter</title>
      <link>https://adventures.michaelfbryan.com/posts/fps-counter/</link>
      <pubDate>Tue, 03 Sep 2019 08:50:00 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/fps-counter/</guid>
      <description>&lt;p&gt;As mentioned in &lt;a href=&#34;https://adventures.michaelfbryan.com/posts/top-level-infrastructure/#the-next-step&#34; &gt;the previous article&lt;/a&gt; the next task is to&#xA;implement our first proper &lt;code&gt;System&lt;/code&gt;, the &lt;code&gt;FpsCounter&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A relatively easy, yet important, component is some sort of FPS counter.&#xA;Ideally there’ll be a bit of text in the corner showing the number of&#xA;&lt;code&gt;poll()&lt;/code&gt;s per second and the average duration. That way we can get a better&#xA;feel for our simulator’s performance characteristics.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;An &lt;code&gt;FpsCounter&lt;/code&gt; has two responsibilities,&lt;/p&gt;</description>
    </item>
    <item>
      <title>Top-Level Infrastructure</title>
      <link>https://adventures.michaelfbryan.com/posts/top-level-infrastructure/</link>
      <pubDate>Mon, 02 Sep 2019 21:22:30 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/top-level-infrastructure/</guid>
      <description>&lt;p&gt;As mentioned in &lt;a href=&#34;https://adventures.michaelfbryan.com/posts/announcing-adventures-in-motion-control/#the-next-step&#34; &gt;the intro article&lt;/a&gt;, the first task will be to set&#xA;up the application&amp;rsquo;s structure and define how the various components will&#xA;communicate.&lt;/p&gt;&#xA;&lt;h2 id=&#34;multitasking&#34;&gt;&#xA;  Multitasking&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#multitasking&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Most embedded systems will implement multi-tasking by rapidly polling each&#xA;system within an infinite loop.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;loop&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    poll_comms();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    poll_motion_planning();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    poll_io();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    poll_machine_events();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A motion controller will normally spend most of its time polling, but there are&#xA;places where polling isn&amp;rsquo;t appropriate. For example, accurate movement of a&#xA;stepper motor relies on sending pulses at very precise times. Another scenario&#xA;is in the handling of communication, where waiting for the next poll to read a&#xA;byte may result in missing part of a message.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Announcing Adventures in Motion Control</title>
      <link>https://adventures.michaelfbryan.com/posts/announcing-adventures-in-motion-control/</link>
      <pubDate>Sun, 01 Sep 2019 16:27:15 +0800</pubDate>
      <guid>https://adventures.michaelfbryan.com/posts/announcing-adventures-in-motion-control/</guid>
      <description>&lt;p&gt;This is the first installation in my &lt;em&gt;Adventures in Motion Control&lt;/em&gt; series.&lt;/p&gt;&#xA;&lt;p&gt;At &lt;code&gt;$JOB&lt;/code&gt; we build industrial CNC machines, and while developing a simulator&#xA;for our machines I noticed a distinct lack of online resources on how&#xA;they work under the hood. Hopefully this series will address the situation.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-goal&#34;&gt;&#xA;  The Goal&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#the-goal&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The goal for this series is to develop a simulator which will accurately reflect&#xA;how an embedded motion controller is implemented internally.&lt;/p&gt;</description>
    </item>
    <item>
      <title>About Me</title>
      <link>https://adventures.michaelfbryan.com/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://adventures.michaelfbryan.com/about/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m Michael Bryan, a software engineer based in Perth, WA, with a passion for building resilient systems and elegant solutions.&lt;/p&gt;&#xA;&lt;h2 id=&#34;professional-overview&#34;&gt;&#xA;  Professional Overview&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#professional-overview&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;m currently a &lt;strong&gt;Senior Software Engineer&lt;/strong&gt; at &lt;a href=&#34;https://multiversal.ventures/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Multiversal Ventures&lt;/a&gt;, primarily focused on developing robust web crawlers at scale and leveraging ML to extract information from US healthcare websites.&lt;/p&gt;&#xA;&lt;p&gt;I specialise in writing precise, maintainable code and consider myself an expert in Rust, with extensive experience in Go, TypeScript, React, and GraphQL. I&amp;rsquo;m particularly passionate about compilers, type-safe code, and designing parsers that gracefully handle errors.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
