<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Development on Clément Joly – Open-Source, Rust &amp; SQLite</title><link>https://joly.pw/tags/development/</link><description>Recent content in Development on Clément Joly – Open-Source, Rust &amp; SQLite</description><image><title>Clément Joly – Open-Source, Rust &amp; SQLite</title><url>https://joly.pw/images/open-graph-home-original.png</url><link>https://joly.pw/images/open-graph-home-original.png</link></image><generator>Hugo -- 0.154.3</generator><language>en</language><copyright>Clément Joly</copyright><lastBuildDate>Wed, 11 Mar 2026 03:32:38 +0000</lastBuildDate><atom:link href="https://joly.pw/tags/development/index.xml" rel="self" type="application/rss+xml"/><item><title>Rust Default Values for Maintainability</title><link>https://joly.pw/blog/rust-default-values-for-maintainability/</link><pubDate>Sat, 25 Jun 2022 14:41:55 +0000</pubDate><guid>https://joly.pw/blog/rust-default-values-for-maintainability/</guid><description>Hidden benefits of the humble Default trait</description><content:encoded><![CDATA[



  
  
  
  

  <div class="alert alert-tldr">
    <p class="alert-heading">
      ⚡
      
        TL;DR
      
    </p>
    <p>The <a href="https://doc.rust-lang.org/std/default/trait.Default.html"><code>Default</code></a> trait can enhance the maintainability of your code. Default values for common types are <a href="#quick-reference">listed</a> at the end.</p>
  </div>



<h2 id="a-pr-review">A PR Review</h2>
<p>Recently, while reviewing a <a href="https://github.com/cljoly/rusqlite_migration/pull/20/files">PR</a><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, I noticed that part of the patch was introducing a new field to a struct:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-diff" data-lang="diff"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 1</span><span>diff --git a/src/lib.rs b/src/lib.rs
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 2</span><span>index eba9a3a..8619e06 100644
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 3</span><span><span style="color:#e06c75">--- a/src/lib.rs
</span></span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 4</span><span><span style="color:#98c379;font-weight:bold">+++ b/src/lib.rs
</span></span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 5</span><span>@@ -106,8 +108,9 @@ use std::{
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 6</span><span> #[derive(Debug, PartialEq, Clone)]
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 7</span><span> pub struct M&lt;&#39;u&gt; {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 8</span><span>     up: &amp;&#39;u str,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 9</span><span>     down: Option&lt;&amp;&#39;u str&gt;,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">10</span><span><span style="color:#98c379;font-weight:bold">+    foreign_key_check: bool,
</span></span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">11</span><span> }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">12</span><span> 
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">13</span><span> impl&lt;&#39;u&gt; M&lt;&#39;u&gt; {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">14</span><span>@@ -137,8 +140,9 @@ impl&lt;&#39;u&gt; M&lt;&#39;u&gt; {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">15</span><span>     pub const fn up(sql: &amp;&#39;u str) -&gt; Self {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">16</span><span>         Self {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">17</span><span>             up: sql,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">18</span><span>             down: None,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">19</span><span><span style="color:#98c379;font-weight:bold">+            foreign_key_check: false,
</span></span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">20</span><span>         }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">21</span><span>     }
</span></span></code></pre></div><p>That prompted me to reflect on the code I had initially written.
Prior to the patch, it looked roughly<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 1</span><span><span style="color:#7f848e">#[derive(Debug, PartialEq, Clone)]</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 2</span><span><span style="color:#c678dd">pub</span> <span style="color:#c678dd">struct</span> <span style="color:#e5c07b">M</span><span style="color:#56b6c2">&lt;</span><span style="color:#e06c75">&#39;u</span><span style="color:#56b6c2">&gt;</span> {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 3</span><span>    <span style="color:#e06c75">up</span>: <span style="color:#c678dd">&amp;</span><span style="color:#e06c75">&#39;u</span> <span style="color:#e5c07b">str</span>,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 4</span><span>    <span style="color:#e06c75">down</span>: <span style="color:#e5c07b">Option</span><span style="color:#56b6c2">&lt;&amp;</span><span style="color:#e06c75">&#39;u</span> <span style="color:#e5c07b">str</span><span style="color:#56b6c2">&gt;</span>,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 5</span><span>}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 6</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 7</span><span><span style="color:#c678dd">impl</span><span style="color:#56b6c2">&lt;</span><span style="color:#e06c75">&#39;u</span><span style="color:#56b6c2">&gt;</span> <span style="color:#e06c75">M</span><span style="color:#56b6c2">&lt;</span><span style="color:#e06c75">&#39;u</span><span style="color:#56b6c2">&gt;</span> {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 8</span><span>    <span style="color:#c678dd">pub</span> <span style="color:#c678dd">const</span> <span style="color:#c678dd">fn</span> <span style="color:#61afef;font-weight:bold">up</span>(<span style="color:#e06c75">sql</span>: <span style="color:#c678dd">&amp;</span><span style="color:#e06c75">&#39;u</span> <span style="color:#e5c07b">str</span>) -&gt; <span style="color:#e5c07b">Self</span> {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 9</span><span>        <span style="color:#e5c07b">Self</span> {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">10</span><span>            <span style="color:#e06c75">up</span>: <span style="color:#e5c07b">sql</span>,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">11</span><span>            <span style="color:#e06c75">down</span>: <span style="color:#e5c07b">None</span>,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">12</span><span>        }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">13</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">14</span><span>}
</span></span></code></pre></div><h2 id="the-default-trait">The <code>Default</code> Trait</h2>
<p>What if I had used the <a href="https://doc.rust-lang.org/std/default/trait.Default.html"><code>Default</code></a> trait here?
The code could have looked like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"><code class="language-rust" data-lang="rust"><span style="display:flex; background-color:#3d4148"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 1</span><span><span style="color:#7f848e">#[derive(Debug, Default, PartialEq, Clone)]</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 2</span><span><span style="color:#c678dd">pub</span> <span style="color:#c678dd">struct</span> <span style="color:#e5c07b">M</span><span style="color:#56b6c2">&lt;</span><span style="color:#e06c75">&#39;u</span><span style="color:#56b6c2">&gt;</span> {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 3</span><span>    <span style="color:#e06c75">up</span>: <span style="color:#c678dd">&amp;</span><span style="color:#e06c75">&#39;u</span> <span style="color:#e5c07b">str</span>,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 4</span><span>    <span style="color:#e06c75">down</span>: <span style="color:#e5c07b">Option</span><span style="color:#56b6c2">&lt;&amp;</span><span style="color:#e06c75">&#39;u</span> <span style="color:#e5c07b">str</span><span style="color:#56b6c2">&gt;</span>,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 5</span><span>}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 6</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 7</span><span><span style="color:#c678dd">impl</span><span style="color:#56b6c2">&lt;</span><span style="color:#e06c75">&#39;u</span><span style="color:#56b6c2">&gt;</span> <span style="color:#e06c75">M</span><span style="color:#56b6c2">&lt;</span><span style="color:#e06c75">&#39;u</span><span style="color:#56b6c2">&gt;</span> {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 8</span><span>    <span style="color:#c678dd">pub</span> <span style="color:#c678dd">const</span> <span style="color:#c678dd">fn</span> <span style="color:#61afef;font-weight:bold">up</span>(<span style="color:#e06c75">sql</span>: <span style="color:#c678dd">&amp;</span><span style="color:#e06c75">&#39;u</span> <span style="color:#e5c07b">str</span>) -&gt; <span style="color:#e5c07b">Self</span> {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 9</span><span>        <span style="color:#e5c07b">Self</span> {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">10</span><span>            <span style="color:#e06c75">up</span>: <span style="color:#e5c07b">sql</span>,
</span></span><span style="display:flex; background-color:#3d4148"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">11</span><span>            <span style="color:#56b6c2">..</span><span style="color:#e5c07b">Default</span>::<span style="color:#e06c75">default</span>()
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">12</span><span>        }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">13</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">14</span><span>}
</span></span></code></pre></div><p>On the first line, the <a href="https://doc.rust-lang.org/reference/attributes/derive.html"><code>#[derive(Default)]</code></a> attribute makes the structure <code>M</code> implement the <code>Default</code> trait.
Thanks to this trait, a call to <code>M::default()</code> will create a struct with default values for its fields: <code>M { up: &quot;&quot;, down: None }</code>. Note that when a structure <code>M</code> is expected, <code>Default::default()</code> is equivalent to <code>M::default()</code>.</p>
<p>We then need to initialize the two fields of that structure, overriding some defaults:</p>
<ul>
<li><code>up</code> is defined directly as before. That’s the value we want to override.</li>
<li><code>down</code> is set by the <code>Default</code> trait. This is done by <code>..Default::default()</code> on line 11. <code>Default::default()</code> provides the values. Then the <a href="https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax"><code>..</code></a> syntax fills out the fields that were not directly set. <code>down</code> is thus set to the same value as before, <code>None</code>.</li>
</ul>
<p>The code is just as long as before, when we were not using the <code>Default</code> trait.
But then, <a href="#a-pr-review">line 19 of the above patch</a> would have been unnecessary: <code>false</code> is the default for a <code>bool</code>, so the new <code>foreign_key_check</code> field would have been covered by the <code>..Default::default()</code>.</p>
<p>This results in a shorter patch:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-diff" data-lang="diff"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 1</span><span>diff --git a/src/lib.rs b/src/lib.rs
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 2</span><span>index eba9a3a..8619e06 100644
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 3</span><span><span style="color:#e06c75">--- a/src/lib.rs
</span></span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 4</span><span><span style="color:#98c379;font-weight:bold">+++ b/src/lib.rs
</span></span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 5</span><span>@@ -106,8 +108,9 @@ use std::{
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 6</span><span> #[derive(Debug, PartialEq, Clone)]
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 7</span><span> pub struct M&lt;&#39;u&gt; {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 8</span><span>     up: &amp;&#39;u str,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f"> 9</span><span>     down: Option&lt;&amp;&#39;u str&gt;,
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">10</span><span><span style="color:#98c379;font-weight:bold">+    foreign_key_check: bool,
</span></span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">11</span><span> }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">12</span><span> 
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#55595f">13</span><span> impl&lt;&#39;u&gt; M&lt;&#39;u&gt; {
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>In the example of this post, we are doing only one instantiation of that particular struct, and it has very few fields anyway.
But if there were many instantiations of that struct, we would have had to change all of those.
Then, using <code>Default</code> would have been quite beneficial.</p>
<p><a href="https://cs.github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b2096662b82b79204944/compiler/rustc_target/src/spec/hermit_base.rs#L21">This</a>
<a href="https://cs.github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b2096662b82b79204944/compiler/rustc_target/src/spec/solaris_base.rs#L15">pattern</a>
<a href="https://cs.github.com/rust-lang/rust-analyzer/blob/6fc5c3cd2117a29981ba9b7cef8a51c1d6804089/crates/ide-completion/src/render.rs#L68">were</a>
<a href="https://cs.github.com/rust-lang/rustc-perf/blob/434ba59ca9fbd793ba2b6d02e65704c108479069/collector/benchmarks/clap-3.1.6/src/build/possible_value.rs#L56">the</a>
<a href="https://cs.github.com/rust-lang/rustup/blob/20ed5d9803ca237c39fbbcba8971c4558be4acca/src/diskio/immediate.rs#L34">return</a>
<a href="https://cs.github.com/rust-lang/mdBook/blob/0547868d4d25e1c840a871f9e17b2b4c2078596b/src/book/book.rs#L89">type</a>
is
<a href="https://cs.github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b2096662b82b79204944/compiler/rustc_target/src/spec/redox_base.rs#L16">built</a>
<a href="https://cs.github.com/rust-lang/docs.rs/blob/1ce3fd876a0f5fd5b52c9962cf7ae9df137e6366/src/web/releases.rs#L653">with</a>
a
<a href="https://cs.github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b2096662b82b79204944/compiler/rustc_target/src/spec/l4re_base.rs#L13">call</a>
to
<code>Default::default()</code>
seems
relatively
common
in
the
<a href="https://github.com/rust-lang">Rust organization</a>.
It can enhance maintainability, much more than I initially thought.</p>
<p>Of course this is a balancing act.
For instance, this pattern could be abused by <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=ae7553d16b481951bd8e3418b82fcd27">defining custom default values</a> on primitive types for a particular structure.
That would lead to <code>Default::default()</code> filling surprising values and the code would be less predictable.</p>




  
  
  
  

  <div class="alert alert-edit">
    <p class="alert-heading">
      ✏
      
        Edit
      
    </p>
    <p>2022-07-29: As SpudnikV <a href="https://www.reddit.com/r/rust/comments/vkozed/comment/idtbgit/?utm_source=share&amp;utm_medium=web2x&amp;context=3">pointed out</a>, using defaults as explained in this post can hide the implications of a change made to a structure. There could be code in various places relying on invariants that may break due to the change. Without <code>Default::default()</code>, the change might make visible edits in these places, drawing the attention of reviewers on these invariants.</p>
<p>That’s another case where it might not be wise to use the <code>Default</code> trait. Again, it’s a balancing act!</p>
  </div>



<hr>
<h2 id="appendix-defaults-for-some-common-types-with-derive">Appendix: Defaults for Some Common Types With <code>derive</code></h2>
<p>Why did I not use the <code>Default</code> trait initially?
Part of it might be the fear of introducing incorrect code.
It was slightly unclear to me what <code>derive</code> uses as a default value for common primitive types.
And you don’t want a field set explicitly to <code>false</code> becoming a <code>true</code> once you use <code>Default</code>, right?</p>
<p>Let’s take a closer look by running the following program:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#7f848e">#[derive(Debug, Default)]</span>
</span></span><span style="display:flex;"><span><span style="color:#c678dd">struct</span> <span style="color:#e5c07b">D</span><span style="color:#56b6c2">&lt;</span><span style="color:#e06c75">&#39;a</span><span style="color:#56b6c2">&gt;</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">b</span>: <span style="color:#e5c07b">bool</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">c</span>: <span style="color:#e5c07b">char</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">o</span>: <span style="color:#e5c07b">Option</span><span style="color:#56b6c2">&lt;</span><span style="color:#e5c07b">usize</span><span style="color:#56b6c2">&gt;</span>,
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">string</span>: <span style="color:#e5c07b">String</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e5c07b">str</span>: <span style="color:#c678dd">&amp;</span><span style="color:#e06c75">&#39;a</span> <span style="color:#e5c07b">str</span>,
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">v</span>: <span style="color:#e5c07b">Vec</span><span style="color:#56b6c2">&lt;</span><span style="color:#e5c07b">usize</span><span style="color:#56b6c2">&gt;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">a</span>: [<span style="color:#e5c07b">usize</span>; <span style="color:#d19a66">10</span>],
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">s</span>: <span style="color:#c678dd">&amp;</span><span style="color:#e06c75">&#39;a</span> [<span style="color:#e5c07b">u32</span>],
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">f</span>: <span style="color:#e5c07b">f64</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">u</span>: (<span style="color:#e5c07b">usize</span>, <span style="color:#e5c07b">u32</span>, <span style="color:#e5c07b">u64</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#c678dd">fn</span> <span style="color:#61afef;font-weight:bold">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#56b6c2;font-weight:bold">println!</span>(<span style="color:#98c379">&#34;</span><span style="color:#98c379">{:#?}</span><span style="color:#98c379">&#34;</span>, <span style="color:#e06c75">D</span>::<span style="color:#e06c75">default</span>());
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Output:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#e06c75">D</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">b</span>: <span style="color:#e5c07b">false</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">c</span>: <span style="color:#e06c75">&#39;</span>\<span style="color:#d19a66">0</span><span style="color:#e06c75">&#39;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">o</span>: <span style="color:#e5c07b">None</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">string</span>: <span style="color:#98c379">&#34;&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e5c07b">str</span>: <span style="color:#98c379">&#34;&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">v</span>: [],
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">a</span>: [
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">s</span>: [],
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">f</span>: <span style="color:#d19a66">0.0</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">u</span>: (
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#d19a66">0</span>,
</span></span><span style="display:flex;"><span>    ),
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>It turns out that in general, the default for common types in the standard library is a 0 byte in the underlying data structure.
Note that arrays are fixed size in rust and thus the default is an array of the right size, filled with defaults for the inner type.
That’s quite similar to <a href="https://go.dev/ref/spec#The_zero_value">go</a>.</p>
<h3 id="quick-reference">Quick Reference</h3>
<p>Here is a table for future reference:</p>
<table>
  <thead>
      <tr>
          <th>Type</th>
          <th>Default value</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>bool</code></td>
          <td><code>false</code></td>
      </tr>
      <tr>
          <td><code>char</code></td>
          <td><code>'\0'</code></td>
      </tr>
      <tr>
          <td><code>Option</code></td>
          <td><code>None</code></td>
      </tr>
      <tr>
          <td><code>String</code>, <code>&amp;str</code></td>
          <td><code>&quot;&quot;</code></td>
      </tr>
      <tr>
          <td><code>Vec&lt;usize&gt;</code></td>
          <td><code>[]</code></td>
      </tr>
      <tr>
          <td><code>[usize; N]</code></td>
          <td><code>[0, 0, …, 0]</code></td>
      </tr>
      <tr>
          <td><code>&amp;[u32]</code></td>
          <td><code>[]</code></td>
      </tr>
      <tr>
          <td><code>f64</code>, <code>f32…</code></td>
          <td><code>0.</code></td>
      </tr>
      <tr>
          <td><code>usize</code>, <code>u32…</code></td>
          <td><code>0</code></td>
      </tr>
  </tbody>
</table>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Please don’t take anything in this post as critical of the PR’s author work. I’m very grateful that they took some time to contribute to <a href="https://cj.rs/rusqlite_migration/">the project</a>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>I’ve slightly edited the patch and the code samples from <a href="https://cj.rs/rusqlite_migration/">rusqlite_migration</a> to make those shorter and easier to grasp.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>Local NeoVim Plugin Development</title><link>https://joly.pw/blog/tips/nvim-plugin-development/</link><pubDate>Tue, 02 Nov 2021 14:28:13 +0000</pubDate><guid>https://joly.pw/blog/tips/nvim-plugin-development/</guid><description>&lt;div class="alert alert-note"&gt;
&lt;p class="alert-heading"&gt;
ℹ️
Note
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2023-05-20&lt;/strong&gt;: Updated to account for the features of NeoVim 0.9 and obsolete plugins&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You have found a (Neo)Vim plugin that you want to fiddle with, either to contribute changes upstream or for your own use. Sounds familiar? Here are some tips and tricks I use for my &lt;a href="https://joly.pw/telescope-repo-nvim/"&gt;NeoVim plugin development&lt;/a&gt;. The aim of these small tricks is to iterate faster on changes, by loading your changes in a live NeoVim instance as quickly as possible.&lt;/p&gt;</description><content:encoded><![CDATA[



  
  
  
  

  <div class="alert alert-note">
    <p class="alert-heading">
      ℹ️
      
        Note
      
    </p>
    <p><strong>2023-05-20</strong>: Updated to account for the features of NeoVim 0.9 and obsolete plugins</p>
  </div>



<p>You have found a (Neo)Vim plugin that you want to fiddle with, either to contribute changes upstream or for your own use. Sounds familiar? Here are some tips and tricks I use for my <a href="https://joly.pw/telescope-repo-nvim/">NeoVim plugin development</a>. The aim of these small tricks is to iterate faster on changes, by loading your changes in a live NeoVim instance as quickly as possible.</p>
<p>We will use <a href="https://joly.pw/telescope-repo-nvim/">telescope-repo.nvim</a> as an example but it is applicable to any plugin (although some sections of this post only apply to Lua NeoVim plugins).</p>
<h2 id="load-local-plugin-version">Load Local Plugin Version</h2>
<p>When developing, you make your changes to a local git repository, for instance <code>~/ghq/github.com/cljoly/telescope-repo.nvim</code>. To test those changes, you need to tell NeoVim to load the plugin from the local repository, instead of using the location set by your plugin manager. To do this, just append the following near the beginning of your <code>init.lua</code> file:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lua" data-lang="lua"><span style="display:flex;"><span><span style="color:#e06c75">vim.opt</span>.<span style="color:#e06c75">runtimepath</span>:<span style="color:#e06c75">prepend</span>(<span style="color:#98c379">&#34;~/ghq/github.com/cljoly/telescope-repo.nvim&#34;</span>)
</span></span></code></pre></div><p>Note the <code>:prepend</code>. It will ensure that your local dev version will override anything installed by your nvim package manager. This way no need to uninstall your plugin when developing!</p>
<h2 id="reloading-changes-in-a-live-neovim-instance">Reloading Changes in a Live NeoVim Instance</h2>
<p>You have now made some changes to the plugin that you would like to test. In doing so, you start a second NeoVim instance and open a set of files, change a bunch of settings…</p>
<p>You then change something in the code, but you don’t want to restart you test NeoVim instance, as that would mean reopening files and altering settings all over again. But just doing <code>require(…)</code> is not enough, because <code>require</code> caches already loaded files and doesn’t reload them if they are loaded already.</p>
<p>If you use <a href="https://github.com/nvim-telescope/telescope.nvim">telescope</a>, you can use the <code>reloader</code> picker. You can then select the module you want to reload, like so:</p>
<figure>
    <img loading="lazy" src="./telescope-reloader.png"
         alt="You type “telescop repo” and the corresponding Lua module surfaces. It will be reloaded when you hit Enter."/> <figcaption>
            Telescope reloader in action<p>You type “telescop repo” and the corresponding Lua module surfaces. It will be reloaded when you hit Enter.</p>
        </figcaption>
</figure>

<p>Under the hood, <code>telescope reload</code> <a href="https://github.com/nvim-telescope/telescope.nvim/blob/587a10d1494d8ffa1229246228f0655db2f0a48a/lua/telescope/builtin/internal.lua#L712">uses plenary</a>:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lua" data-lang="lua"><span style="display:flex;"><span><span style="color:#e06c75">require</span>(<span style="color:#98c379">&#34;plenary.reload&#34;</span>).<span style="color:#e06c75">reload_module</span>(<span style="color:#e06c75">selection.value</span>)
</span></span></code></pre></div><p>which handle various cases (like whether <a href="https://github.com/lewis6991/impatient.nvim">impatient.nvim</a> is used at the time of writing). Despite this careful handling, sometimes, a plugin may not fully reload. In that case, you want to automate as much of the setup as possible on NeoVim restart.</p>
<h2 id="if-all-else-fails">If All Else Fails</h2>
<p>Sometimes, a “soft” reloading is not enough and you need to restart NeoVim. For instance, if we are testing the <code>:Telescope repo list</code> command and need to open <code>/tmp/file</code>, we can do:</p>
<pre tabindex="0"><code>nvim +&#39;Telescope repo list&#39; /tmp/file
</code></pre><p>and even place this in an infinite loop with a <code>sleep</code> command, to escape the loop more easily once we are done.</p>
<p>Of course, you will want to replace <code>Telescope repo list</code> with the command you want to test. You can also add more setup by supplying multiple “<code>+'…'</code>” arguments)</p>
<h2 id="all-set">All Set</h2>
<p>Now that you are all set, you can go on and write complete plugins! You may find the following resources useful in your journey:</p>
<ul>
<li>the <a href="https://neovim.io/doc/user/lua-guide.html"><code>:help lua-guide.txt</code></a> has a lot of resources to write plugins and alter NeoVim’s configuration,
<ul>
<li><a href="https://www.2n.pl/blog/how-to-write-neovim-plugins-in-lua">2n.pl</a> walks through writing a simple plugin,</li>
</ul>
</li>
<li><a href="https://web.archive.org/web/20211207190156/https://www.chrisatmachine.com/Neovim/28-neovim-lua-development/">set up a Language Server Protocol for Lua</a>,
<ul>
<li>and maybe even a full-blown <a href="https://github.com/folke/neodev.nvim">plugin</a> for Lua plugin development,</li>
</ul>
</li>
<li>to test a piece of Lua code real quick, <code>:=my.lua.code(here)</code> is great. For bigger pieces of code, <a href="https://github.com/rafcamlet/nvim-luapad">luapad</a> can be useful: it provides a scratch buffer where the result of a Lua snippet is displayed as you type.</li>
</ul>
]]></content:encoded></item></channel></rss>