<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Matt Delacour</title>
    <subtitle>Entrepreneur, Data Scientist and currently CTO. I have a passion for challenges and learning new skills.</subtitle>
    <link rel="self" type="application/atom+xml" href="/atom.xml"/>
    <link rel="alternate" type="text/html" href="/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-05-05T00:00:00+00:00</updated>
    <id>/atom.xml</id>
    <entry xml:lang="en">
        <title>Why Experience Still Beats Knowledge in AI-Assisted Engineering</title>
        <published>2026-05-05T00:00:00+00:00</published>
        <updated>2026-05-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/the-prototype-gap/"/>
        <id>/posts/the-prototype-gap/</id>
        
        <content type="html" xml:base="/posts/the-prototype-gap/">&lt;p&gt;Six weeks ago, my brother went to an Anthropic event in London. Then he called me: “I built a working prototype in two days. This is crazy.”&lt;&#x2F;p&gt;
&lt;p&gt;I asked him to push his code to github and to share it. He asked: “What do you mean? How do I do that?&lt;&#x2F;p&gt;
&lt;p&gt;The first commit made me smile when I saw he committed a failed curl command.
&lt;img src=&quot;&#x2F;posts&#x2F;the-prototype-gap&#x2F;failed_curl_cmd.png&quot; alt=&quot;Failed curl command screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And nonetheless, he is right, “this is crazy”. He had a working prototype without even knowing what a terminal was.&lt;br &#x2F;&gt;
We are going through a fascinating revolution.&lt;&#x2F;p&gt;
&lt;p&gt;The economics behind that revolution are shifting fast.&lt;&#x2F;p&gt;
&lt;p&gt;The cost of prototyping has been massively reduced. Some already think that code is going to become disposable as the cost of writing keeps getting cheaper. We, engineers, often want to rebuild everything from scratch. Whether in a new programming language (eg Rust&#x2F;Golang) or with new patterns and libraries. This is definitely easier today than a decade ago and the cost of doing so went down.&lt;&#x2F;p&gt;
&lt;p&gt;However, while AI gives you knowledge, it cannot give you judgment.
Judgment is what makes you pause before adding a cache layer because you’ve felt what a cache invalidation bug looks like at 2am. Judgment is recognizing you’re over-engineering before the codebase makes it obvious.&lt;br &#x2F;&gt;
This is the gap. Non-engineers using AI don’t know the questions they aren’t asking. And AI — however capable — can only answer what it’s asked.&lt;&#x2F;p&gt;
&lt;p&gt;Think about what you actually get when you hire a junior engineer. You spend months transferring context - the unwritten rules, the past mistakes, the reasons. It’s painful. But that investment compounds. They grow, develop taste, become senior, eventually lead.&lt;&#x2F;p&gt;
&lt;p&gt;With LLM, at least today, you have  to transfer the context over and over. They don’t learn on your specific use case, it does not grow. It does not accumulate judgment from your codebase, your incidents, your specific constraints.&lt;&#x2F;p&gt;
&lt;p&gt;However the model, it is not capable of becoming your senior engineer. The trap is not incompetence - it’s misplaced trust. You would not hand over unsupervised access to your production database to a junior engineer after a few weeks of never growing. And interesting engouh, we are seeing people spinning up armies of agents with full access to their system.&lt;&#x2F;p&gt;
&lt;p&gt;And while product stakeholders can now share their vision and help polish the product without competing for engineering resources; let’s not confuse “prototype” with “production-ready” software.&lt;&#x2F;p&gt;
&lt;p&gt;Today my brother’s prototype works and he wanted to go live using the family business data warehouse. That is where I had to draw a line to make sure we would not leak the business data (sales, customers, products, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;If you’re a software engineer: your value isn’t writing code faster. It’s knowing which questions to ask before the code is written. It’s providing clarity. It’s to understanding the tradeoffs.&lt;br &#x2F;&gt;
If you’re a product stakeholder: prototype freely. But find an engineer before you ship.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Releasing a tiny ORM for CRUD operations.</title>
        <published>2025-10-28T00:00:00+00:00</published>
        <updated>2025-10-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/tiny-orm/"/>
        <id>/posts/tiny-orm/</id>
        
        <content type="html" xml:base="/posts/tiny-orm/">&lt;p&gt;Previously, I explored how to set up a project without relying on an ORM (&lt;a href=&quot;&#x2F;posts&#x2F;simple-crud-only-using-sqlx&#x2F;&quot;&gt;see the previous post&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;To recap, not using an ORM can be a good thing, as it reduces the number of dependencies in your binary. There are many benefits to it. It also helps gain clarity into the queries executed (easier to debug performance issues). The downside is that boilerplate needs to be copied for simple manipulations, and tests should always be added. This makes the data layer more verbose.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tradeoffs&quot;&gt;Tradeoffs&lt;&#x2F;h2&gt;
&lt;p&gt;While handwritten SQL queries make sense in many use cases, simple operations are often performed. Those are most likely going to be a CRUD one.&lt;&#x2F;p&gt;
&lt;p&gt;At first, I wanted to use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;treydempsey&#x2F;sqlx-crud&quot;&gt;&lt;code&gt;sqlx-crud&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, which was precisely what I aspire to do. But the library seems unmaintained, as the last release was a few years ago. So bugs were not addressed, and dependencies were not updated. This is why I decided to release a Rust library, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;tiny-orm&quot;&gt;&lt;code&gt;tiny-orm&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, that focuses on CRUD SQL operations. I also took the time to look at the different libraries and their approach.&lt;&#x2F;p&gt;
&lt;p&gt;My main goals and philosophy were:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;To have the least amount of dependencies&lt;&#x2F;li&gt;
&lt;li&gt;Tackle all the boilerplate of the CRUD operations&lt;&#x2F;li&gt;
&lt;li&gt;Add no complexity by default&lt;&#x2F;li&gt;
&lt;li&gt;Can fit real-world problems&lt;&#x2F;li&gt;
&lt;li&gt;It is easy to maintain&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Thus, I decided to make the following technical tradeoffs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tradeoff-1-only-support-crud-operations&quot;&gt;Tradeoff 1: Only support CRUD operations&lt;&#x2F;h3&gt;
&lt;p&gt;ORMs can get complex very quickly. Looking at a full ORM like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sea-ql.org&#x2F;SeaORM&#x2F;&quot;&gt;SeaORM&lt;&#x2F;a&gt;, it can do a lot, from generating the schemas to handling relations between tables.&lt;br &#x2F;&gt;
Because most of the boilerplate I had to copy and paste over and over in my production services was around CRUD operations (aka inserting, updating, and deleting a record). And even more, handling the logic about partially updating only the values of your struct that are different (as seen in my previous post).&lt;br &#x2F;&gt;
Thus, I decided to focus only on CRUD operations (bulk insert&#x2F;update, as of the time of writing) and leave the rest aside (schema generation, migrations, table relations, etc.).&lt;br &#x2F;&gt;
And even then, I ended up adding extra features like the ability to skip fields that are not set through a wrapper called &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MattDelac&#x2F;tiny_orm?tab=readme-ov-file#setoption&quot;&gt;&lt;code&gt;SetOption&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;br &#x2F;&gt;
Supporting all the databases and their differences (e.g., handling UUIDs, RETURN statements, etc.) was more than I thought.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tradeoff-2-use-sqlx-querybuilder&quot;&gt;Tradeoff 2: Use SQLx QueryBuilder&lt;&#x2F;h3&gt;
&lt;p&gt;Looking at a few repositories, I realized that many had to reinvent the wheel. How to parse parameters? How to deal with datetime values? How to parse input and sanitize it? etc.&lt;br &#x2F;&gt;
Since I wanted to keep maintenance of the library to a minimum and since it’s built on top of SQLx, I decided to use their &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;sqlx_wasi&#x2F;latest&#x2F;sqlx&#x2F;struct.QueryBuilder.html&quot;&gt;QueryBuilder&lt;&#x2F;a&gt;. This allows me to be compatible with PostgreSQL, MySQL, and SQLite right away.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tradeoff-3-do-not-use-compile-time-checked-queries&quot;&gt;Tradeoff 3: Do not use compile-time checked queries&lt;&#x2F;h3&gt;
&lt;p&gt;SQLx allows you to check queries at compile time against a local database. That’s an excellent feature that makes the code more robust.&lt;br &#x2F;&gt;
While I like the idea of compile-time checks, I don’t want to impose such restrictions on downstream users of this library (and even if SQLx’s compile-time checks can run offline after initializing a metadata JSON file).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tradeoff-4-supports-for-multiple-versions-of-sqlx&quot;&gt;Tradeoff 4: Supports for multiple versions of SQLx&lt;&#x2F;h3&gt;
&lt;p&gt;When I started this library, SQLx was on &lt;code&gt;0.7.*&lt;&#x2F;code&gt;. Then they release &lt;code&gt;0.8.*&lt;&#x2F;code&gt; soon after. A lot of libraries update to the latest dependencies and call it a day. Libraries should be flexible and avoid enforcing a specific version of their dependencies when possible.&lt;br &#x2F;&gt;
Even if there were breaking changes between &lt;code&gt;0.7.*&lt;&#x2F;code&gt; and &lt;code&gt;0.8.*&lt;&#x2F;code&gt;, I decided to add a feature flag &lt;code&gt;sqlx-0.7&lt;&#x2F;code&gt; to work around some limitations when upgrading SQLx.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note: I did not find a way to make my code and macros dependent on the version of SQLx installed by the user. There should be logic to detect the SQLx version being used automatically. I see the feature flag as a workaround only.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;feedback-from-the-community&quot;&gt;Feedback from the community&lt;&#x2F;h2&gt;
&lt;p&gt;I started designing the library’s API layer based on some of my assumptions. One of the best things that happened was when I asked for feedback in the #rust topic of Reddit. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MattDelac&#x2F;tiny_orm&#x2F;issues&#x2F;15&quot;&gt;joshka&lt;&#x2F;a&gt; opened an issue with detailed feedback and ideas.&lt;br &#x2F;&gt;
Even if I have no real ambition for this library, this was a fantastic moment that forced me to get back to the whiteboard. Some of his ideas were to add smart defaults with good examples. Now the crate is easy to use and understand by default, while keeping a lot of flexibility for others.&lt;&#x2F;p&gt;
&lt;p&gt;For example, we can make assumptions by just looking at the name of the struct (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MattDelac&#x2F;tiny_orm?tab=readme-ov-file#example-using-the-default-options&quot;&gt;see this example&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FromRow&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Table&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Same as adding the following manually&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; #[tiny_orm(table_name = &amp;quot;todo&amp;quot;, return_object = &amp;quot;Self&amp;quot;, exclude = &amp;quot;create,update&amp;quot;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Todo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    created_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; DateTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Utc&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    updated_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; DateTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Utc&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    done&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FromRow&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Table&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Because the struct name starts with &amp;quot;New&amp;quot;, it would automatically use the following options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; #[tiny_orm(table_name = &amp;quot;todo&amp;quot;, return_object = &amp;quot;Todo&amp;quot;, only = &amp;quot;create&amp;quot;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; The primary key will be auto-generated by the database and returned once the record is created.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; NewTodo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FromRow&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Table&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Because the struct name starts with &amp;quot;Update&amp;quot;, it would automatically use the following options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; #[tiny_orm(table_name = &amp;quot;todo&amp;quot;, return_object = &amp;quot;Todo&amp;quot;, only = &amp;quot;update&amp;quot;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateTodo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    done&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I like the idea of multiple structs for different sets of actions (e.g., adding a new record vs. updating it). It makes the code very explicit and makes certain types of mistakes impossible (eg, updating the &lt;code&gt;created_at&lt;&#x2F;code&gt; field).&lt;&#x2F;p&gt;
&lt;p&gt;It is still possible to have all the methods available in the same struct. The following would provide all CRUD methods for the unique struct Todo.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FromRow&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Table&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[tiny_orm(all)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Todo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    created_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; DateTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Utc&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    updated_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; DateTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Utc&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    done&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the end, I learned a lot from building my own Rust crates. I found that dealing with AST and macros was painful at first, but it got easier once I understood how to debug them. But that should be its own post.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Simple CRUD only using SQLx</title>
        <published>2024-03-20T00:00:00+00:00</published>
        <updated>2024-03-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/posts/simple-crud-only-using-sqlx/"/>
        <id>/posts/simple-crud-only-using-sqlx/</id>
        
        <content type="html" xml:base="/posts/simple-crud-only-using-sqlx/">&lt;p&gt;Most use cases require some simple CRUD operations. And that was true even for a new API we built that is now used by one of our user-facing products.&lt;&#x2F;p&gt;
&lt;p&gt;The goal of this article is not to debate whether using an ORM is a good or bad idea. Because there are very few resources on doing CRUD without an ORM in Rust, I wanted to share my experience.&lt;&#x2F;p&gt;
&lt;p&gt;A few guidelines we had&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Centralize insert and update logic to make it obvious&lt;&#x2F;li&gt;
&lt;li&gt;Having complete control of the SQL queries since some of the background tasks have to be optimized&lt;&#x2F;li&gt;
&lt;li&gt;Most of us have a data background (data engineering or data science), which gives us high confidence in writing good, optimized SQL queries&lt;&#x2F;li&gt;
&lt;li&gt;Prototype fast, but also build for the long term&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-example-user-model&quot;&gt;The Example: User Model&lt;&#x2F;h2&gt;
&lt;p&gt;So we organized the project without an ORM, instead implementing a structure and helpers to make CRUD operations as easy as possible.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s jump into it&lt;&#x2F;p&gt;
&lt;p&gt;Let’s take the following example.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Users&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    created_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DateTime&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    updated_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DateTime&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    preferred_color&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    last_login_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;First, we can see that only the last two fields are Optional. This means that every time you pull a row from your database, you have the certainty of which field is potentially null or not. This would be the equivalent of a &lt;code&gt;Model&lt;&#x2F;code&gt; in something like SeaOrm.&lt;&#x2F;p&gt;
&lt;p&gt;What about creating and updating a row?&lt;&#x2F;p&gt;
&lt;p&gt;I did not like the idea of a generic struct where anything could be modified (eg, &lt;code&gt;ActiveModel&lt;&#x2F;code&gt;). Instead, I want us to be very explicit about what can be created and updated. Moreover, I want to ensure we centralize the business logic for each operation.&lt;&#x2F;p&gt;
&lt;p&gt;First, let’s have a look at the following.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Users&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    created_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    updated_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    preferred_color&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    last_login_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateUsers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    preferred_color&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    last_login_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;introducing-setoption&quot;&gt;Introducing SetOption&lt;&#x2F;h2&gt;
&lt;p&gt;We can see that we wrap all of the fields that could be updated by another &lt;code&gt;Option&amp;lt;&amp;gt;&lt;&#x2F;code&gt; . The goal here is to check whether a field is set. To make things more explicit than having another &lt;code&gt;Option&amp;lt;&amp;gt;&lt;&#x2F;code&gt; . I went with the following approach&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Builder&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateUsers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    preferred_color&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    last_login_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Default&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PartialEq&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Eq&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PartialOrd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Ord&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Hash&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    NotSet&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This simple &lt;code&gt;SetOption&lt;&#x2F;code&gt; enum, working similarly to the &lt;code&gt;Option&lt;&#x2F;code&gt; enum, clearly identifies which field was set by the user intentionally and which is left. Thus, setting a field to &lt;code&gt;None&lt;&#x2F;code&gt; means creating or updating the field with a &lt;code&gt;NULL&lt;&#x2F;code&gt; value.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;builder-pattern-for-flexibility&quot;&gt;Builder Pattern for Flexibility&lt;&#x2F;h2&gt;
&lt;p&gt;You might also have noticed the macro &lt;code&gt;Builder&lt;&#x2F;code&gt; set at the &lt;code&gt;UpdateUsers&lt;&#x2F;code&gt; struct. This uses the &lt;code&gt;[builder-pattern&lt;&#x2F;code&gt; macro](https:&#x2F;&#x2F;lib.rs&#x2F;crates&#x2F;builder-pattern), which is very simple and has few dependencies. The goal is to build the &lt;code&gt;UpdateUsers&lt;&#x2F;code&gt; Struct as we go in our code. It gives us much more flexibility than having to fill out all the fields at once.&lt;&#x2F;p&gt;
&lt;p&gt;This makes the logic in the code so much easier to read.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Each of those fields could be constructed in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; different places of the code based on some logic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; update_user&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateUsers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateUsers&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;user&lt;&#x2F;span&gt;&lt;span&gt;.id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;preferred_color&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;new_color&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, centralize the business logic.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Builder&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateUsers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    preferred_color&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    last_login_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateUsers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    pub async fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;sqlx_conn&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Users&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; anyhow&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.id.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; is_not_set() is implemented at the SetOption enum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; return Err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.email.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.password.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.preferred_color.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.last_login_at.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; return Err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        let mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; sqlx&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;QueryBuilder&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;UPDATE users SET updated_at = now()&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;email&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.email {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, email = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;email&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;password&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.password {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, password = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;password&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;preferred_color&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.preferred_color {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, preferred_color = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;preferred_color&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;last_login_at&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.last_login_at {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, last_login_at = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;last_login_at&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot; WHERE id = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.id.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;()?);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; method `value() to retrieve T implemented at SetOptions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot; RETURNING *&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Return the updated row&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;build_query_as&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fetch_one&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;sqlx_conn&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;await&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;map_err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; e&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;into&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Default&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PartialEq&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Eq&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PartialOrd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Ord&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Hash&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    NotSet&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let’s look at what is happening. We first need to construct the &lt;code&gt;UpdateUsers&lt;&#x2F;code&gt; using the builder pattern, which gives us the flexibility to set any field at any time.&lt;&#x2F;p&gt;
&lt;p&gt;Then we run some sanity checks like “field ID has to be set” or “At least one of the fields has to be set, otherwise there is nothing to update”&lt;&#x2F;p&gt;
&lt;p&gt;Then we construct a query using &lt;code&gt;sqlx::QueryBuilder&lt;&#x2F;code&gt; so that we only update the fields that have been set. Also, notice that we automatically added the &lt;code&gt;updated_at&lt;&#x2F;code&gt; field so users cannot forget about it.&lt;&#x2F;p&gt;
&lt;p&gt;Even if this looks verbose, a tool like Copilot will fill in 80% of the boilerplate at the end :)&lt;&#x2F;p&gt;
&lt;p&gt;The main benefit is that all the business logic can be centralized in one place. Thus, whenever someone wants to “update a user,” we can validate as many things as we want (e.g., that the password is valid and stored as a hash).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;complete-implementation&quot;&gt;Complete Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Overall, this could look like the following.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Users&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;select_by_email&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;sqlx_conn&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;an_email&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; update_user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Updater_users&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;user&lt;&#x2F;span&gt;&lt;span&gt;.id);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;update_user&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;password&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;new_password&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;update_user&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;preferred_color&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;new_color&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; update_user&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;sqlx_conn&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;await&lt;&#x2F;span&gt;&lt;span&gt;?;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At the end, the code looks like the following.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(sqlx::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;FromRow&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Default&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PartialEq&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Eq&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Users&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    created_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    updated_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    preferred_color&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    last_login_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Builder&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; CreateUsers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Builder&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateUsers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    preferred_color&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    last_login_at&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;chrono&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;DataTime&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; NewUsers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    pub async fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;sqlx_conn&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Users&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; anyhow&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.email.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.password.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; return Err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        sqlx&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;query_as&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;            r#&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;    INSERT INTO users (email, password, created_at, updated_at)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;    VALUES ($1, $2, now(), now())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;    RETURNING *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;    &amp;quot;#&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.email.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;()?)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.password.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;()?)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fetch_one&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;pool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;await&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;map_err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; e&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;into&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UpdateUsers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    pub async fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;sqlx_conn&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Users&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; anyhow&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.id.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; is_not_set() is implemented at the SetOption enum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; return Err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.email.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.password.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.preferred_color.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.last_login_at.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;is_not_set&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; return Err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        let mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; sqlx&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;QueryBuilder&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;UPDATE users SET updated_at = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Utc&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;now&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;email&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.email {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, email = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;email&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;password&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.password {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, password = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;password&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;preferred_color&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.preferred_color {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, preferred_color = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;preferred_color&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;last_login_at&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.last_login_at {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, last_login_at = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;last_login_at&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot; WHERE id = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.id.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;()?);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; method `value() to retrieve T implemented at SetOptions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot; RETURNING *&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Return the updated row&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;build_query_as&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fetch_one&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;sqlx_conn&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;await&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;map_err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; e&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;into&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Users&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    pub async fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; select_by_id&lt;&#x2F;span&gt;&lt;span&gt;(...) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Self&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; And any other method to retrieve the users with your business logic.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; -------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SetOption util&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Debug&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Clone&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Default&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PartialEq&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Eq&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PartialOrd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Ord&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Hash&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[default]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    NotSet&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Implement `From` for `SetOption` to allow for easy conversion from a value to a `SetOption`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Mostly used by the `[into]` attribute of the builder-pattern macros&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; ```&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; let set_option: SetOption&amp;lt;i32&amp;gt; = 1.into();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; assert_eq!(set_option, SetOption::Set(1));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; ```&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; From&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; T&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Self&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        SetOption&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SetOption&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; anyhow&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            SetOption&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;) =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Ok&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            SetOption&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;anyhow!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;Value is not set&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; is_set&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            SetOption&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;) =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            SetOption&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; is_not_set&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            SetOption&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;) =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            SetOption&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;NotSet&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A few notes here&lt;&#x2F;p&gt;
&lt;p&gt;Note 1: We only use the attribute &lt;code&gt;sqlx::FromRow&lt;&#x2F;code&gt; at the &lt;code&gt;Users&lt;&#x2F;code&gt; object. This is because we never retrieve a partially created or updated user.&lt;&#x2F;p&gt;
&lt;p&gt;Note 2: For “complex” (or custom) queries, we have a &lt;code&gt;queries&#x2F;...&lt;&#x2F;code&gt; folder in which we create a struct that corresponds to the result of the query. This gives us a lot of flexibility and clarity.&lt;&#x2F;p&gt;
&lt;p&gt;Note 3: I wish I could iterate over the fields of my Struct easily to have a logic like. That would require creating a macro and parsing the AST.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; my_struct&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fields&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; This has to be set otherwise return an error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;, {name} = &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; just to illustrate the idea&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        query&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push_bind&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To conclude this article, after doing it, what are the pros and cons of this approach compared to using an ORM?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Fewer dependencies. We added smaller dependencies like &lt;code&gt;builder-pattern&lt;&#x2F;code&gt;, but the reality is that those macros are so simple that they haven’t been updated since 2021, since they are stable.&lt;&#x2F;li&gt;
&lt;li&gt;We only use some of the concepts of an ORM that we like (eg &lt;code&gt;Model&lt;&#x2F;code&gt; and &lt;code&gt;ActiveModel&lt;&#x2F;code&gt; for which I took some inspiration from (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sea-ql.org&#x2F;SeaORM&#x2F;docs&#x2F;advanced-query&#x2F;custom-active-model&#x2F;&quot;&gt;see seaORM here&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;All the business logic is centralized, and we can lock down how each object is inserted and updated&lt;&#x2F;li&gt;
&lt;li&gt;All of our custom&#x2F;complex queries are plain-based SQL, which are easy to debug and prototype first (vs converting SQL &amp;lt;&amp;gt; ORM logic back and forth)&lt;&#x2F;li&gt;
&lt;li&gt;We have total control of the queries and how we want to handle them (eg: manipulating a query to force using an index, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;We use Sqlx for everything we need (eg, Migrations, queries, transactions, etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We have to reimplement some of the boilerplate that an ORM covers, like the ability to insert or update specific fields in our database&lt;&#x2F;li&gt;
&lt;li&gt;All this custom code (or boilerplate) has to be tested&lt;&#x2F;li&gt;
&lt;li&gt;This misses the ability to generate Struct from a CLI that inspects the database (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sea-ql.org&#x2F;SeaORM&#x2F;docs&#x2F;generate-entity&#x2F;sea-orm-cli&#x2F;#generating-entity-files&quot;&gt;eg with SeaORM here&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the end, we like where we landed with our approach. We could have used something bigger, like SeaORM, but we felt that we would be embarking on too many concepts for our simple use case.&lt;&#x2F;p&gt;
&lt;p&gt;While implementing all that logic was not trivial at first (first time the team built in Rust), it was primarily because we were looking for how we wanted to structure the project (also first time building a web API for a user-facing product). Now that we have this pattern and built our experience, the second project would be much faster if we used the same approach.&lt;&#x2F;p&gt;
&lt;p&gt;This is why, I ended up creating a simple library that do just that. It’s very well tested and comes with smart default. More about it in the &lt;a href=&quot;..&#x2F;tiny-orm&quot;&gt;next post&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
