<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Noob Science</title>
    <description>The latest articles on DEV Community by Noob Science (@noobscience123).</description>
    <link>https://dev.to/noobscience123</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F961702%2Fde278eca-7a15-4597-bae5-9cf3b3912267.png</url>
      <title>DEV Community: Noob Science</title>
      <link>https://dev.to/noobscience123</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/noobscience123"/>
    <language>en</language>
    <item>
      <title>Understanding Concurrency</title>
      <dc:creator>Noob Science</dc:creator>
      <pubDate>Tue, 12 Sep 2023 20:27:47 +0000</pubDate>
      <link>https://dev.to/noobscience123/understanding-concurrency-lia</link>
      <guid>https://dev.to/noobscience123/understanding-concurrency-lia</guid>
      <description>&lt;h2&gt;
  
  
  Some Background
&lt;/h2&gt;

&lt;p&gt;Well in real life, we are often advised to do one thing at a time and do it perfectly. Did I just use the UNIX philosophy and applied it to real life? Well, yes. I am a nerd.&lt;br&gt;
Programs too, most times are better off doing just one thing and doing it perfectly.&lt;br&gt;
However, it takes a whole 360 degree turn when it comes to computing. The keyword here being computing. Not the fancy CLI's and GUI's we use. Computing is a very broad term and it includes a lot of things. One of them being concurrency.&lt;br&gt;
So let's give a text book definition first shall we:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Concurrency is the ability of different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically, the program is able to do multiple things at once. So, let's look inside this a bit more. There are two types of concurrency:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parallelism&lt;/strong&gt;: This is when the program is able to do multiple things at once. This is the most common type of concurrency. This is what we are going to be talking about in this post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous&lt;/strong&gt;: This is when the program is able to do multiple things at once, but not exactly at the same time. This is a bit more complicated and we will talk about it in a later post.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, let's get into the whole thing shall we, but first, let's talk about the anti pattern of concurrency: Synchronous programming.&lt;/p&gt;
&lt;h2&gt;
  
  
  Jargon Buster and Basics
&lt;/h2&gt;

&lt;p&gt;Before we get into the whole thing, here is a small jargon buster for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blocking&lt;/strong&gt;: Blocking is when the program is waiting for something to happen. For example, if you are reading from a file, the program will be blocked until the file is read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread&lt;/strong&gt;: A thread is the most basic unit of execution. A process can have multiple threads. Each and every thread in a memory space has access to the same memory. Hence, they can share state between each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process&lt;/strong&gt;: A process is a program that is running. A process can have multiple threads. Each process has its own memory space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daemon&lt;/strong&gt;: A daemon is a process that runs in the background.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IPC&lt;/strong&gt;: IPC stands for Inter Process Communication. It is a mechanism that allows processes to communicate with each other. This can be done using TCP/IP, Sockets, Message Queues, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operation&lt;/strong&gt;: An operation is a task that the program has to do. For example, reading from a file is an operation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Synchronous Programming
&lt;/h2&gt;

&lt;p&gt;Synchronous programming is when the program does one thing at a time. &lt;br&gt;
Let's say we have a very simple web server written in go and it has to do some algorithmic computation. So, it will do the computation and then send the response to the client.&lt;br&gt;
For every request sent, imagine an imaginary plate stack. The program will take a plate from the stack, do the computation and then send the response.&lt;/p&gt;

&lt;p&gt;Essentially when you imagine a stack of plates, you put all the plates on the fancy plate stack the pops out the plates one by one. This is how synchronous programming works. It does one thing at a time and only then exposes the next thing to do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mhJYk4g1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqv2j0tghncmbzab824j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mhJYk4g1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqv2j0tghncmbzab824j.png" alt="Synchronous Plates" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hence, if you are doing a lot of computation, the program will be blocked until the computation is done. &lt;br&gt;
Let's say that you are reading from an external API, and the API is slow. The program will essentially be blocked until the API responds. &lt;br&gt;
Hence, your program is essentially choke holding itself. &lt;br&gt;
This is where the concept of &lt;em&gt;concurrency&lt;/em&gt; comes in.&lt;/p&gt;
&lt;h2&gt;
  
  
  Concurrency
&lt;/h2&gt;

&lt;p&gt;Now imagine you &lt;strong&gt;tilt&lt;/strong&gt; the plate stack to be horizontal. You can now do multiple things at once. You can take &lt;em&gt;any&lt;/em&gt; plate from the stack and enjoy the yummy food (computations) on it.&lt;br&gt;
So, essentially, your program is no longer &lt;em&gt;blocked&lt;/em&gt; by a long computation. It can do other computations while the long computation is going on.&lt;br&gt;
In fact, it doesn't matter if the computation is long or short, the program can do other things while the computation is going on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SdH96pBv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ci0e080mu63ggae2v5nh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SdH96pBv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ci0e080mu63ggae2v5nh.png" alt="Async Programming" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hence concurrency sort of does stuff in parallel. It is not exactly parallelism, but it is close enough.&lt;br&gt;
We will be differentiating between concurrency and parallelism in a bit.&lt;br&gt;
Regardless, this pattern of programming is called &lt;em&gt;concurrent programming&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Async and Concurrent are used interchangeably, however, as I mentioned in the beginning, they are not the same thing.&lt;br&gt;
Asynchronous programming is a subset of concurrent programming.&lt;br&gt;
So what are the other subsets of concurrent programming?&lt;/p&gt;
&lt;h2&gt;
  
  
  Classification of Concurrences
&lt;/h2&gt;

&lt;p&gt;There are boardly three types of concurrent programming:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MultiThreading&lt;/li&gt;
&lt;li&gt;MultiProcessing&lt;/li&gt;
&lt;li&gt;Asynchronous&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's talk about each of them one by one.&lt;/p&gt;
&lt;h3&gt;
  
  
  MultiThreading
&lt;/h3&gt;

&lt;p&gt;MultiThreading is often confused with parallelism. However, it is not the same thing.&lt;br&gt;
MultiThreading is when you have multiple threads of execution in a single process.&lt;br&gt;
A thread is the most basic unit of execution. A process can have multiple threads.&lt;br&gt;
Each and every thread in a memory space has access to the same memory. Hence, they can share state between each other.&lt;br&gt;
This solves the problem of blocking. If one thread is blocked, the other threads can continue to do their work.&lt;br&gt;
We will be talking more about blocking in a bit.&lt;/p&gt;

&lt;p&gt;You can think of a thread as a worker. Each worker has a task to do. If one worker is blocked, the other workers can continue to do their work.&lt;br&gt;
Hence, essentially, you are running a main worker called the daemon and the daemon is &lt;em&gt;spawning&lt;/em&gt; multiple workers to do the work, while it self is not able to interfere with the worker's state.&lt;br&gt;
You might have heard of the term &lt;em&gt;daemon&lt;/em&gt; in UNIX. A daemon is a process that runs in the background.&lt;/p&gt;
&lt;h3&gt;
  
  
  MultiProcessing
&lt;/h3&gt;

&lt;p&gt;MultiProcessing is when you have multiple processes running at the same time. Each process has its own memory space and hence, they cannot share state between each other.&lt;br&gt;
This is particularly useful for a micro service like architecture. Each process can be a micro service and they can communicate with each other using some sort of IPC (Inter Process Communication) mechanism.&lt;br&gt;
These methods can vary from TCP/IP to Sockets to even message queues.&lt;br&gt;
MultiProcessing finds its use in distributed systems and in micro service architectures.&lt;/p&gt;
&lt;h3&gt;
  
  
  Asynchronous
&lt;/h3&gt;

&lt;p&gt;An async operation runs on a single thread know as the event loop. This event loop is responsible for running the async operations.&lt;br&gt;
The event loop is non blocking and hence, it can run multiple async operations at the same time.&lt;/p&gt;

&lt;p&gt;However, the async operations are not exactly running at the same time. They are running one after the other, but they are not blocking each other.&lt;br&gt;
What I mean by blocking is that the event loop is not waiting for the actual data. It operates on the &lt;em&gt;promise&lt;/em&gt; of the data. This might be a bit familiar if you have used JavaScript.&lt;br&gt;
The event loop is not waiting for the data to come back from the API. It is just waiting for the promise of the data to come back. Once the promise is fulfilled, the event loop will run something called a &lt;em&gt;callback&lt;/em&gt; function. The promise is called using the &lt;em&gt;await&lt;/em&gt; keyword in most languages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do something&lt;/span&gt;
  &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the program interperts data as a promise that will be fulfilled by the variable res. Once the promise is fulfilled, the program will run the next line of code.&lt;br&gt;
So, the program can operate on the principle of promises. This is what async programming is.&lt;/p&gt;

&lt;p&gt;This is basically like you using one company's stocks to buy another company's stocks. You are essentially operating on the promise of the first company's stocks inherent value and you will be able to buy the second company's stocks.&lt;/p&gt;

&lt;p&gt;Asynchronous is hence the most basic form of concurrency. You don't have something running in parallel technically, but sort of dismissed on the basis of the promise of the data.&lt;br&gt;
This helps the event loop to run multiple operations at the same time.&lt;br&gt;
There is a very famous talk by Philip Roberts on the event loops that gets into the nitty gritty of how the event loop works. I highly recommend you to watch it.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/8aGhZQkoFbQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I plan on doing a deep dive into async programming in a later post. So stay tuned for that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blocking
&lt;/h2&gt;

&lt;p&gt;Blocking occurs when a program is paused or held up, waiting for a specific event to complete, such as reading data from a file. During this time, the program can't proceed because it relies on the outcome of that event. Concurrency, on the other hand, is a technique that allows a program to continue executing other tasks while one or more operations are blocked, enhancing its overall efficiency.&lt;/p&gt;

&lt;p&gt;Think of it like a restaurant scenario. You're a waiter taking orders from customers and passing them to the chef. The chef prepares the dishes and hands them back to you, and you serve them to the customers. It sounds straightforward, right?&lt;/p&gt;

&lt;p&gt;However, consider a situation where a customer orders a complex dish that takes a long time to cook. In a blocking scenario, the chef would wait until that dish is ready before starting any others, causing delays. This is similar to how a program can get blocked when waiting for a time-consuming operation to complete.&lt;/p&gt;

&lt;p&gt;Now, let's introduce concurrency. If the chef decides to cook the complex dish concurrently, it means they can work on other orders while the challenging dish is being prepared. This parallels how a program can continue performing other tasks even while waiting for certain operations to finish. This ability to multitask or work in parallel, like our chef, is the essence of concurrency, making processes more efficient and responsive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding through a Go Program
&lt;/h2&gt;

&lt;p&gt;Now, let's understand this through a simple go program.&lt;br&gt;
We want to emulate a web server that some complex algorithmic computation. We will be using the &lt;code&gt;time.Sleep()&lt;/code&gt; function to emulate the computation and be calculating the time taken to do the computation.&lt;/p&gt;

&lt;p&gt;Below is an example of a synchronous program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Program started"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emulateComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emulateComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emulateComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emulateComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emulateComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Program ended in"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;emulateComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Millisecond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Computation done for "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how we must first wait for the id 1 computation to finish before we can start the id 2 computation.&lt;br&gt;
This is because the program is synchronous and it can only do one thing at a time.&lt;/p&gt;

&lt;p&gt;When we run the program, we get the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Program started
Computation &lt;span class="k"&gt;done for &lt;/span&gt;1
Computation &lt;span class="k"&gt;done for &lt;/span&gt;2
Computation &lt;span class="k"&gt;done for &lt;/span&gt;3
Computation &lt;span class="k"&gt;done for &lt;/span&gt;4
Computation &lt;span class="k"&gt;done for &lt;/span&gt;5
Program ended &lt;span class="k"&gt;in &lt;/span&gt;15.0052ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the program took 15.0052ms to complete. This is because the program is doing one thing at a time and hence, it is blocked by the computation.&lt;br&gt;
Finding the time complexity of this program is pretty easy. It is &lt;code&gt;O(n)&lt;/code&gt; where &lt;code&gt;n&lt;/code&gt; is the number of computations.&lt;/p&gt;

&lt;p&gt;Now, let's make the program concurrent. We will be using the &lt;code&gt;go&lt;/code&gt; keyword to make the program concurrent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;resch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;emulateAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;emulateAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;emulateAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;emulateAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;emulateAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nb"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;resch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;endProgram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;emulateAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resch&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Millisecond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;resch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;endProgram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Program ended in"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first one was pretty simple? I know. This one is a bit more complicated. Let's break it down.&lt;br&gt;
So, go has this concept of channels. Channels are a way to communicate between goroutines. Goroutines are like the threads in go.&lt;/p&gt;

&lt;p&gt;Essentially a channel is like a way to share state between these different goroutines. It is a type of IPC (Inter Process Communication) mechanism.&lt;br&gt;
I mean, not exactly, but it is close enough. Now, we use a waiting or a blocking mechanism to wait for the goroutines to finish.&lt;br&gt;
The &lt;code&gt;sync.WaitGroup&lt;/code&gt; is a way to wait for the goroutines to finish. The rest is handled native to go.&lt;/p&gt;

&lt;p&gt;When we run the program, we get the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Program started
Result: 1
Result: 2
Result: 3
Result: 4
Result: 5
Program ended &lt;span class="k"&gt;in &lt;/span&gt;5.0120ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hence, the total time of execution is the same as the longest computation. This is because the program is doing multiple things at once.&lt;br&gt;
While the timer is counting to 5 seconds on one thread, another thread is already done with counting 2 seconds and is waiting in the waiting group to be closed.&lt;br&gt;
The outputs are systematically put in the channel &lt;code&gt;resch&lt;/code&gt; and then the main thread prints them out using the &lt;code&gt;range&lt;/code&gt; iterator.&lt;/p&gt;

&lt;p&gt;Interesting thing to be noted here is that the order of the results is not the same as the order of the goroutines.&lt;br&gt;
This is because the goroutines are running concurrently and hence, the order of the results is not guaranteed.&lt;br&gt;
One more thing that beginners often get confused about is that the program is not running in parallel.&lt;br&gt;
It is running concurrently. Parallelism is when the program is doing multiple things at the same time.&lt;br&gt;
Concurrency is when the program is doing multiple things at once. The difference is subtle, but it is there, which we will be talking about in a later post, so stay tuned for that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where and Why to use Concurrency
&lt;/h2&gt;

&lt;p&gt;Concurrency is a very powerful tool. It can significantly improve the performance of your program.&lt;br&gt;
Concurrency might be a little harder to implement than synchronous programming, but it is worth it.&lt;br&gt;
However, it is not a silver bullet. It is not a tool that you can use everywhere. It is a tool that must be used wisely.&lt;br&gt;
For example, if you want to read from a file, you don't need concurrency. You can just read from the file asynchronously and you will be fine.&lt;/p&gt;

&lt;p&gt;Concurrency is specifically used when you have to compute almost parallel. For example, if you have to read from multiple files, you can use concurrency.&lt;/p&gt;

&lt;p&gt;With that being said, let's talk about some of the use cases of concurrency:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;WebServers: Web servers can use concurrency to handle multiple requests at the same time. This is a very common use case of concurrency. Moreover, you can also handle the loss of a thread by spawning a new thread.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lV7j3H9p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nf6vgyejdlpwb2ga5ks9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lV7j3H9p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nf6vgyejdlpwb2ga5ks9.png" alt="Web Server" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Database Management Systems: MultiThreading can be used to handle multiple queries at the same time. This makes the database more efficient and responsive.&lt;/li&gt;
&lt;li&gt;Distributed Systems: A system that can efficiently handle multiple requests at the same time is a distributed system.&lt;/li&gt;
&lt;li&gt;Video Streaming: Streaming services use concurrency to serve multiple users simultaneously. Each user's request for video content can be processed concurrently, allowing for efficient streaming.&lt;/li&gt;
&lt;li&gt;Video Games: Video games use many concurrency patterns like the actor model to handle multiple players at the same time, lobbies, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Concurrency Patterns
&lt;/h2&gt;

&lt;p&gt;Concurrency patterns are a set of patterns that are used to solve a specific problem. They are a set of best practices that are used to solve a specific problem.&lt;br&gt;
They are some very interesting and powerful patterns that are used in concurrency. I will listing some of them below, they will be explained in a later post.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Actor Model&lt;/strong&gt;: The actor model is a model of concurrent computation that treats actor as the universal primitive of concurrent computation. In response to a message that it receives, an actor can: make local decisions, create more actors, send more messages, and determine how to respond to the next message received.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread Pool&lt;/strong&gt;: A thread pool is a software design pattern for achieving concurrency of execution in a computer program. Often also called a replicated workers or worker-crew model, a thread pool maintains multiple threads waiting for tasks to be allocated for concurrent execution by the supervising program.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Futures and Promises&lt;/strong&gt;: Futures and promises originated in functional programming and related paradigms (such as logic programming) to decouple a value (a future) from how it was computed (a promise), allowing the computation to be done more flexibly, notably by parallelizing it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Executive Summary
&lt;/h2&gt;

&lt;p&gt;If you're time is limited, here is a quick summary of the post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Concurrency is the ability of different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome.&lt;/li&gt;
&lt;li&gt;There are three types of basic concurrency:

&lt;ol&gt;
&lt;li&gt;MultiThreading&lt;/li&gt;
&lt;li&gt;MultiProcessing&lt;/li&gt;
&lt;li&gt;Asynchronous&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;MultiThreading is when you have multiple threads of execution in a single process.&lt;/li&gt;
&lt;li&gt;MultiProcessing is when you have multiple processes running at the same time.&lt;/li&gt;
&lt;li&gt;Asynchronous is when you have a single thread of execution that is non blocking.&lt;/li&gt;
&lt;li&gt;Blocking is when the program is waiting for something to happen.&lt;/li&gt;
&lt;li&gt;Concurrency is when the program is able to do multiple things at once.&lt;/li&gt;
&lt;li&gt;Parallelism is when the program is able to do multiple things at the same time.&lt;/li&gt;
&lt;li&gt;Concurrency significantly improves the performance of the program.&lt;/li&gt;
&lt;li&gt;However, it is not a silver bullet. It can be a bit complicated to implement and it can be a bit hard to debug.&lt;/li&gt;
&lt;li&gt;Moreover, not everything must be concurrent. It is a tool that must be used wisely.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;So, this was the primer on concurrency. I hope you enjoyed it. I will be doing a deep dive into async programming in a later post.&lt;br&gt;
I mostly addressed some of the major questions I had when I was learning concurrency. I hope this post helped you.&lt;br&gt;
If you have any questions, feel free to reach out to me on &lt;a href="https://twitter.com/noobscienc1"&gt;Twitter&lt;/a&gt; or contact me through my &lt;a href="https://noobscience.rocks/contact"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With that being said, I hope you had a great time reading this post. Have a great day and keep reading Ishan Writes. Bye!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thanks for the enormous response I got for my posts here ❤️. I hope you enjoyed this style of blog posts, with the illustrations and weird examples. If you did, please let me know 😄.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>beginners</category>
      <category>coding</category>
    </item>
    <item>
      <title>Grow into Programming</title>
      <dc:creator>Noob Science</dc:creator>
      <pubDate>Sat, 09 Sep 2023 18:45:11 +0000</pubDate>
      <link>https://dev.to/noobscience123/grow-into-programming-250g</link>
      <guid>https://dev.to/noobscience123/grow-into-programming-250g</guid>
      <description>&lt;p&gt;This October marks 3 years since I started programming. Do I feel good? Yeah obviously! I love coding and my passion for programming has only grown since when I started. I love learning new stuff, trying to keep up with what’s new and just over all have a great time.&lt;/p&gt;

&lt;p&gt;Talking cool stuff about programming however is not why I am writing this article. The reason I am writing this article is well, I wanted to talk about something that doesn’t get said very often in programming. I &lt;em&gt;know&lt;/em&gt; I am not like a senior dev with all this cool experiences and anecdotes I can tell you, but yeah I can tell you are few anecdotes from my own learning experiences. So buckle up my friend. &lt;/p&gt;

&lt;p&gt;Programming is not something you learn. In my opinion, it is like an art form that is perfected through smart repetition and having genuine interest. Some of the best programmers I have ever had the pleasure of talking to (chatting with) are some the most humble and amazing people that really love what they do and are pretty good at it. That is something that is taken for granted quite often actually. Programming is not a skill, it is an art. Yes I know I sound like a old couple in a old museum, but I mean it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Git Checkout
&lt;/h2&gt;

&lt;p&gt;I’ll start with a very good example. If you are a programmer, you know what &lt;code&gt;git&lt;/code&gt; is. It is a version control system used for tracking changes in software development and if you are not a programmer, think of it like Google Drive for your code (I know this definition is not right, but it is not wrong as well, so 🙂). I started using GitHub quite early in my programming journey. My first repo was just to store my Firefox config. It’s been nearly 3 years since I am in the code thing and I started using commands like &lt;code&gt;git branch&lt;/code&gt;, &lt;code&gt;git checkout&lt;/code&gt; and &lt;code&gt;git stash&lt;/code&gt; just yesterday when I was working on a rust CLI that wraps around git and makes it easy for beginners to start out. That is how long is took me to even use the most basic of git features. &lt;/p&gt;

&lt;p&gt;This might seem so wrong to some of you. I mean, how can I use git without &lt;em&gt;completely&lt;/em&gt; knowing everything about it. Here’s the thing. I didn’t learn git, I grew into git. You learn something for the sake of learning it or probably because you want to. Whereas you only grow into something when you need it. It is sort of like “Necessity is the mother of all invention”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Knowing and Learning
&lt;/h2&gt;

&lt;p&gt;We often think that knowing something as completely learning it. This might be true to other sciences, but programming I feel is different. You can never really learn anything. You only know stuff and have used it enough number of times to accurately reproduce the results. That is why developers write code that is so varied. Some like to use the docs, others like to ask on forums or increase their stack overflow points, even use ChatGPT. All of these methods are valid. Because I feel that you are ultimately learning how to solve a problem. Not a learning a language.&lt;/p&gt;

&lt;p&gt;This does not mean that I am asking you to be a script kiddie, the type of programmer that cannot even import a function without autocomplete or “looking it up”. You should obviously know what you are doing and must know a language as much as possible. But here’s the thing. You should not actively seek knowing the language as the only measure of your programming skills. This again ties into the concept of not being only a “React Programmer” or just a “Flutter Dev”. I believe once you know the basics of a programming language, to write code in another one, all you should know is the syntax of that programming language. &lt;/p&gt;

&lt;p&gt;One you are familiar with &lt;em&gt;any&lt;/em&gt; programming language, trying out a new one should not be that big a deal. Just get to know the basic syntax of the language and implement some programs in it. I have a certain set of programs I write in a language before I am ready to actually use it. Doing this gives me confidence on the language and that is enough for me to start a new project in the language. Do I know &lt;em&gt;everything&lt;/em&gt; about the language? No! But I still can solve a problem in it. I use the docs, sometimes stack overflow and ever since I got the student access to GitHub Copilot, I don’t even need to exit my VSCode or Neovim to ask AI something. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are wondering why I don’t need to exit, try this. Copilot is technically still GPT. So, if you ask it a question in a comment with &lt;code&gt;q:&lt;/code&gt;, it will answer it. So, something like&lt;br&gt;
    &lt;code&gt;q: what are rust macros&lt;/code&gt; will get it to answer it like normal GPT.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, all you need to know is why you want to do something, &lt;br&gt;
the rest can be figured out along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issues
&lt;/h2&gt;

&lt;p&gt;It is wrong to assume that this is the best way to do programming.&lt;br&gt;
I have never really worked in the industry, so I don’t know how it is there.&lt;br&gt;
However, I don't think it would be &lt;em&gt;financially&lt;/em&gt; viable to learn as you go in a company.&lt;br&gt;
I mean, you are getting paid to do something, so you should know how to do it.&lt;br&gt;
However, I am not talking about the industry. Atleast for now, I program for fun, it is a hobby.&lt;/p&gt;

&lt;p&gt;So, I don’t really need to know everything about a language to use it.&lt;br&gt;
I just need to know enough to get started.&lt;br&gt;
Moreover, I am mostly a project based learner.&lt;br&gt;
I write code to solve a problem that most times is not mathematical.&lt;br&gt;
So, I can't speak for leetcoders as well.&lt;br&gt;
All these issues are not something that should stop you from learning this way, but rather short comings that should be&lt;br&gt;
addressed by you later on so that you can be a better programmer.&lt;/p&gt;

&lt;h2&gt;
  
  
  However
&lt;/h2&gt;

&lt;p&gt;I am not saying that you should not learn a language.&lt;br&gt;
You should know the language you are using.&lt;br&gt;
You should try and understand it's inner workings, how it works, what it does etc.&lt;br&gt;
Honestly, it is quite fascinating to know how a language works.&lt;br&gt;
I am currently learning rust and recently wrote my first lexer and parser.&lt;br&gt;
I am quite proud of it and I am sure I will be using it in my future projects.&lt;/p&gt;

&lt;p&gt;Hence all I am saying is that start to treat programming like an art form more than a skill.&lt;br&gt;
An art is something you can work on for years and still not be perfect.&lt;br&gt;
An art is something that you can never really learn, you can only grow into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to grow into a language
&lt;/h2&gt;

&lt;p&gt;Well the idea behind it is quite simple. Don't focus on the language, focus on the problem.&lt;br&gt;
If you are trying to solve a problem, you will automatically learn the language.&lt;/p&gt;

&lt;p&gt;I mean, let's say that you are writing a parser in rust.&lt;br&gt;
Don't start by learning the whole of rust. Know a little bit about it, just enough to get started.&lt;br&gt;
Then start writing the parser. Oh so what do you need for the parser? You need to know how to read a file.&lt;br&gt;
Okay, cool. Read about the &lt;code&gt;fs&lt;/code&gt; module in rust. Then you need to know how to build a Abstract Syntax Tree.&lt;br&gt;
Okay, cool. Read about the &lt;code&gt;enum&lt;/code&gt; and &lt;code&gt;struct&lt;/code&gt; in rust.&lt;br&gt;
You get the idea. You are learning the language as you go.&lt;/p&gt;

&lt;p&gt;You are not opening up the docs and reading the whole thing like reading your favourite novel.&lt;br&gt;
Once you have written the parser, you will know a lot about rust.&lt;br&gt;
This is because you have used it and you have used it enough number of times to know it.&lt;br&gt;
That is how you grow into a language.&lt;br&gt;
You don't learn it, memorize it and then use it.&lt;br&gt;
You use it and then you automatically learn it.&lt;/p&gt;

&lt;p&gt;Similarly, you don't need to know every command and every vim movement to start using vim.&lt;br&gt;
I mean, the only thing you need to know is how to exit vim. That too you know only because you entered vim in the first place.&lt;br&gt;
So, don't just be stuck and sucked into these online courses that teach you how to code.&lt;br&gt;
They are useful no doubt, but they are not the only way to learn programming.&lt;br&gt;
An artist can never really learn how to draw. He just draws and draws and draws.&lt;br&gt;
He grows into it. He learns how to draw a face, then a body, then a landscape and so on.&lt;/p&gt;

&lt;p&gt;So, to all my fellow code artists (cringey I know), keep on coding and keep on growing.&lt;br&gt;
I know I want to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The End
&lt;/h2&gt;

&lt;p&gt;So, the next time you see someone who asks you which is the best way to learn a language, tell them that there is no best way.&lt;br&gt;
There is only the way that works for you. If you are a person who likes to learn a language before using it, go ahead.&lt;br&gt;
I am not saying that is wrong. I am just saying that it is not the only way to learn programming.&lt;br&gt;
You can learn programming by just doing it. You can learn programming by just solving problems.&lt;/p&gt;

&lt;p&gt;One more small disclaimer. This is purely my opinion and &lt;strong&gt;not a fact&lt;/strong&gt;.&lt;br&gt;
At this point I am just rambling on and on about how I feel about programming.&lt;br&gt;
All these might be wrong and I might be a complete idiot and that's okay. So, yeah.&lt;br&gt;
Take everything I say with a grain of salt. I am just a 18 year old kid who likes to code. &lt;br&gt;
I am not a senior dev or anything. I mean, I want to be one, but I am not one right now.&lt;br&gt;
Maybe when I like 30 or something, I will look back at this article and laugh at myself. Who knows?&lt;br&gt;
Then I'll probably write another article about how I was wrong and how I have grown as a programmer.&lt;br&gt;
Till then, I'll just keep on coding and keep on growing (That should totally be a song or something).&lt;/p&gt;

&lt;p&gt;Thanks for reading this article. I hope you liked it. If you did, please consider sharing it with your dev friends or on social media.&lt;br&gt;
It would mean a lot to me. If you have any suggestions or feedback, please let me know in the comments below.&lt;br&gt;
Hope you have a great day :)&lt;/p&gt;

</description>
      <category>programming</category>
      <category>coding</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Chad-ifying My Web Tools</title>
      <dc:creator>Noob Science</dc:creator>
      <pubDate>Wed, 06 Sep 2023 19:28:55 +0000</pubDate>
      <link>https://dev.to/noobscience123/chad-ifying-my-web-tools-4ckc</link>
      <guid>https://dev.to/noobscience123/chad-ifying-my-web-tools-4ckc</guid>
      <description>&lt;p&gt;I am almost certain that if you are a web dev, actually scrap that, if you are a developer, you at some point or the other have &lt;br&gt;
built at least one of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A URL shortener&lt;/li&gt;
&lt;li&gt;Paste bin&lt;/li&gt;
&lt;li&gt;Markdown editor&lt;/li&gt;
&lt;li&gt;Todo list&lt;/li&gt;
&lt;li&gt;A CLI (Any CLI, it doesn't matter)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These might seem very superficial and useless, but they are far from that. So this post is to show you how I built my own versions of these tools, and how you can too. Maybe this article will inspire you to finally dig open the grave of that URL Shortener you started 2 years ago and never finished. However, along the way, you might end up making some mistakes that I made, and I hope this article will help you avoid them. With that out of the way, let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I have built
&lt;/h2&gt;

&lt;p&gt;Well I have built a lot of things, most of them not worthy of being mentioned here. I am primarily a project based learner, so I learn by building things. I honestly have a folder called "graveyard" where I keep all my failed projects. But I have built a few things that I am proud of, and I will be talking about them here. Most of these tools are public, you can give them a try if you want. All of these are open source of course, and I will link the source code in the respective sections. They are also quite easy to build yourself. I will be mentioning the architecture of these tools as well so you can build your own versions of them. However, you are free to also just fork my repos and build on top of them. I will be happy to see what you build.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://noobscience.rocks/go" rel="noopener noreferrer"&gt;NoobShort&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;NoobShort is one project that I have a lot of memories with. It was first a very simple &lt;strong&gt;URL Shortener&lt;/strong&gt; built using Flask and Postgres. It was a very simple project, but it was one of my &lt;br&gt;
first major projects that I actually deployed. Back when heroku was free, it was called Shortpaw. You can actually still find the original source code [here (&lt;a href="https://github.com/newtoallofthis123/shortpaw" rel="noopener noreferrer"&gt;https://github.com/newtoallofthis123/shortpaw&lt;/a&gt;). When heroku ended their free tier, I sort of abandoned it and started using other URL shorteners. Shortpaw was an excellent learning experience for me. With a lot of hard work I introduced reactiviy to the app, using jquery and ajax. I also learned how to use Postgres and Flask. This was a precursor to all the comforts that React and Next.js provide.&lt;/p&gt;

&lt;p&gt;A while ago, when I was learning Next.js, I decided to build a URL shortener again. This time I decided to use Next.js and MongoDB. I also decided to make it a bit more advanced. I coded an API and a beautiful frontend using tailwindcss and that was it for a while. Looking back, it was quite cool that I used a stack that is so easily deployable, nearly free. So when I got my domain noobscience.rocks and started building a portfolio site, I just decided to leave it as a subsection of my portfolio site. I also decided to make it open source. You can find the source code &lt;a href="https://github.com/newtoallofthis123/noobscience/tree/main/src/pages/go" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When I migrated my site to Astro, I just split it into API and frontend components. The frontend form is now a component that I can use anywhere. The API is part of Astro's serverless functions.&lt;br&gt;
I decided to not allow anyone to custom slug URLs, because I didn't want to deal with the hassle of moderating them.&lt;br&gt;
I also added a small rust CLI for it which makes it very easy to use. You can find the CLI [here (&lt;a href="https://github.com/newtoallofthis123/short_cli%22" rel="noopener noreferrer"&gt;https://github.com/newtoallofthis123/short_cli"&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwh7t9frwxotun1okwieb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwh7t9frwxotun1okwieb.png" alt="NoobShort"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is how it looks. It is quite simple, but it works. I have also added a few features like custom slugs, and a few other things. I will be adding more features in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://noobscience.rocks/code" rel="noopener noreferrer"&gt;NoobPaste&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You know how you have that one project that has so much nostalgia attached to it that you just can't let it go? Well NoobPaste is that project for me. It was one of my first projects that I actually deployed. It is once again built using Flask and Postgres. It is a very simple &lt;strong&gt;Paste Bin&lt;/strong&gt; that allows you to paste code and share it with others. It is very simple, but it works. I have used it a lot of times to share code with my friends. Then original app was a huge flask app with a lot features like a full code editor, syntax highlighting, and a lot of other things. I have since then stripped it down to the bare minimum. You can find the original source code &lt;a href="https://github.com/newtoallofthis123/NoobPaste" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now however, it is a very simple and beautiful frontend built using tailwindcss and a very simple API built using Next.js and MongoDB. I added the ability to handle all the code snippets from my custom built rust CMS which I will talk about in one my previous posts. One of the most nostalgic things about this project is that I used to use it to share code with my friends.&lt;br&gt;
I pretty much still use it for the majority of my code sharing. &lt;br&gt;
This is how it looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kcsbibw8atr24igkh1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kcsbibw8atr24igkh1c.png" alt="NoobPaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope you are able to see a pattern here. I am a huge fan of simple and minimalistic UIs. I also like to keep my projects as simple as possible. I don't like to add a lot of features to my projects. Why? Well I'll be talking about that in a bit.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://noobscience.rocks/htmler" rel="noopener noreferrer"&gt;HTMLEr&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Any markdown app that you use is probably a 100 MB download. I don't know why, but they are. I don't like that. I don't like downloading a 100 MB app just to write markdown! So, I decided to build my own markdown editor. I decided to call it HTMLEr. It is a very simple &lt;strong&gt;Markdown Editor&lt;/strong&gt; built using plain HTML and JS. Okay I added a little of Tailwind CSS, but that's it. I promise. The source code is very simple so if you are interested, you can check it out &lt;a href="https://github.com/newtoallofthis123/htmler" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
It uses the &lt;code&gt;marked.js&lt;/code&gt; library to convert markdown to HTML. I in fact am using it to write this article. It is very simple, but it works. The best feature? Every click is a save. So you don't have to worry about losing your work. Everything and I mean everything is saved in the local storage. So you can close the tab, close the browser, restart your computer, and your work will still be there. &lt;br&gt;
You can even save it as a file. It is very simple, but it works. This is how it looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4up8whfkac2t0l77u959.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4up8whfkac2t0l77u959.png" alt="HTMLEr"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quite fun and minimalistic right? I love it.&lt;br&gt;
It is like my go to writing app. Best part? I just have to open a URL. No downloads, no installations, nothing. Just a URL. I love it. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/newtoallofthis123/noob_key" rel="noopener noreferrer"&gt;NoobKey&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;NoobKey is a very simple Key Value store built using Rust. &lt;br&gt;
It wrote a lot about it in my previous post. You can check it out &lt;a href="https://noobscience.rocks/blog/tutorials/rust-cli" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built these tools
&lt;/h2&gt;

&lt;p&gt;The internet is full of tools. There are so many. You have something for everything. Want to unwrap a JSON? There is a tool for that. Want to convert a PDF to a Word Document? There is a tool for that. It is a wonderful eco system that we have built. But there is one problem. Most of these tools are either paid or have a lot of ads. I don't like that. I don't like paying for things that I can build myself. That is just a personal preference. &lt;/p&gt;

&lt;p&gt;Keeping aside the fact about paying, there is something else that we need to take into consideration. Privacy. Most of these tools are not open source. So you don't know what they are doing with your data. URL's for example are a &lt;em&gt;very&lt;/em&gt; private thing to share. You key value store is also a very private thing. You don't want to share it with anyone. So why would you use a tool that you don't know what it is doing with your data? It is a very different story if the tool you are using is open source. But most of them are not. So I decided to build my own tools. I decided to build tools that I can trust. Tools that I know are not doing anything with my data. Because I own my data. I even took it one step further and even bought my own domain.&lt;/p&gt;

&lt;p&gt;I trust my tools because they are after all, my tools. If I didn't like a feature, it is a commit away. If I suddenly find the whole UI ugly, that too, is just a commit away. Moreover, once I figure out the API's and stuff, I can use them in my other projects as well. I can use my URL shortener in my portfolio site. I can use my paste bin to share code with my friends. It just feels so empowering to have your own tools. It is like having your own super powers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advice
&lt;/h2&gt;

&lt;p&gt;While building these tools, I have made a lot of mistakes. Here are a few lessons that I learned along the way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep it simple stupid
&lt;/h3&gt;

&lt;p&gt;Keep your tools as minimal as possible. There is no need to add authentication, or a CRUD API, or a lot of other things. Keep it simple. Keep it minimal. You want to build a URL shortener? Just build a URL shortener. Don't unnecessarily add a lot of features. You can always add them later if you want to. For example, my pastebin doesn't need a code editor. It is a pastebin. It is supposed to be minimal and fast. Just a &lt;code&gt;textarea&lt;/code&gt; where I can paste my code and share it quickly with a very easy to access URL.&lt;br&gt;
The syntax highlighting too is not very customizable. I just use a single &lt;code&gt;highlight.js&lt;/code&gt; theme. I don't want to add a lot of themes either.&lt;/p&gt;

&lt;p&gt;The more you try and add features, the more you will get distracted. The point is not to have a sass product that you can sell. The point is to have a tool that you can use. The keyword being just &lt;code&gt;you&lt;/code&gt;. You don't need to build a product. You just need to build a tool that you can use. So keep it simple. Keep it minimal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't over engineer
&lt;/h3&gt;

&lt;p&gt;Choose a very simple and easily deployable stack. I chose Next.js and MongoDB. It is very easy to deploy. I can deploy it on Vercel for free and don't have to worry about it. Not need to worry about scaling, misusing resources, or any of the stuff that I would have had to worry about if I had used something like Django or Express.&lt;br&gt;
Similarly, I use Rust for building my CLI tools because it just works. I have never had a rust tool fail on me. It is very easy to build and install. Portable, functional and fast.&lt;br&gt;
That is all I need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't over optimize
&lt;/h3&gt;

&lt;p&gt;It is okay if your tool is not the most fastest, SEO optimized, or the most beautiful.&lt;br&gt;
Remember you are the only one who is going to be using it. Yes other people can, but that is not the point. The point is to build a tool that you can use. If other people start using it, good for you. But that is not the point. The point is to build a tool that you can use. So don't worry about SEO, or performance, or any of that stuff.&lt;/p&gt;

&lt;p&gt;Remember it is &lt;em&gt;your&lt;/em&gt; tool so you can always optimize it later if you want to, but you don't need to. If you chose a simple stack, you probably have enough server resources to not worry about performance. Remember your tools is not a product. It most probably wont' have a lot of concurrent users and that is okay.&lt;/p&gt;

&lt;h3&gt;
  
  
  It is for you
&lt;/h3&gt;

&lt;p&gt;Not for anyone else. You are building this tool for yourself. So don't worry about what other people think. If you want to add a feature, add it. If you don't want to, don't.&lt;br&gt;
For example, I always found the QR code feature in URL shorteners to be very useless. I never used it. So I didn't add it. I don't care if other people want it. I don't want it, so my tool doesn't have it. Yes, it really does feel that powerful. You can build your own tools, and you can build them however you want. &lt;/p&gt;

&lt;h3&gt;
  
  
  Don't be afraid to change
&lt;/h3&gt;

&lt;p&gt;Delete the whole project if you want to. It is your project. Let it grow with you. If you want to change the stack, change it. If you want to change the UI, change it. Let your tools reflect your unique personality. Give them space to breath. They are not putting bread on your table and are not supposed to. They are just tools that you can use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Observations
&lt;/h2&gt;

&lt;p&gt;My work flow with these tools is quite simple actually. I use my URL shortener to shorten all my URLs. I use my paste bin to share code with my friends. The markdown editor is what I use to write all my articles. I use my key value store to store all my keys and secrets. The Custom rust CMS that I built is used to manage the whole MongoDB.&lt;br&gt;
Hence, I don't need to build a lot of features into my tools. I don't need to add authentication, or a lot of other things. &lt;br&gt;
ALl my tools don't even have the option to delete anything because I don't need a bloated UI for that, nor do I need to worry about security of my data. If I want to delete something, I just use the CMS CLI to delete it. It is that simple.&lt;/p&gt;

&lt;p&gt;Moderation? What even is that? I obviously won't be sharing any illegal stuff on my tools, but still, the feeling of not being moderated is quite liberating. What about me being a bad actor? Well first up, all of my tools are open source. So you can see what they are doing. Second, I am not a bad actor. I don't want to be one. All this is quite cool and all but what about others being bad actors? Well, the DB is in my control. I can always delete stuff if I want to. In fact, about once every month, I just delete the last 100 entries of my URL shortener. I don't need them. I don't want them. So I just delete them. It is that simple.&lt;br&gt;
Some of the more permanent stuff like my keys and secrets are stored in my key value store. I don't need to delete them. I just update them if I want to.&lt;br&gt;
It is honestly so cool.&lt;/p&gt;

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

&lt;p&gt;Well, this was once again, one of those weird posts that I just wanted to write. I hope you enjoyed it. I hope you are inspired to build your own tools. If you do end up building something, do let me know in the comments. I would love to see what you build. I hope you learned something from this post. It is always liberating to start having your own spaces on the web, be it a blog or a tool. It is a very different feeling. I hope you get to experience it and I hope you enjoy it as well.&lt;br&gt;
So, I hope I have inspired you enough to start digging your old projects and start building your own tools. Remember, it is not about someone else using your tools. It is about you using your tools. So, build it in such a way that you can use it. Making it public is just a bonus. So, go ahead and build your own tools. I hope you have fun doing it. I know I did.&lt;br&gt;
Thanks for reading. Have a nice day. Bye.&lt;/p&gt;

&lt;h2&gt;
  
  
  PS
&lt;/h2&gt;

&lt;p&gt;Here are the links to all the tools that I mentioned in this post:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://noobscience.rocks/go" rel="noopener noreferrer"&gt;NoobShort&lt;/a&gt; | &lt;a href="https://github.com/newtoallofthis123/short_cli" rel="noopener noreferrer"&gt;CLI&lt;/a&gt; | &lt;a href="https://github.com/newtoallofthis123/noobscience/tree/main/src/pages/go" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://noobscience.rocks/code" rel="noopener noreferrer"&gt;NoobPaste&lt;/a&gt; | &lt;a href="https://github.com/newtoallofthis123/noobscience/tree/main/src/pages/code" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://noobscience.rocks/htmler" rel="noopener noreferrer"&gt;HTMLEr&lt;/a&gt; | &lt;a href="https://github.com/newtoallofthis123/htmler" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/newtoallofthis123/noob_key" rel="noopener noreferrer"&gt;NoobKey&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Small disclaimer before using them though. All of their content is &lt;em&gt;clearly&lt;/em&gt; visible to me. So don't share anything that you don't want me to see. I don't care about your data, but I can see it and I am not comfortable with that.&lt;br&gt;
Care about your data. Be safe. If you want to use them, I recommend you fork them and build your own versions. I will make a future blog post or maybe a doc on how to do that.&lt;br&gt;
Keep upto date with my blog to know when that happens. Thanks for reading. I hope you find my tools useful. I know I do.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Migrating My Site To Astro</title>
      <dc:creator>Noob Science</dc:creator>
      <pubDate>Wed, 06 Sep 2023 16:34:45 +0000</pubDate>
      <link>https://dev.to/noobscience123/migrating-my-site-to-astro-37ic</link>
      <guid>https://dev.to/noobscience123/migrating-my-site-to-astro-37ic</guid>
      <description>&lt;p&gt;It feels good doesn't it? You've just finished building your website and you're ready to show it off to the world. You've got your domain, your hosting, and your site is live. When we as developers build a website, we expect it to work seamlessly for the rest of time. Now this might be true for a static website, which is hosted on a CDN and doesn't have any backend code. However, most sites now a days are dynamic, and have some sort of backend code, which is where the complexities of maintainance come in. Now it is not really the backend which is to blame. Sometimes find even the frontend to be a pain to maintain. Especially the front ends which are built using meta frameworks like Gatsby, Next, Nuxt, etc. Dynamic and interactive websites are great, but they come with a cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I was Migrating My Site
&lt;/h2&gt;

&lt;p&gt;This was when my site was built using Next.js and I was using a custom CMS I made using MonoDB to manage the content. Now this was a very small dynamicity, but it was still a pain to maintain. I also had to make sure that I don't exceed the free tier of MongoDB Atlas, which was a pain. I had to make all sort of changes to the SWR hooks to make sure that the site doesn't make too many requests to the database. After all this too, the site was rather slow at times and on top of that, the site was 500GB in size.&lt;/p&gt;

&lt;p&gt;The thing was, the reason I had to introduce this dynamicity was because I wanted to make the content on my site easily manageable.&lt;br&gt;
I wanted to be able to add new quips (called updates) to my site without having to make a new commit to my site. However, this would be one of the best examples of over engineering.&lt;br&gt;
I didn't have to make a whole CMS for this. Now trust me, it was fun to make the CMS, but it was not worth it. It slowed my site terribly and most of the libraries that were used to render the markdown I was storing in the database were not working properly with Next.js's new server components. Moreover, as I will be talking more about later, writing the code using messy scss and weird React hooks made the code really hard to maintain. I realized that in the age of static site generators, I was using a meta framework to build a simple site, with very little dynamicity.&lt;/p&gt;

&lt;p&gt;So, I decided to migrate my site to a static site generator. The only question was which one?&lt;/p&gt;
&lt;h2&gt;
  
  
  Why I Chose Astro
&lt;/h2&gt;

&lt;p&gt;I had used Gatsby in the past, but I didn't really enjoy it. Gatsby is an excellent for high performance, commercial sites, but it is not really suited for personal sites. I mean, it is, but it was not for me. It was a bit too complex to set up. Powerful, but complex. This would then, once again lead to over engineering. Hence, I wanted to use something which was simple, yet powerful.&lt;br&gt;
I had already learned and proved that I could build a site using Next.js, so I wanted to try something new. I had heard about Astro, and I decided to give it a shot.&lt;/p&gt;

&lt;p&gt;Astro is a static site generator which is really unique. It provides a lot of features which are not available in other static site generators. For one, it feels very natural for a Web developer to use Astro. You can write normal HTML, CSS, and JS in Astro. However, what makes Astro unique is that it allows you to use React components in your HTML. Not just react components, but you can use any framework in your HTML. This is because Astro is framework agnostic. This means that you can use any framework you want in your Astro site. Astro uses the concept of islands, which are basically components that can be rendered using a framework of your choice. This is a much cleaner way of doing things, as you don't have to worry about all the messy code.&lt;/p&gt;

&lt;p&gt;Hence, Astro seemed like a good choice for me. So, with that, I started migrating my site to Astro. However, before that, I needed to identify the pain points in my site. This would help me not make the same mistakes again. With that, let's talk about the pain points I identified in my site. &lt;/p&gt;
&lt;h2&gt;
  
  
  The Pain Points
&lt;/h2&gt;

&lt;p&gt;In any analysis, the first step is to identify the pain points. Now, you might multiple pain points in your site, but you need to identify the ones which are the most important. So pain points I found in my site were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Migrating from page/ to app/ in Next.js&lt;/li&gt;
&lt;li&gt;The messy scss&lt;/li&gt;
&lt;li&gt;Long repetitive code&lt;/li&gt;
&lt;li&gt;Really slow build times&lt;/li&gt;
&lt;li&gt;Easily Breakable code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now these all might sound sort of a given, but let me explain why these were pain points for me. First off, with the release of Next.js 13.4 and the release of the app/ directory, I had to migrate my site from page/ to app/. This was easier said then done, as I had a lot of problems with the messy scss my was using.&lt;br&gt;
This led me to using weird React hooks to make sure that the site was responsive. It was now a pain to migrate to the new server components, as I had to make sure that the site was responsive.&lt;br&gt;
This led to a whole lot of making new directories, layouts and components.&lt;br&gt;
I actually did the whole thing before finally deciding that this site was not worth maintaining. This is what the final result would be if you don't take proper steps to write clean and maintainable code.&lt;/p&gt;

&lt;p&gt;You might have different pain points, but these were the ones I had, which turn out to be quite common in Next.js sites. So, let's talk about how I solved these pain points.&lt;/p&gt;
&lt;h2&gt;
  
  
  How I Solved These Pain Points
&lt;/h2&gt;

&lt;p&gt;The first pain point was the migration from page/ to app/. This was solved de facto by moving to Astro. Astro has a much cleaner syntax and a much cleaner way of doing things. It uses the concept of islands, which are basically components. These islands can be used to create layouts, pages, and components. This is a much cleaner way of doing things, as you don't have to worry about the messy scss. You can just use the built in classes to style your site. This was perfect for me, so I decided to move to Astro.&lt;/p&gt;

&lt;p&gt;The second pain point was the messy scss. The main issue I faced was that I had written a lot of weird React Hooks to manage the responsiveness of the site. This was primarily because I was writing bad css and scss. So, for my new site, I decided to use Tailwind CSS. I had used tailwindcss in the past, but I didn't really enjoyed it.&lt;br&gt;
However, I decided to give it another shot and I'm glad I did.&lt;br&gt;
I now use Tailwind CSS as my de facto css framework.&lt;/p&gt;

&lt;p&gt;The third pain point was the long repetitive code. This was solved by using the concept of islands in Astro. I now have a layout for my blog posts, a layout for my projects, and a layout for my home page. This has made my code much cleaner and much more maintainable. I also have a layout for my 404 page, which is a nice touch. Tailwind CSS also helps with this, as I don't have to write long repetitive css code. I can just use the built in classes to style my site.&lt;/p&gt;

&lt;p&gt;The fourth pain point was the really slow build times. This was solved by using Astro. Astro has a really fast build time, which is a huge plus. It also has a really fast dev server, which is also a huge plus. This has made my development process much faster and much more enjoyable. I can now make changes to my site and see them instantly. The build time was very slow in Next.js, which was a huge pain.&lt;/p&gt;

&lt;p&gt;The fifth pain point was the easily breakable code. Till now, Astro has been really good at this. I haven't had any issues with the code breaking. Tailwind CSS also helps with this, as I don't have to worry about the css breaking. All in all, Astro is an amazing framework and I'm glad I decided to use it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploying The Switch
&lt;/h2&gt;

&lt;p&gt;Now that I had decided to move to Astro, I had to figure out how to deploy it. I had initally planned on using netlify and I had even set up a netlify.toml file. But, I decided to go with Vercel, as I found it to be much easier to use.&lt;/p&gt;

&lt;p&gt;I had to make a few changes to my site to make it work withVercel. Which was relatively very easy. All you had to do is the vercel's server adapter and you're good to go. &lt;br&gt;
Which you can do by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx astro add vercel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's that simple.&lt;br&gt;
The vercel server adapter, however, only starts to work when you deploy your site. So, you'll have to deploy your site to see it in action. When you are developing locally, you can use the default server adapter, which is the node server adapter.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, is Astro it?
&lt;/h2&gt;

&lt;p&gt;Well, it is hard to say. I have been using Astro for a while now and I have to say, I'm really enjoying it. It had been far easier to maintain my site with Astro than it was with Next.js.&lt;br&gt;
However, this is true for a site with very little dynamicity.&lt;br&gt;
When I am working on a site with a lot of dynamicity, I will probably use Next.js. It is just easier to do so.&lt;/p&gt;

&lt;p&gt;However, if you are working on a site with very little dynamicity, Astro is the way to go. It is much easier to maintain and it is much easier to deploy. Moreover, if you site has no dynamicity at all, you can also deploy it as a static site. This is a huge plus, as you don't have to worry about the server costs. You can just deploy it as a static site and you're good to go.&lt;/p&gt;

&lt;p&gt;However, I can't say that Astro is the best framework out there.&lt;br&gt;
The JavaScript ecosystem is huge and there are a lot of frameworks out there. It is continuously evolving and there are a lot of new frameworks coming out every day. So, my advice would be to try out a few frameworks and see which one works best for you. The thing however, is that with so many frameworks out there, it is quite easy to migrate from one to another. This is because most of the frameworks use the same concepts. So, if you know one framework, you can easily migrate to another.&lt;/p&gt;

&lt;h2&gt;
  
  
  My site now
&lt;/h2&gt;

&lt;p&gt;So, this site you are currently reading is built using Astro.&lt;br&gt;
I use a few islands to create the layout of the site.&lt;br&gt;
Most importantly the Nav, Footer. I have still kept a few pages from the old site, like the updates and the url shortener.&lt;br&gt;
These have the same database as the old site, so I didn't have to change anything. I just had to make sure that they are migrated to Astro and rewritten using tailwindcss. This site is till in beta, but Astro has helped me add a lot of new features to it.&lt;br&gt;
I was also able to improve it's SEO and performance a lot.&lt;br&gt;
Since most of the site is static, it is also very fast.&lt;/p&gt;

&lt;p&gt;You might have also noticed the blog you are currently reading.&lt;br&gt;
I am quite proud of it. I was able to incorporate suggested posts, tags, and a lot of other features. I was also able to improve the SEO of the blog a lot. So, you now get the title and image of the blog when you share it on social media. This is a huge plus, as it helps with the discoverability of the blog. One more thing that Astro helped me is with the code blocks. I was able to add syntax highlighting to the code blocks, which is a huge plus.&lt;br&gt;
This makes the blog much more readable and much more enjoyable.&lt;/p&gt;

&lt;p&gt;I am quite happy with the way the site has turned out. I'll write another post about the site when it is out of beta. &lt;/p&gt;

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

&lt;p&gt;So, that's it for this post. I know this post was relatively weird, but I just wanted to share my experience with Astro. The main takeaway from this post is that you should try out a few frameworks and see which one works best for you. Also, I hope my method of identifying pain points and solving them was helpful.&lt;br&gt;
If you have any questions, feel free to reach out to me on &lt;a href="https://twitter.com/noobscience1"&gt;Twitter&lt;/a&gt;. Also, if you want to check out my site which I built using Astro, you can do so &lt;a href="https://noobscience.rocks"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading, Hope you have a great day!&lt;/p&gt;

</description>
      <category>astro</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Writing your own CLI in rust</title>
      <dc:creator>Noob Science</dc:creator>
      <pubDate>Tue, 05 Sep 2023 12:56:09 +0000</pubDate>
      <link>https://dev.to/noobscience123/writing-your-own-cli-in-rust-3jn3</link>
      <guid>https://dev.to/noobscience123/writing-your-own-cli-in-rust-3jn3</guid>
      <description>&lt;p&gt;The world of the terminal is beautiful and I always love dwelling in it. Away from the small old experience of the web which I am finding is quite “routine” now a days, you can build a little corner where you are in &lt;em&gt;total control&lt;/em&gt;. So, here is a small tutorial on building your own small CLI in rust. I’ll be going through how to prettify the output, connections and more. So, let’s get started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;br&gt;
This tutorial is by no means to a complete guide. This is just to show you the basic way you can approach making a CLI and how to sort of &lt;br&gt;
go about making it. This article also presumes that you have a good enough knowledge of the rust language. If you don’t, I recommend you check out the official rust book. It is a very good resource for learning rust. You can find it here: &lt;a href="https://doc.rust-lang.org/book/"&gt;https://doc.rust-lang.org/book/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What are we building?
&lt;/h2&gt;

&lt;p&gt;So, what we are going to build is actually quite simple and you might actually find it useful. We are going to build a “Key-Value” Store. So, the concept is quite simple. We have 5 commands&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a Key-Value [C]&lt;/li&gt;
&lt;li&gt;Read a Value from Key [R]&lt;/li&gt;
&lt;li&gt;Update a Value from Key [U]&lt;/li&gt;
&lt;li&gt;Delete a Value from key [D]&lt;/li&gt;
&lt;li&gt;Search a Key / Value [S]&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The classic CRUDS App.&lt;br&gt;
So, this is how we are going to do this.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enter Rust
&lt;/h2&gt;

&lt;p&gt;We will be using rust. Rust is a very simple to use memory and type safe language that is excellent for building cool and reliable CLI’s. In fact it has quickly become the number one tool for building CLI’s. I’ll dive into more on why rust CLI’s are good in a future blog post, so stay tuned for that.&lt;br&gt;
So, with that, let’s get our project set up.&lt;br&gt;
Install rust on your machine if you have not already. You can do so by visiting&lt;br&gt;
&lt;a href="https://rust-lang.org/"&gt;Rust Programming Language&lt;/a&gt;&lt;br&gt;
and just downloading rust for your platform.&lt;br&gt;
Once that is done, just head over to your terminal. The terminal is an excellent way to interact with your computer. If you want to know the basics, there are plenty of resources on YouTube, below is one I recommend from freeCodeCamp.&lt;br&gt;
With that, &lt;code&gt;cd&lt;/code&gt; into a new directory and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo init &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--bin&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"nkv"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We are using &lt;code&gt;--bin&lt;/code&gt; to signify to cargo that we will be using this as a binary rather than a crate, just to make it clear.&lt;br&gt;
Now, open this up in your favourite text editor. I personally use VSCode (I know shocking), but rust has a very good ecosystem for Neovim and Emacs as well.&lt;br&gt;
Now, create all the files shown below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5y1lmf49--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9w7zts7n1r2vudtxr1e5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5y1lmf49--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9w7zts7n1r2vudtxr1e5.png" alt="File Structure" width="706" height="885"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don’t worry, you don’t need to have SQLITE3 installed to have this work. We will be directly using rust a crate. Let’s just quickly go over the file structure:&lt;/p&gt;

&lt;p&gt;We are going to have four files in the &lt;code&gt;src&lt;/code&gt;, including the &lt;code&gt;main.rs&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;db.rs: Handles database connections and the CRUD operation’s brain&lt;/li&gt;
&lt;li&gt;handler.rs: Essentially acts as a middle ware&lt;/li&gt;
&lt;li&gt;utils.rs: For some cool utility functions like copying, hash generation etc.&lt;/li&gt;
&lt;li&gt;.env file to store our Database address&lt;/li&gt;
&lt;li&gt;main.db, which is our dev database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you have created these files, it is time to install some crates. Crates are independent rust libraries that provide additional features on top. They are built and maintained by the community and are very useful. It is very easy to install them in your rust project. Just head over to &lt;code&gt;cargo.toml&lt;/code&gt; and under &lt;code&gt;[dependencies]&lt;/code&gt;, just paste the dependency name. I’ll be listing what we are using below, however, if you want to find more rust crates, I recommend you check out the GitHub List linked below.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rust-unofficial"&gt;
        rust-unofficial
      &lt;/a&gt; / &lt;a href="https://github.com/rust-unofficial/awesome-rust"&gt;
        awesome-rust
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A curated list of Rust code and resources.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Awesome Rust &lt;a href="https://github.com/rust-unofficial/awesome-rust/actions/workflows/rust.yml"&gt;&lt;img src="https://github.com/rust-unofficial/awesome-rust/actions/workflows/rust.yml/badge.svg?branch=main" alt="build badge"&gt;&lt;/a&gt; &lt;a href="https://www.trackawesomelist.com/rust-unofficial/awesome-rust/" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/a3a46cf6e9b86345756f800e47a3d24ba217ba4004dd2164a6d4c5168e0c00c9/68747470733a2f2f7777772e747261636b617765736f6d656c6973742e636f6d2f62616467652e737667" alt="Track Awesome List"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;A curated list of Rust code and resources.&lt;/p&gt;
&lt;p&gt;If you want to contribute, please read &lt;a href="https://github.com/rust-unofficial/awesome-rustCONTRIBUTING.md"&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
Table of contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-unofficial/awesome-rust#applications"&gt;Applications&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#audio-and-music"&gt;Audio and Music&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#cryptocurrencies"&gt;Cryptocurrencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#database"&gt;Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#emulators"&gt;Emulators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#games"&gt;Games&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#graphics"&gt;Graphics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#image-processing"&gt;Image processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#industrial-automation"&gt;Industrial automation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#observability"&gt;Observability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#operating-systems"&gt;Operating systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#payments"&gt;Payments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#productivity"&gt;Productivity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#routing-protocols"&gt;Routing protocols&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#security-tools"&gt;Security tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#simulation"&gt;Simulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#social-networks"&gt;Social networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#system-tools"&gt;System tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#task-scheduling"&gt;Task scheduling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#text-editors"&gt;Text editors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#text-processing"&gt;Text processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#utilities"&gt;Utilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#video"&gt;Video&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#virtualization"&gt;Virtualization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#web"&gt;Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#web-servers"&gt;Web Servers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-unofficial/awesome-rust#development-tools"&gt;Development tools&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#build-system"&gt;Build system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#debugging"&gt;Debugging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#deployment"&gt;Deployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#embedded"&gt;Embedded&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#ffi"&gt;FFI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#formatters"&gt;Formatters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#ides"&gt;IDEs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#profiling"&gt;Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#services"&gt;Services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#static-analysis"&gt;Static analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#testing"&gt;Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#transpiling"&gt;Transpiling&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-unofficial/awesome-rust#libraries"&gt;Libraries&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-unofficial/awesome-rust#artificial-intelligence"&gt;Artificial Intelligence&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#genetic-algorithms"&gt;Genetic algorithms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#machine-learning"&gt;Machine learning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#openai"&gt;OpenAI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#astronomy"&gt;Astronomy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#asynchronous"&gt;Asynchronous&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#audio-and-music-1"&gt;Audio and Music&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#authentication"&gt;Authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#automotive"&gt;Automotive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#bioinformatics"&gt;Bioinformatics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#caching"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#cloud"&gt;Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#command-line"&gt;Command-line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#compression"&gt;Compression&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#computation"&gt;Computation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#concurrency"&gt;Concurrency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#configuration"&gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#cryptography"&gt;Cryptography&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#data-processing"&gt;Data processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#data-streaming"&gt;Data streaming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#data-structures"&gt;Data structures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#data-visualization"&gt;Data visualization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#database-1"&gt;Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#date-and-time"&gt;Date and time&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#distributed-systems"&gt;Distributed systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#domain-driven-design"&gt;Domain driven design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#ebpf"&gt;eBPF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#email"&gt;Email&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#encoding"&gt;Encoding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#filesystem"&gt;Filesystem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#finance"&gt;Finance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#functional-programming"&gt;Functional Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#game-development"&gt;Game development&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#geospatial"&gt;Geospatial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#graph-algorithms"&gt;Graph algorithms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#graphics-1"&gt;Graphics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#gui"&gt;GUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#image-processing-1"&gt;Image processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#language-specification"&gt;Language specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#logging"&gt;Logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#macro"&gt;Macro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#markup-language"&gt;Markup language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#mobile"&gt;Mobile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#network-programming"&gt;Network programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#parsing"&gt;Parsing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#peripherals"&gt;Peripherals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#platform-specific"&gt;Platform specific&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#scripting"&gt;Scripting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#simulation-1"&gt;Simulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-unofficial/awesome-rust#system"&gt;System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rust-unofficial/awesome-rust"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;This is going to to our &lt;code&gt;cargo.toml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[package]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"nkv"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.2.0"&lt;/span&gt;
&lt;span class="py"&gt;edition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2021"&lt;/span&gt;

&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="nn"&gt;clap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"4.3.23"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["derive"]&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nn"&gt;sqlx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s"&gt;"runtime-tokio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"sqlite"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nn"&gt;serde&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nn"&gt;["derive"]&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;bunt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="py"&gt;inquire&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="nn"&gt;tokio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nn"&gt;["full"]&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;chrono&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="nn"&gt;clipboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.5.0"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;rand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="nn"&gt;dotenv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nn"&gt;tabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;human-panic&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We will be using quite a bit of dependencies to make a pretty CLI. The &lt;code&gt;clap&lt;/code&gt; dependency is a very simple to use CLI argument parser that uses a predefined struct to manage. &lt;code&gt;sqlx&lt;/code&gt; is a simple SQL binder, not ORM for rust that makes it very easy to execute SQL queries on our database.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;serde&lt;/code&gt; is a popular JSON library, we use &lt;code&gt;chrono&lt;/code&gt; for managing time related stuff. &lt;code&gt;clipboard&lt;/code&gt; is an intuitive Clipboard abstraction for rust. &lt;code&gt;rand&lt;/code&gt; is random generation, &lt;code&gt;dotenv&lt;/code&gt; for reading from the .env file, &lt;code&gt;tabled&lt;/code&gt; to style a struct into a table and &lt;code&gt;tokio&lt;/code&gt; to make our function asynchronous, so execution will be blocked till our database is queried.&lt;br&gt;
&lt;code&gt;bunt&lt;/code&gt; and &lt;code&gt;inquire&lt;/code&gt; are CLI formatting and prompting libraries that are similar to the &lt;code&gt;rich&lt;/code&gt; library in python&lt;br&gt;
Woah. So we are done with libraries. Be sure to also include the same features I did since we will be using all of them.&lt;/p&gt;
&lt;h2&gt;
  
  
  Let’s Start
&lt;/h2&gt;

&lt;p&gt;Now, we can finally start the actual coding. Open &lt;code&gt;[main.rs](http://main.rs)&lt;/code&gt; file and configure the &lt;code&gt;clap::Parser&lt;/code&gt; to a nice struct.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;clap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Parser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;human_panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;setup_panic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Parser,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="nd"&gt;#[command(name=&lt;/span&gt;&lt;span class="s"&gt;"NoobKey"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;author=&lt;/span&gt;&lt;span class="s"&gt;"Ishan Joshi"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;version,&lt;/span&gt; &lt;span class="nd"&gt;about=&lt;/span&gt;&lt;span class="s"&gt;"A Simple Key Value Store"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;long_about&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;None)]&lt;/span&gt;

&lt;span class="c1"&gt;//? The Args struct is used to parse the command line arguments&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Args&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[arg(required=&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="nd"&gt;#[arg(short,&lt;/span&gt; &lt;span class="nd"&gt;long)]&lt;/span&gt;
    &lt;span class="n"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="nd"&gt;#[arg(short,&lt;/span&gt; &lt;span class="nd"&gt;long)]&lt;/span&gt;
    &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;cmd&lt;/code&gt; is a Optional argument and we will prompt the user if it is not entered. We want this CLI for personal use, so no need to worry too much.&lt;br&gt;
We also add all the files to the main file as mods.&lt;br&gt;
Now, in the main function, all the predefined &lt;code&gt;dotenv().ok()&lt;/code&gt;; &lt;code&gt;setup_panic!()&lt;/code&gt;&lt;br&gt;
These will take care of the environment and errors in production. Now let’s parse the arguments and check if the user enter the command. If he has not, let’s ask him&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Args&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="py"&gt;.cmd&lt;/span&gt;&lt;span class="nf"&gt;.is_some&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="py"&gt;.cmd&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;inquire&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter Command: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_help_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter a valid command"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_autocomplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;suggester&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.prompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;utils::suggester&lt;/code&gt; is a simple filter and map function that inquire takes as input, this is the function. You can open up utils and paste this into it&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;suggester&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;suggestions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"set"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"delete"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"list"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"help"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"exit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;val_lower&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="nf"&gt;.to_lowercase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;suggestions&lt;/span&gt;
        &lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.to_lowercase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;val_lower&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We basically just add a simple rust filter map function.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Database
&lt;/h2&gt;

&lt;p&gt;Let’s configure the database connection now. First, open up &lt;a href="http://db.rs"&gt;db.rs&lt;/a&gt; and import the necessary modules and define a struct of how our Database query would look like.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(sqlx::FromRow,&lt;/span&gt; &lt;span class="nd"&gt;Serialize,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We use serde to Serialize and DeSerialize data, that is derived from sqlx.&lt;br&gt;
Our entry will have a simple id, key, value, hash and timestamp. Quite a simple and easy to work structure.&lt;br&gt;
Now, let’s get the Database connection using &lt;code&gt;sqlx&lt;/code&gt; and return a connection to the table I am calling &lt;code&gt;entries&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SqliteConnection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//used to connect to the DATABASE_URL&lt;/span&gt;
    &lt;span class="c1"&gt;// It can be any valid SQLite connection string&lt;/span&gt;
    &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;SqliteConnection&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sqlite:{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"KEY_STORE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SqliteConnection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//create table todo if not exists&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error connecting to db"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;r#"
        CREATE TABLE IF NOT EXISTS entries (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            key TEXT NOT NULL,
            value TEXT NOT NULL,
            hash TEXT NOT NULL,
            created_at TEXT NOT NULL
        )
        "#&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As you can see, in the connect function, we just use a SQL query. No ORM needed.&lt;/p&gt;

&lt;p&gt;Now, we can use the &lt;code&gt;connect()&lt;/code&gt; function to just return a connection from the db, without having the need to reconnect everytime.&lt;/p&gt;

&lt;p&gt;We now define an &lt;code&gt;add_to_db&lt;/code&gt; function, the create part of CRUD&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;r#"
        INSERT INTO entries (key, value, hash, created_at)
        VALUES (?, ?, ?, ?)
        "#&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;chrono&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Local&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_rfc3339&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error adding entry"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As you can see, we just used simple SQL. &lt;code&gt;sqlx&lt;/code&gt; allows us to bind the &lt;code&gt;?&lt;/code&gt; with a value, which is exactly what we did. We also used the &lt;code&gt;chrono::Local&lt;/code&gt; time in a the ISO format as the timestamp.&lt;/p&gt;

&lt;p&gt;We similarly write rest of the RUD:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;//get from db&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Entry&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM entries WHERE key = ?"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.fetch_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//delete from db&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DELETE FROM entries WHERE key = ?"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//list all entries&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Entry&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM entries"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.fetch_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//list all keys&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;list_keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT key FROM entries"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.fetch_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The Handler
&lt;/h2&gt;

&lt;p&gt;We now define a middleware like file to handle all the operations and display appropriately to the user. For example, we can ask the user to add like this&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nn"&gt;bunt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executing add command..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;inquire&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter Key: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_help_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter any identifier"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.prompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;inquire&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter Value: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_help_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter any value"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.prompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;random_hash&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;db&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;bunt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Added entry: {$green}{}{/$}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nn"&gt;bunt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value: {$yellow}{}{/$}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now that we have defined the &lt;code&gt;add&lt;/code&gt;, we can just use a match statement in the main file to call the handler&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"set"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"list"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"delete"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"get"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"search"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"exit"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;bunt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{$red}Exiting...{/$}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="s"&gt;"help"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;todo!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Help command not implemented"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;todo!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Command not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Like I defined the functions, similarly, you can define your own as well.&lt;/p&gt;

&lt;p&gt;Now, this is where I leave you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The whole point of this article was to help you take your first steps in writing your own CLI using rust and the whole point would be lost if I impose my own ideas on to you. You are now free to create your own CLI.&lt;br&gt;
Format it as you like. Maybe using a little bit of rust magic, you can make a very pretty CLI.&lt;br&gt;
You are free to use &lt;code&gt;NoobKey&lt;/code&gt; for reference, or even build on top of it. It is quite simple and easy to use codebase. This is it’s GitHub repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/newtoallofthis123"&gt;
        newtoallofthis123
      &lt;/a&gt; / &lt;a href="https://github.com/newtoallofthis123/noob_key"&gt;
        noob_key
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Simple and efficient Key Value Store
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
NoobKey&lt;/h1&gt;
&lt;p&gt;A Simple Key Value Store written in rust&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/newtoallofthis123/noob_key"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;With that being said, thank you for reading. You can check out this article on my site &lt;a href="https://noobscience.rocks/blog/tutorials/rust-cli"&gt;here&lt;/a&gt;. Thanks for reading, hope you have a great day.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>cli</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🦀 Writing a CMS in Rust</title>
      <dc:creator>Noob Science</dc:creator>
      <pubDate>Sat, 02 Sep 2023 16:58:54 +0000</pubDate>
      <link>https://dev.to/noobscience123/writing-a-cms-in-rust-30e4</link>
      <guid>https://dev.to/noobscience123/writing-a-cms-in-rust-30e4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;So, CMS is something that I always loved using. I just like the idea of having a service that controls your service.&lt;br&gt;
I mean, it's like a service-ception. But, I always hated the idea of having a bloated admin panel.&lt;br&gt;
I mean, why do you need a whole admin panel for a blog that you can manage with a CLI tool? &lt;br&gt;
You can if you want to, but then why not just integrate it with your blog?&lt;br&gt;
If you do that, you would need to do so many things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need to configure secure routes&lt;/li&gt;
&lt;li&gt;Add authentication&lt;/li&gt;
&lt;li&gt;Manage Access Control&lt;/li&gt;
&lt;li&gt;Basically a lot of things&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, I thought why not just write a CLI tool that handles all the stuff for you and since I had been learning Rust, I thought why not write it in Rust?&lt;br&gt;
Hence, welcome the Noob Handler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Write in Rust?
&lt;/h2&gt;

&lt;p&gt;I basically love CLI tools. They are a great and &lt;em&gt;easy&lt;/em&gt; way to get things done.&lt;br&gt;
They are also so easy to ship. No need to check some weird windows compatibility or anything.&lt;br&gt;
Just compile it and ship it. That's it. And, Rust is a great language for writing CLI tools.&lt;br&gt;
It's fast, it's easy to write, and it's easy to ship.&lt;br&gt;
You get an executable on the spot. Moreover, you get an executable that is fast and small in size.&lt;br&gt;
No weird dependencies folder that needs to be shipped or anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why not python?
&lt;/h3&gt;

&lt;p&gt;Python on the other hand, atleast in my opinion, has the worst executable experience.&lt;br&gt;
To compile a python file, you might end up using a library like &lt;code&gt;pyinstaller&lt;/code&gt; or something.&lt;br&gt;
And, even then, you would end up with a huge executable. I mean, I don't want to ship a 100MB executable for a CLI tool.&lt;br&gt;
That's just too much. Moreover, let's actually look at how pyinstaller works.&lt;/p&gt;

&lt;p&gt;So, you see, pyinstaller works primarily by creating a virtual environment and then installing all the dependencies in that virtual environment.&lt;br&gt;
Then, it creates all the necessary binding to &lt;em&gt;all&lt;/em&gt; the dependencies in cpython. And, then it creates an executable.&lt;br&gt;
This executable is just for name sake. It's just a wrapper around the virtual environment.&lt;br&gt;
So, when you run the executable, it just runs the virtual environment and then runs the python file.&lt;br&gt;
This slows down the execution time and also increases the size of the executable.&lt;br&gt;
That in the long run is not good for a CLI tool. That brings us to an important conclusion.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Python is not meant to be compiled, it is meant to be interpreted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't get me wrong, python has these cool libraries like &lt;code&gt;rich&lt;/code&gt; that make writing CLI tools in python a breeze.&lt;br&gt;
I have worked with &lt;code&gt;rich&lt;/code&gt; in the past and it is one of my favorite libraries. However, it is best when &lt;br&gt;
it is used as a script. I use rich to style my scripts and it works great. But, when it comes to writing a CLI tool,&lt;br&gt;
I would rather use a language that is meant to be compiled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rust is awesome
&lt;/h3&gt;

&lt;p&gt;So, welcome Rust.&lt;br&gt;
Rust has a bunch of libraries that make writing CLI tools a breeze.&lt;br&gt;
You have one for asking questions, one for styling, one for parsing arguments, and so on.&lt;br&gt;
It is python with the speed of C and the safety of Haskell. What more can you ask for?&lt;br&gt;
Actually scrap that. You can't really compare Rust with any other language.&lt;br&gt;
It is it's own thing and it is great at what it does.&lt;/p&gt;

&lt;p&gt;Here are some things that made me choose Rust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Great Type System&lt;/li&gt;
&lt;li&gt;Simple to use package manager&lt;/li&gt;
&lt;li&gt;Well documented libraries for CLI tools&lt;/li&gt;
&lt;li&gt;Single Binary executable&lt;/li&gt;
&lt;li&gt;Fast execution&lt;/li&gt;
&lt;li&gt;Good error handling&lt;/li&gt;
&lt;li&gt;Great community&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you feel that I just listed the most generic reasons to use Rust, you are right.&lt;br&gt;
I mean, there is a reason why so many CLI's are written in Rust.&lt;br&gt;
Infact, there is a whole community for rewriting &lt;code&gt;GNU/Linux&lt;/code&gt; tools in Rust.&lt;br&gt;
So, for example, you might have heard of &lt;code&gt;bat&lt;/code&gt; which is a replacement for &lt;code&gt;cat&lt;/code&gt;.&lt;br&gt;
It has some cool features like syntax highlighting and stuff like that, you have &lt;code&gt;exa&lt;/code&gt; which is a replacement for &lt;code&gt;ls&lt;/code&gt; with some cool features like icons.&lt;br&gt;
You basically have a sub community in rust that is interested in command line tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a CMS?
&lt;/h2&gt;

&lt;p&gt;Well, if you are unfamiliar with the term CMS, it stands for Content Management System.&lt;br&gt;
So, the idea behind it is that instead of your content being changed at deployment time, it is changed at runtime.&lt;br&gt;
Let me explain. So, let's say you use Astro to build your website. You have a bunch of markdown files that you use to generate your website.&lt;br&gt;
Now, let's say you want to add a new blog post. You would have to add a new markdown file and then deploy your website.&lt;br&gt;
This is the traditional way of doing things. However, with a CMS, you can just add a new blog post from the admin panel and it would be added to your website.&lt;br&gt;
This is because your website will be reading off a remote database and not a local markdown file.&lt;/p&gt;

&lt;p&gt;Now, my current blog is written using markdown files. I have a bunch of markdown files that are run through some remark plugins and then converted to HTML by Astro.&lt;br&gt;
Nothing fancy. This is because my blog posts usually take a lot of time to write and I don't really write them that often.&lt;br&gt;
Hence, when I do write them, I just add a markdown file and then deploy my website. It's not that big of a deal.&lt;/p&gt;

&lt;p&gt;However, I have a page called &lt;code&gt;quips&lt;/code&gt; where I write little updates about my life. I write them pretty often and I don't really want to deploy my website every time I write a new quip.&lt;br&gt;
Hence, I use a MongoDB database to store my quips. I have a simple API that I use to add new quips and then I have a page that fetches all the quips from the database and displays them.&lt;br&gt;
This is a CMS. I am managing my content from a remote database.&lt;/p&gt;

&lt;p&gt;Along with quips, I have two other pages that use a database.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/code"&gt;NoobPaste Mini&lt;/a&gt;: A simple and minimal pastebin that I use to share code snippets.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/go"&gt;NoobShort&lt;/a&gt;: A simple URL shortener that I use to shorten URLs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both of these use a database to store their data. I have a simple API that I use to add new pastes and new URLs.&lt;br&gt;
I actually have a NoobShort CLI that you can check out at &lt;a href="https://github.com/newtoallofthis123/short_cli" rel="noopener noreferrer"&gt;newtoallofthis123/short_cli&lt;/a&gt;.&lt;br&gt;
It is quite easy to use and it is one of the first CLI's that I wrote in Rust.&lt;br&gt;
You can just install it using &lt;code&gt;cargo install nshrt&lt;/code&gt; and then you can use it to shorten URLs.&lt;/p&gt;

&lt;p&gt;Anyways, getting back to the topic at hand, I have a bunch of pages that use a database to store their data.&lt;br&gt;
All this is stored using a MongoDB database. I use MongoDB because it is easy to use and it is easy to setup.&lt;br&gt;
So, MongoDB has a very easy to use rust driver called &lt;code&gt;mongodb&lt;/code&gt;. It is well documented and it is easy to use.&lt;br&gt;
I have used it in the past and I have had no issues with it. So, I decided to use it for my CMS.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plan
&lt;/h2&gt;

&lt;p&gt;The plan is simple. I want to write a CLI tool that can be used to manage my content.&lt;br&gt;
I had to manage three types of content with the following B-JSON schemas:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Quips&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ObjectId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Code&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ObjectId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lang"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ObjectId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, the idea was that each of these had the following operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show&lt;/li&gt;
&lt;li&gt;Add&lt;/li&gt;
&lt;li&gt;Edit&lt;/li&gt;
&lt;li&gt;Delete
The &lt;strong&gt;CRUD&lt;/strong&gt; operations if you may. The CLI would have the following commands:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

handler __doc__ __hash__

handler new __doc__

handler list __doc__


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;doc&lt;/strong&gt; can be either &lt;code&gt;quips&lt;/code&gt;, &lt;code&gt;code&lt;/code&gt;, or &lt;code&gt;go&lt;/code&gt;. The &lt;code&gt;__hash__&lt;/code&gt; is the hash of the document that you want to edit or delete.&lt;/p&gt;

&lt;p&gt;The list was basically show and search combined. It would show all the documents and then you could search for a specific document.&lt;br&gt;
This could be done natively using the &lt;code&gt;inquire&lt;/code&gt; crate, but more on that later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary of the Plan
&lt;/h3&gt;

&lt;p&gt;So, let's summarize the plan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect to MongoDB&lt;/li&gt;
&lt;li&gt;Enable CRUD operations on the database&lt;/li&gt;
&lt;li&gt;Add a CLI interface to the CRUD operations&lt;/li&gt;
&lt;li&gt;Add New, Edit, and Delete operations&lt;/li&gt;
&lt;li&gt;Add a list operation&lt;/li&gt;
&lt;li&gt;Make everything as native and as fast as possible&lt;/li&gt;
&lt;li&gt;Make it look pretty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take all these head on and see how we can implement them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving the Problems
&lt;/h2&gt;

&lt;p&gt;First up was actually setting up the database. I already had a database with the given collections.&lt;br&gt;
I just used the URI of it and connected to it using the &lt;code&gt;mongodb&lt;/code&gt; crate. It was pretty easy to do.&lt;br&gt;
It looks something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_connection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;mongodb&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_uri_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get_mongo_url&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;get_mongo_url&lt;/code&gt; function just returns the URI of the database. I have it stored in an environment variable so that &lt;br&gt;
I don't have to hardcode it in the code. I just use the &lt;code&gt;dotenv&lt;/code&gt; crate to load the environment variables.&lt;/p&gt;

&lt;p&gt;Next up was actually enabling CRUD operations on the database. This was pretty easy to do as well.&lt;br&gt;
So, the &lt;code&gt;mongodb&lt;/code&gt; crate has a &lt;code&gt;Collection&lt;/code&gt; struct that you can use to interact with the database.&lt;br&gt;
I predefine the collections and then I just use the &lt;code&gt;Collection&lt;/code&gt; struct to interact with the database.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The collections use &lt;code&gt;serde&lt;/code&gt; to automatically serialize and deserialize the data.&lt;br&gt;
Next, I can use the inbuilt functions of the collections struct like &lt;code&gt;insert_one&lt;/code&gt;, &lt;code&gt;find_one&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;delete_one&lt;/code&gt;, and &lt;code&gt;update_one&lt;/code&gt; to interact with the database.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_page_conn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="nf"&gt;.find_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;doc!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Page Not Found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, that is one of the functions that I use to get a page from the database. I just use the &lt;code&gt;find_one&lt;/code&gt; function to find a page with the given hash.&lt;br&gt;
The &lt;code&gt;doc!&lt;/code&gt; macro is very handy and is used to create a BSON document. It is basically a JSON object that is used to query the database.&lt;br&gt;
If you are starting to see a pattern here, you are right. The mongodb driver for rust is basically an ORM for MongoDB.&lt;br&gt;
One thing that I forgot to mention, all this set up with tokio and futures so that the whole execution is blocked till the database operation is complete.&lt;br&gt;
This makes it easier to avoid type errors and stuff like that.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI and Inquire
&lt;/h3&gt;

&lt;p&gt;Next up was actually adding a CLI interface to the CRUD operations. This was pretty easy to do as well.&lt;br&gt;
I use the &lt;code&gt;clap&lt;/code&gt; crate to parse the arguments and then I use the &lt;code&gt;inquire&lt;/code&gt; crate to ask questions.&lt;br&gt;
The clap crate is pretty easy to use. You just define the arguments in a struct and then you use the clap macros to parse the arguments.&lt;br&gt;
It looks something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="nd"&gt;#[derive(Parser,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="nd"&gt;#[command(name=&lt;/span&gt;&lt;span class="s"&gt;"Handler"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;author=&lt;/span&gt;&lt;span class="s"&gt;"Ishan Joshi"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;version,&lt;/span&gt; &lt;span class="nd"&gt;about=&lt;/span&gt;&lt;span class="s"&gt;"A Simple CLI to handle my site"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;long_about&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;None)]&lt;/span&gt;

&lt;span class="c1"&gt;// The Args struct is used to parse the command line arguments&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Args&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[arg(required=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="nd"&gt;#[arg(required=&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That's it! It is that simple. This comes with everything, the help command, the version command, and so on.&lt;br&gt;
You can also add your own commands and subcommands. I just use the arg macro to define the arguments.&lt;br&gt;
We get the arguments by calling the &lt;code&gt;Args::parse()&lt;/code&gt; function. This returns a struct with the parsed arguments.&lt;/p&gt;

&lt;p&gt;Although, I don't like to impose arguments on the user. I like to ask questions. So, I use the &lt;code&gt;inquire&lt;/code&gt; crate to ask questions.&lt;br&gt;
Inquire is a very useful crate that beautifully implements most of standard input and output operations.&lt;br&gt;
So, you can ask for confirmation, ask for a password, ask for a list of options, and so on.&lt;br&gt;
You can even have it open up a text editor for you to write your answer. It is a very useful crate.&lt;br&gt;
So, I used it to write a custom function that takes in a instance of a struct and then asks questions based on the struct.&lt;br&gt;
The quips struct looks something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;ask_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Editing {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;inquire&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.prompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;inquire&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Editor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_file_extension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".md"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_editor_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ffi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;OsStr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"vim"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.with_predefined_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="py"&gt;.content&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.prompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;inquire&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Author"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="py"&gt;.author&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.prompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;inquire&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Date"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="py"&gt;.date&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.prompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="py"&gt;._id&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="py"&gt;.hash&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This would give an output like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw09gs012n7vk7ec7atnf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw09gs012n7vk7ec7atnf.png" alt="Rust CMS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which is pretty cool. I mean, it is a CLI tool, but it looks like a GUI. I love it.&lt;/p&gt;

&lt;p&gt;I also had to implement a search function. I used the &lt;code&gt;inquire&lt;/code&gt; crate for that as well.&lt;br&gt;
I just used the &lt;code&gt;Select&lt;/code&gt; struct to ask for a list of options and passed in the list of pages.&lt;br&gt;
The inquire's &lt;code&gt;Select&lt;/code&gt; struct is very powerful. It automatically asks the user to start typing and then it filters the list based on the input.&lt;br&gt;
So, I just passed in the list of pages and then I got a list of pages that I could select from.&lt;br&gt;
Searching was solved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compiling
&lt;/h3&gt;

&lt;p&gt;Next, all I had to do was integrate the whole thing together. I just had to call the functions in the right order.&lt;br&gt;
It was quite easy and after a lot of debugging, I finally got it to work. Then, for the moment of truth, I ran &lt;code&gt;cargo build --release&lt;/code&gt; and I got a single binary executable.&lt;br&gt;
It was just 914kb in size! I now have a fully functional CMS that is just 914kb in size.&lt;/p&gt;

&lt;p&gt;The best part? I don't need to carry or clone anything if I want to use it on another machine.&lt;br&gt;
I only need to download the executable, which I will be hosting on my website, and then I can use it to manage my content.&lt;/p&gt;

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

&lt;p&gt;So, what can you take away from this? Well, you can take away the fact that you can write a CMS in Rust.&lt;br&gt;
Rust is an awesome tool for writing CLI tools. It is fast, it is easy to use, and it is easy to ship.&lt;br&gt;
After the whole thing, I only ended up writing about 600 lines of code. That is just amazing.&lt;/p&gt;

&lt;p&gt;This was also a good learning experience for me. I learnt a lot about Rust, tokio and futures.&lt;br&gt;
Overall, it was quite cool. So, for conclusion, should you write a CMS in Rust? Well, if you want to, go ahead.&lt;br&gt;
However, sometimes, just sticking with a good web framework is the best option. I mean, you don't need to write a CMS for everything.&lt;br&gt;
In my case, I had a very small use case and I wanted to write a CLI tool. Hence, I wrote a CMS in Rust.&lt;br&gt;
However, I probably do recommend you writing a CLI CMS, since that teaches you a lot about the language and it's libraries, plus it is fun.&lt;/p&gt;

&lt;p&gt;Anyways, I hope you enjoyed this post. I know this was a bit more technical than my other posts, but I hope you enjoyed it.&lt;br&gt;
If you want to check out the code, you can check it out at &lt;a href="https://github.com/newtoallofthis123/noob_handler" rel="noopener noreferrer"&gt;newtoallofthis123/noob_handler&lt;/a&gt;.&lt;br&gt;
You can even clone it, but you can't really use it since it is configured to work with my database.&lt;br&gt;
Thanks for reading and I will see you in the next one. Bye!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>cli</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
