Go To Do Rust

In this post, I want to go from step by step what it would look like building a taskr binary in both Go and Rust side by side so you can see conversion conventions and why Rust wins in the battle between the gopher and the crab.

Starting Point

package main

import "fmt"

func main() {
   fmt.Println("Hello World")
}
fn main() {
   println!("Hello World")
}

From both of these applications, you should be working in a directory structure that looks like:

~/work/personal/learning-go/taskr/main.go
~/work/personal/learning-rust/taskr/main.rs

To get the ~/work/personal/learning-go directory, create it and then create a new Go file using:

mkdir -p ~/work/personal/learning-go/taskr
cd ~/work/personal/learning-go/taskr
go mod init taskr

To get the ~/work/personal/learning-rust/taskr directory, run:

mkdir -p ~/work/personal/learning-rust
cargo new taskr

From that command you’ll get a Cargo.toml file which will be versioned to 0.1.0.

The program’s data structure

We’re building out a task, so lets define what that looks like in Go and in Rust.

type Status string

const (
    StatusTodo Status = "Todo"
    StatusDone Status = "Done"
)

type Task struct {
    ID     uint32 `json:"id"`
    Title  string `json:"title"`
    Status Status `json:"status"`
}
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
enum Status {
    Todo,
    Done,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
struct Task {
    id: u32,
    title: String,
    status: Status,
}
Decorator Usage
Debug lets me print the value using {:?} format
Serialize generate JSON code at compile time
Deserialize read JSON code at compile time
Clone allows you to duplicate a value
PartialEq allows equality comparisons between Status values

These decorators will be used throughout the program later. Specifically, the Debug will be used in println!() statements. serde import provides Serialize and Deserialize in order to engage with JSON files at compile time. Without PartialEq, the status would not be comparable. It’s required.

Let’s define what the print_usage() function is going to look like in Go and in Rust.

func printUsage() {
    fmt.Println("taskr - A simple task manager")
    fmt.Println()
    fmt.Println("Usage:")
    fmt.Println("  taskr add     Add a new task"</span><span class="p">)</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"  taskr list           List all tasks"</span><span class="p">)</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"  taskr done <id>      Mark a task as done"</span><span class="p">)</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"  taskr delete <id>    Delete a task"</span><span class="p">)</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"  taskr search <query> Search for a task"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">print_usage</span><span class="p">()</span> <span class="p">{</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"taskr - A simple task manager"</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">();</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Usage:"</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"  taskr add <title>    Add a new task"</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"  taskr list           List all tasks"</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"  taskr done <id>      Mark a task as done"</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"  taskr delete <id>    Delete a task"</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"  taskr search <query> Search for a task"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
</div>
<p>This should go above the <code>main()</code> func in both <code>main.go</code> and <code>main.rs</code> respectively.</p>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Command</th>
<th>About</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>taskr add <title></code></td>
<td>Add a new task</td>
</tr>
<tr>
<td><code>taskr list</code></td>
<td>List all tasks</td>
</tr>
<tr>
<td><code>taskr done <id></code></td>
<td>Mark a task as done</td>
</tr>
<tr>
<td><code>taskr delete <id></code></td>
<td>Delete a task</td>
</tr>
<tr>
<td><code>taskr search <id></code></td>
<td>Search for a task</td>
</tr>
</tbody>
</table>
</div>
<p>Implementing the <code>print_usage()</code> func in both Go and Rust is very simple and is done in the <code>main()</code> func respectively:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Args</span><span class="p">)</span> <span class="o"><</span> <span class="m">2</span> <span class="p">{</span>
        <span class="n">printUsage</span><span class="p">()</span>
        <span class="k">return</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>

    <span class="c1">// .collect() returns the .args() into a Vec<String> format</span>
    <span class="k">let</span> <span class="n">args</span><span class="p">:</span> <span class="nb">Vec</span><span class="o"><</span><span class="nb">String</span><span class="o">></span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">env</span><span class="p">::</span><span class="nf">args</span><span class="p">()</span><span class="nf">.collect</span><span class="p">();</span>

    <span class="c1">// ensure that there are enough arguments to run the program</span>
    <span class="k">if</span> <span class="n">args</span><span class="nf">.len</span><span class="p">()</span> <span class="o"><</span> <span class="mi">2</span> <span class="p">{</span>
        <span class="nf">print_usage</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The big difference here is the <strong>Go</strong> <code>os.Args</code> and the <strong>Rust</strong> <code>std::env::args().collect()</code>. Clearly, Rust is more verbose, and without <code>.collect()</code> the value of the <code>.args()</code> could be a tuple of <code><String, Err></code>, but <code>.collect()</code> returns a <code>Vec<String></code> if there are no <code>Err</code> thrown.</p>
<p>With this basic program functionality, we can implement in the <code>main()</code> func in both languages what that <em>switching</em> is going to look like parsing the 2nd and 3rd arguments respectively.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="n">main</span><span class="p">(){</span> 
    <span class="c">// ... existing</span>

    <span class="k">switch</span> <span class="n">args</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="p">{</span>
        <span class="c">// 1. taskr search <query></span>
        <span class="k">case</span> <span class="s">"search"</span><span class="o">:</span>

        <span class="c">// 2. taskr add <title></span>
        <span class="k">case</span> <span class="s">"add"</span><span class="o">:</span>

        <span class="c">// 3. taskr list</span>
        <span class="k">case</span> <span class="s">"list"</span><span class="o">:</span>

        <span class="c">// 4. taskr done <id></span>
        <span class="k">case</span> <span class="s">"done"</span><span class="o">:</span>

        <span class="c">// 5. taskr delete <id></span>
        <span class="k">case</span> <span class="s">"delete"</span><span class="o">:</span>

        <span class="c">// 6. taskr <else> catch-all</span>
        <span class="k">default</span><span class="o">:</span>

    <span class="p">}</span>

    <span class="c">//- end of main</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// ... existing</span>

    <span class="k">match</span> <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="nf">.as_str</span><span class="p">()</span> <span class="p">{</span>

        <span class="c1">// 1. taskr search <query></span>
        <span class="s">"search"</span> <span class="k">=></span> <span class="p">{}</span>

        <span class="c1">// 2. taskr add <title></span>
        <span class="s">"add"</span> <span class="k">=></span> <span class="p">{}</span>

        <span class="c1">// 3. taskr list</span>
        <span class="s">"list"</span> <span class="k">=></span> <span class="p">{}</span>

        <span class="c1">// 4. taskr done <id></span>
        <span class="s">"done"</span> <span class="k">=></span> <span class="p">{}</span>

        <span class="c1">// 5. taskr delete <id></span>
        <span class="s">"delete"</span> <span class="k">=></span> <span class="p">{}</span>

        <span class="c1">// 6. taskr <else> catch-all</span>
        <span class="n">_</span> <span class="k">=></span> <span class="p">{</span>
           <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Invalid command"</span><span class="p">);</span>
            <span class="nf">print_usage</span><span class="p">();</span>
            <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// SIGTERM 1</span>
        <span class="p">}</span>

    <span class="p">}</span> <span class="c1">//- match arg[1]</span>

    <span class="c1">//- end of main</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The <code>match</code> (rust) and <code>switch</code> (go) statements are both reading from <code>args[1]</code>. The <code>0</code> in <code>args[0]</code> would be the filename of the binary running. In the example of <strong>taskr list</strong>, the <code>args[0]</code> is <code>taskr</code> and <code>args[1]</code> is <code>list</code>. In <strong>rust</strong>, the <code>.as_str()</code> is used to ensure that the underlying type is a string, since the <code>statement</code> is a <code>String</code> in <code>"statement" => { }</code> (rust) and <code>case "statement":</code> (go). </p>
<p>Next, we are going to be implementing the <code>TaskStore</code>, but before we do that, we need to ensure that our programs respectively have the correct imports.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">import</span> <span class="p">(</span>
    <span class="s">"encoding/json"</span>
    <span class="s">"errors"</span>
    <span class="s">"fmt"</span>
    <span class="s">"os"</span>
    <span class="s">"strconv"</span>
    <span class="s">"strings"</span>
<span class="p">)</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="c1">// serde is used for JSON structure support at compile time</span>
<span class="k">use</span> <span class="nn">serde</span><span class="p">::{</span><span class="n">Deserialize</span><span class="p">,</span> <span class="n">Serialize</span><span class="p">};</span>

<span class="c1">// read and write on file functions</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">fs</span><span class="p">;</span>

<span class="c1">// access the io::Result type for propagating I/O errors</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">io</span><span class="p">;</span>

<span class="c1">// owned mutable file path</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">path</span><span class="p">::</span><span class="n">PathBuf</span><span class="p">;</span>
</code></pre>
</div>
<p>These imports allow each of the programs to respectively handle the functionality needed. Within <strong>Go</strong>, you’ll interact with the <code>os</code> package for I/O related work and in <strong>Rust</strong>, you interact with <code>std::io</code> instead. Files are handled in <strong>Go</strong> using the <code>os</code> package, as well as the <code>fs</code> and <code>ioutil</code> packages. <strong>Rust</strong> consolidates it into a two packages called <code>std::io</code> and <code>std::fs</code>. Both languages are designed to be cross platform natively. One last thing to point out about this is the <code>std::path::PathBuf</code> and how its very similar to Go’s <code>filepath</code> package offering. In Rust, the <code>PathBuf</code> type is specifically for filesystem paths. On Windows, you split your directory tree using <code></code> and on Linux, you split your directory tree using <code>/</code>. Those differences are handled under the hood by the <code>filepath</code> (Go) and <code>std::path::PathBuf</code> (Rust) automatically. </p>
<h2 id="the-task-store">
<p>  The Task Store<br />
</h2>
<p>The bulk of the logic of the application is going to expose <code>TaskStore</code> in both <strong>Go</strong> and <strong>Rust</strong>. How these are implemented matter and you’ll see why that is.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">type</span> <span class="n">TaskStore</span> <span class="k">struct</span> <span class="p">{</span>
    <span class="n">tasks</span>    <span class="p">[]</span><span class="n">Task</span>
    <span class="n">filePath</span> <span class="kt">string</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">struct</span> <span class="n">TaskStore</span><span class="p">{</span>
    <span class="n">tasks</span><span class="p">:</span> <span class="nb">Vec</span><span class="o"><</span><span class="n">Task</span><span class="o">></span><span class="p">,</span>
    <span class="n">file_path</span><span class="p">:</span> <span class="n">PathBuf</span><span class="p">,</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Both of these snippets show you how similar <strong>Go</strong> and <strong>Rust</strong> can appear. The <code>[]Task</code> in <strong>Go</strong> becomes a <code>Vec<Task></code> in <strong>Rust</strong> and the <code>filePath</code> uses <strong>Rust</strong>‘s <code>PathBuf</code>. In <strong>Go</strong>, the <code>struct</code> can use and store the <code>filePath</code> as a <code>string</code> since <code>filepath</code> package returns only <code>String</code> types back – <strong>Rust</strong> gives you an entirely new type called <code>PathBuf</code> whereas <strong>Go</strong> gives you a wrapper for it.</p>
<p>When implementing the methods on the <code>TaskStore</code>, this is where <strong>Go</strong> and <strong>Rust</strong> diverge quite radically.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="n">NewTaskStore</span><span class="p">(</span><span class="n">filePath</span> <span class="kt">string</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="n">TaskStore</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Save</span><span class="p">()</span> <span class="kt">error</span> <span class="p">{}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Add</span><span class="p">(</span><span class="n">title</span> <span class="kt">string</span><span class="p">)</span> <span class="p">{}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Complete</span><span class="p">(</span><span class="n">id</span> <span class="kt">uint32</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Delete</span><span class="p">(</span><span class="n">id</span> <span class="kt">uint32</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">List</span><span class="p">()</span> <span class="p">{}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Search</span><span class="p">(</span><span class="n">query</span> <span class="kt">string</span><span class="p">)</span> <span class="p">[]</span><span class="o">*</span><span class="n">Task</span> <span class="p">{}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">impl</span> <span class="n">TaskStore</span> <span class="p">{</span>

    <span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">file_path</span><span class="p">:</span> <span class="n">PathBuf</span><span class="p">)</span> <span class="k">-></span> <span class="nn">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="k">Self</span><span class="o">></span> <span class="p">{}</span>

    <span class="k">fn</span> <span class="nf">save</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">)</span> <span class="k">-></span> <span class="nn">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="p">()</span><span class="o">></span> <span class="p">{}</span>

    <span class="k">fn</span> <span class="nf">add</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="nb">String</span><span class="p">)</span> <span class="p">{}</span>

    <span class="k">fn</span> <span class="nf">complete</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">id</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-></span> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span> <span class="nb">String</span><span class="o">></span> <span class="p">{}</span>

    <span class="k">fn</span> <span class="nf">delete</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">id</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-></span> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span> <span class="nb">String</span><span class="o">></span> <span class="p">{}</span>

    <span class="k">fn</span> <span class="nf">list</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">)</span> <span class="p">{}</span>

    <span class="k">fn</span> <span class="nf">search</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="o">&</span><span class="nb">str</span><span class="p">)</span> <span class="k">-></span> <span class="nb">Vec</span><span class="o"><&</span><span class="n">Task</span><span class="o">></span> <span class="p">{}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>There is a pretty clean <code>1:1</code> relationship between the implemented methods of the <code>TaskStore</code> between <strong>Go</strong> and <strong>Rust</strong> and specifically what I want to note here for you is how in <strong>Rust</strong> everything is wrapped inside of the <code>impl TaskStore {}</code> block itself, whereas in Go, this can be literally anywhere at the root level of the file inside the <code>package main</code> project. The order of the routes does not matter in either language.</p>
<p><strong>Rust</strong> has a convention called <code>io::Result<Self></code> which in <strong>Go</strong> simply looks like <code>(<Type>, error)</code>. The <code>NewTaskStore</code> method in <strong>Go</strong> is unattached per-se to the <code>TaskStore</code> <code>struct</code> itself, but it does return the <strong>Go</strong> equivalent of <code>(*TaskStore, error)</code> as <code>io::Result<Self></code>. When <code>io::Result<Self></code> is used, the method must also include <code>Ok(())</code> in order to satisfy the contract.</p>
<p>At this point, let’s ensure that our <strong>Go</strong> program has two little helper functions in it in order to improve runtime readability – this is common in Go.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="n">parseID</span><span class="p">(</span><span class="n">arg</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">uint32</span> <span class="p">{</span>
    <span class="n">id</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">strconv</span><span class="o">.</span><span class="n">ParseUint</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="m">10</span><span class="p">,</span> <span class="m">32</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintf</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="s">"Invalid task ID: %s</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
        <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="kt">uint32</span><span class="p">(</span><span class="n">id</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">func</span> <span class="n">mustSave</span><span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">s</span><span class="o">.</span><span class="n">Save</span><span class="p">();</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintf</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="s">"Error saving tasks: %v</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
        <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>This application does not need or use helper functions in the <strong>Rust</strong> implementation. In <strong>Rust</strong> we’re using <code>u32</code> for the <code>id</code> and in <strong>Go</strong> that is a <code>uint32</code> which imports the <code>strconv</code> package. <strong>Rust</strong> does not need to import any packages. </p>
<p>Before implementing the specifics in the <code>TaskStore</code>, lets consume it in the <code>main()</code> func.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>

    <span class="c">// ... after checking the length of args</span>

    <span class="n">store</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">NewTaskStore</span><span class="p">(</span><span class="s">"tasks.json"</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintf</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="s">"Error loading tasks: %v</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
        <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="c">// ... before switching args[1]</span>

<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="k">-></span> <span class="nn">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="p">()</span><span class="o">></span> <span class="p">{</span>

    <span class="c1">// ... after checking the length of args</span>

    <span class="k">let</span> <span class="n">database</span> <span class="o">=</span> <span class="nn">PathBuf</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"tasks.json"</span><span class="p">);</span>

    <span class="k">let</span> <span class="k">mut</span> <span class="n">store</span> <span class="o">=</span> <span class="k">match</span> <span class="nn">TaskStore</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">database</span><span class="p">){</span>
        <span class="nf">Ok</span><span class="p">(</span><span class="n">store</span><span class="p">)</span> <span class="k">=></span> <span class="n">store</span><span class="p">,</span>
        <span class="nf">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="k">=></span> <span class="p">{</span>
            <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Error loading tasks: {}"</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span>
            <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// SIGTERM 1</span>
        <span class="p">}</span>
    <span class="p">};</span>

    <span class="c1">// ... before matching args[1]</span>

<span class="p">}</span>
</code></pre>
</div>
<p>Both of these implementations will leverage the <strong>current working directory</strong> and consume the resource <code>tasks.json</code> if it exists. If it does not exist, the program will create it, if it exists, the program will overwrite it. </p>
<p>In <strong>Rust</strong>, the <code>TaskStore</code> is consumed slightly differently than in <strong>Go</strong> because of the <code>impl TaskStore {}</code> differences. In <strong>Rust</strong> the <code>TaskStore</code> must have <code>mut</code> after <code>let</code> and before the name of the variable in order to indicate to the compiler that the value of <code>store</code> is eligible for changing in the future. Since the <code>TaskStore::new(database)</code> returns with an <code>io::Result<Self></code>, we can <code>match</code> against it when assigning it to the <code>store</code> variable. </p>
<p>The <strong>Go</strong> tuple that <code>io::Result<Self></code> is satisfying is <code>(*TaskStore, error)</code> and in <strong>Rust</strong>, the first component <code>*TaskStore</code> is represented in by the <code>Ok()</code> invocation. At the end of the various <code>impl TaskStore {}</code> methods, you’ll see an <code>Ok(())</code> at the end of each method ; this invokes the contract and exits the method since we’re good. Otherwise, your program will not compile. When assigning a value to <code>store</code> and executing <code>TaskStore::new(database)</code>, each component of the output gets matched to the <code>Ok(store) =></code> or <code>Err(e) => {}</code> blocks respectively. When we receive an <code>Ok(())</code> then that returned <code>store</code> from <code>Ok()</code> is then assigned to the <code>let mut store</code> variable. </p>
<p>Otherwise, if <code>Err(e)</code> satisfies, it means that <em>something went wrong</em> and we’ll print the error and exit with status code 1. In <strong>Go</strong>, we use <code>os.Exit(1)</code> and in <strong>Rust</strong> we use <code>std::process::exit(1);</code>. In <strong>Go</strong>, we can use the <code>fmt</code> or <code>slog</code> or <a href="https://github.com/andreimerlescu/verbose" rel="noopener noreferrer">verbose</a> packages to write to STDOUT and STDERR, and in <strong>Rust</strong> we use <code>eprintln!()</code> for STDERR and <code>println!()</code> for STDOUT respectively.</p>
<h2 id="implementing-new-taskstore">
<p>  Implementing <strong>new</strong> <code>TaskStore</code><br />
</h2>
<p>We have stubbed out each of our methods, and at this point we need to implement the body of these methods in two locations. We’re going to implement the <code>TaskStore</code> now, and that means populating each of the methods in TWO locations. First in the <code>impl TaskStore {}</code> block for <strong>Rust</strong> and inside of the <code>func (s *TaskStore) ...</code> methods for <strong>Go</strong>. </p>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Method</th>
<th>Go Signature</th>
<th>Rust Signature</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>new</code></td>
<td><code>func NewTaskStore(filePath string) (*TaskStore, error)</code></td>
<td><code>fn new(file_path: PathBuf) -> io::Result<Self></code></td>
</tr>
<tr>
<td><code>save</code></td>
<td><code>func (s *TaskStore) Save() error</code></td>
<td><code>fn save(&self) -> io::Result<()></code></td>
</tr>
<tr>
<td><code>list</code></td>
<td><code>func (s *TaskStore) List()</code></td>
<td><code>fn list(&self)</code></td>
</tr>
<tr>
<td><code>complete</code></td>
<td><code>func (s *TaskStore) Complete(id uint32) error</code></td>
<td><code>fn complete(&mut self, id: u32) -> Result<(), String></code></td>
</tr>
<tr>
<td><code>delete</code></td>
<td><code>func (s *TaskStore) Delete(id uint32) error</code></td>
<td><code>fn delete(&mut self, id: u32) -> Result<(), String></code></td>
</tr>
<tr>
<td><code>add</code></td>
<td><code>func (s *TaskStore) Add(title string)</code></td>
<td><code>fn add(&mut self, title: String)</code></td>
</tr>
<tr>
<td><code>search</code></td>
<td><code>func (s *TaskStore) Search(query string) []*Task</code></td>
<td><code>fn search(&self, query: &str) -> Vec<&Task></code></td>
</tr>
</tbody>
</table>
</div>
<h3 id="taskstores-new-implemented">
<p>  TaskStore’s <code>new</code> Implemented<br />
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="n">NewTaskStore</span><span class="p">(</span><span class="n">filePath</span> <span class="kt">string</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="n">TaskStore</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">tasks</span> <span class="o">:=</span> <span class="p">[]</span><span class="n">Task</span><span class="p">{}</span>

    <span class="n">data</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">os</span><span class="o">.</span><span class="n">ReadFile</span><span class="p">(</span><span class="n">filePath</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">err</span> <span class="o">==</span> <span class="no">nil</span> <span class="p">{</span>
        <span class="k">if</span> <span class="n">jsonErr</span> <span class="o">:=</span> <span class="n">json</span><span class="o">.</span><span class="n">Unmarshal</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="o">&</span><span class="n">tasks</span><span class="p">);</span> <span class="n">jsonErr</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
            <span class="n">tasks</span> <span class="o">=</span> <span class="p">[]</span><span class="n">Task</span><span class="p">{}</span>
        <span class="p">}</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">!</span><span class="n">errors</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">err</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">ErrNotExist</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="no">nil</span><span class="p">,</span> <span class="n">err</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="o">&</span><span class="n">TaskStore</span><span class="p">{</span><span class="n">tasks</span><span class="o">:</span> <span class="n">tasks</span><span class="p">,</span> <span class="n">filePath</span><span class="o">:</span> <span class="n">filePath</span><span class="p">},</span> <span class="no">nil</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">file_path</span><span class="p">:</span> <span class="n">PathBuf</span><span class="p">)</span> <span class="k">-></span> <span class="nn">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="k">Self</span><span class="o">></span> <span class="p">{</span>

    <span class="k">let</span> <span class="n">tasks</span> <span class="o">=</span> <span class="k">if</span> <span class="n">file_path</span><span class="nf">.exists</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">data</span> <span class="o">=</span> <span class="nn">fs</span><span class="p">::</span><span class="nf">read_to_string</span><span class="p">(</span><span class="o">&</span><span class="n">file_path</span><span class="p">)</span><span class="o">?</span><span class="p">;</span>
        <span class="nn">serde_json</span><span class="p">::</span><span class="nf">from_str</span><span class="p">(</span><span class="o">&</span><span class="n">data</span><span class="p">)</span><span class="nf">.unwrap_or_else</span><span class="p">(|</span><span class="n">_</span><span class="p">|</span> <span class="nn">Vec</span><span class="p">::</span><span class="nf">new</span><span class="p">()</span> <span class="p">)</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> 
        <span class="nn">Vec</span><span class="p">::</span><span class="nf">new</span><span class="p">()</span>
    <span class="p">};</span>

    <span class="nf">Ok</span><span class="p">(</span><span class="k">Self</span> <span class="p">{</span> <span class="n">tasks</span><span class="p">,</span> <span class="n">file_path</span> <span class="p">})</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The most notable thing to understand in this code block is the difference between how <strong>Go</strong> and <strong>Rust</strong> respectively handle <strong>JSON</strong>. In <strong>Go</strong>, you can use the <code>json.Unmarshal</code> method to parse the string of data and map it into a struct – the compiler will let you break everything – by design. <strong>Rust</strong> on the other hand, blocks it entirely before you can even compile. What does this mean? Instead of handing off the task to the <em>go runtime</em> in order to determine the <em>types</em> of the fields and how they are to map from string form into structured data form – <strong>Rust</strong> does it before compilation time using <code>.unwrap_or_else</code> whereas <strong>Go</strong> relies on <code>jsonErr != nil</code> to understand if a problem occurred. <strong>Rust</strong> enforces the types of the <code>struct</code> that you’re mapping data into at compilation time, whereas <strong>Go</strong> attempts to do this at runtime. This difference could be spending 5x the amount of time you’d normally spend in <strong>Go</strong> running <code>Unmarshal</code> on the data getting the type explicit nature of <strong>Rust</strong> compiling correctly. Ultimately, <strong>Rust</strong> forces correctness before compilation time – preventing the most painful part of <strong>Go</strong> development – <em>interacting with irregular JSON files</em>. </p>
<p>Literally, an <em>irregular JSON file</em> being implemented in <strong>Rust</strong> could legitimately take you 5x the amount of time to get right. The investment of time in this, on the surface, feels like its a waste and unnecessary – but years down the road, when you re-compile your program and <strong>Rust</strong> will always have correctness built in, whereas at any point that <strong>Go</strong> changes the <code>json</code> package, the way the runtime determines <em>type</em> <strong>could</strong> change. Doesn’t mean that it will or is wants to – but it could. And that potential, matters when you’re choosing a language that you can write once, and compile 25 years later with zero effort. C gives that to you. C++ gives that to you. Rust gives that to you. Go tries to. Higher level languages like Python, PHP and Ruby – can’t by definition and design of their languages. </p>
<p>We consumed the <code>new</code> method in the <code>main()</code> func when we established our <code>let mut store</code> (rust) and <code>store, err := NewTaskStore("tasks.json")</code> (go). </p>
<h3 id="taskstores-list-implemented">
<p>  TaskStore’s <code>list</code> Implemented<br />
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">List</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">)</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"No tasks yet. Add one with: taskr add </span><span class="se">"</span><span class="s">your task</span><span class="se">"</span><span class="s">"</span><span class="p">)</span>
        <span class="k">return</span>
    <span class="p">}</span>

    <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">task</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span> <span class="p">{</span>
        <span class="n">marker</span> <span class="o">:=</span> <span class="s">"[ ]"</span>
        <span class="k">if</span> <span class="n">task</span><span class="o">.</span><span class="n">Status</span> <span class="o">==</span> <span class="n">StatusDone</span> <span class="p">{</span>
            <span class="n">marker</span> <span class="o">=</span> <span class="s">"[X]"</span>
        <span class="p">}</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"%s %d - %s</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">marker</span><span class="p">,</span> <span class="n">task</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span> <span class="n">task</span><span class="o">.</span><span class="n">Title</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">list</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="k">self</span><span class="py">.tasks</span><span class="nf">.is_empty</span><span class="p">()</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"No tasks yet. Add one with: taskr add </span><span class="se">"</span><span class="s">your task</span><span class="se">"</span><span class="s">"</span><span class="p">);</span>
        <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">for</span> <span class="n">task</span> <span class="k">in</span> <span class="o">&</span><span class="k">self</span><span class="py">.tasks</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">market</span> <span class="o">=</span> <span class="k">match</span> <span class="n">task</span><span class="py">.status</span> <span class="p">{</span>
            <span class="nn">Status</span><span class="p">::</span><span class="n">Todo</span> <span class="k">=></span> <span class="s">"[ ]"</span><span class="p">,</span>
            <span class="nn">Status</span><span class="p">::</span><span class="n">Done</span> <span class="k">=></span> <span class="s">"[X]"</span><span class="p">,</span>
        <span class="p">};</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"{} {} - {}"</span><span class="p">,</span> <span class="n">market</span><span class="p">,</span> <span class="n">task</span><span class="py">.id</span><span class="p">,</span> <span class="n">task</span><span class="py">.title</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Respectively, these two methods look pretty much the same. Specifically in <strong>Rust</strong> we’re leveraging the borrower for <code>&self.tasks</code> and in <strong>Go</strong> we just range over them without needing to indicate memory usage. Without the <code>Debug</code> derived decorator attacked to the <code>Task</code> struct, the <code>println!()</code> methods that use <code>{}</code> wouldn’t compile.</p>
<h3 id="taskstores-add-implemented">
<p>  TaskStore’s <code>add</code> Implemented<br />
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Add</span><span class="p">(</span><span class="n">title</span> <span class="kt">string</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">var</span> <span class="n">maxID</span> <span class="kt">uint32</span>
    <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">t</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span> <span class="p">{</span>
        <span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">ID</span> <span class="o">></span> <span class="n">maxID</span> <span class="p">{</span>
            <span class="n">maxID</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">ID</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="n">task</span> <span class="o">:=</span> <span class="n">Task</span><span class="p">{</span>
        <span class="n">ID</span><span class="o">:</span>     <span class="n">maxID</span> <span class="o">+</span> <span class="m">1</span><span class="p">,</span>
        <span class="n">Title</span><span class="o">:</span>  <span class="n">title</span><span class="p">,</span>
        <span class="n">Status</span><span class="o">:</span> <span class="n">StatusTodo</span><span class="p">,</span>
    <span class="p">}</span>

    <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Added task %d: %s</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">task</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span> <span class="n">task</span><span class="o">.</span><span class="n">Title</span><span class="p">)</span>
    <span class="n">s</span><span class="o">.</span><span class="n">tasks</span> <span class="o">=</span> <span class="nb">append</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">,</span> <span class="n">task</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">add</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="nb">String</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">id</span> <span class="o">=</span> <span class="k">self</span><span class="py">.tasks</span><span class="nf">.iter</span><span class="p">()</span> <span class="c1">// use the iterator</span>
        <span class="nf">.map</span><span class="p">(|</span><span class="n">t</span><span class="p">|</span> <span class="n">t</span><span class="py">.id</span><span class="p">)</span>         <span class="c1">// use only the id field</span>
        <span class="nf">.max</span><span class="p">()</span>                 <span class="c1">// select the maximum value in the set</span>
        <span class="nf">.unwrap_or</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>     <span class="c1">// if no err, use # else use 0 + 1</span>

    <span class="k">let</span> <span class="n">task</span> <span class="o">=</span> <span class="n">Task</span> <span class="p">{</span>
        <span class="n">id</span><span class="p">,</span>                    <span class="c1">// short for `id: id,`</span>
        <span class="n">title</span><span class="p">,</span>                 <span class="c1">// short for `title: title,`</span>
        <span class="n">status</span><span class="p">:</span> <span class="nn">Status</span><span class="p">::</span><span class="n">Todo</span><span class="p">,</span>
    <span class="p">};</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"Added task {}: {}"</span><span class="p">,</span> <span class="n">task</span><span class="py">.id</span><span class="p">,</span> <span class="n">task</span><span class="py">.title</span><span class="p">);</span>

    <span class="k">self</span><span class="py">.tasks</span><span class="nf">.push</span><span class="p">(</span><span class="n">task</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Most notably between this <strong>Go</strong> and <strong>Rust</strong> code you can see the manner for acquiring the <em>next ID</em> in the set is radically different. In <strong>Rust</strong> we are using the <code>.iter()</code> in order to <code>.map()</code> then <code>.max()</code> with a final check of <code>.unwrap_or(0)</code> in order to get an iterable list of IDs via the <code>.map()</code> extraction of just the <code>id</code> field, followed by the <code>.max()</code> choice. This quickly returns the largest integer of the result and then attempts to <code>+ 1</code> at the end of it. In <strong>Rust</strong> this expression is a simple statement and in <strong>Go</strong> its multiple lines using <code>maxID</code> inside the method. </p>
<p>In <strong>Rust</strong> without the <code>&mut</code> on the <code>self</code> argument of the method, the <code>self.tasks.push(task);</code> would fail because the compiler is missing the <code>&mut</code> on <code>self</code> in order to actually <em>write</em> via <code>.push()</code>. In <strong>Go</strong>, we simply use <code>append(...)</code>. </p>
<p>Both languages now need to take this <code>impl TaskStore { "add" => {} }</code> and <code>func (s *TaskStore) Add(title string)</code> and consume them in the <code>main()</code> func.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="c">// ... existing after `switch args[1]`</span>

    <span class="k">case</span> <span class="s">"add"</span><span class="o">:</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o"><</span> <span class="m">3</span> <span class="p">{</span>
            <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintln</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="s">"Usage: taskr add <title>"</span><span class="p">)</span>
            <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
        <span class="p">}</span>
        <span class="n">store</span><span class="o">.</span><span class="n">Add</span><span class="p">(</span><span class="n">strings</span><span class="o">.</span><span class="n">Join</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="m">2</span><span class="o">:</span><span class="p">],</span> <span class="s">" "</span><span class="p">))</span>
        <span class="n">mustSave</span><span class="p">(</span><span class="n">store</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="c">// ... existing before `default:` case </span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>

    <span class="c1">// ... existing after `match args[1].to_str() {`</span>

    <span class="c1">// 2. taskr add <title></span>
    <span class="s">"add"</span> <span class="k">=></span> <span class="p">{</span>
        <span class="k">if</span> <span class="n">args</span><span class="nf">.len</span><span class="p">()</span> <span class="o"><</span> <span class="mi">3</span> <span class="p">{</span>
            <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Usage: taskr add <title>"</span><span class="p">);</span>
            <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// SIGTERM 1</span>
        <span class="p">}</span>
        <span class="k">let</span> <span class="n">title</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="o">..</span><span class="p">]</span><span class="nf">.join</span><span class="p">(</span><span class="s">" "</span><span class="p">);</span>
        <span class="n">store</span><span class="nf">.add</span><span class="p">(</span><span class="n">title</span><span class="p">);</span>
        <span class="n">store</span><span class="nf">.save</span><span class="p">()</span><span class="o">?</span><span class="p">;</span>
        <span class="nf">Ok</span><span class="p">(())</span>
    <span class="p">}</span>

    <span class="c1">// ... existing before `_ => {}` match</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Our <strong>Go</strong> code is consuming the <code>mustSave</code> helper method and our <strong>Rust</strong> code is calling <code>.add()</code> and <code>.save()</code> endpoints on the <code>TaskStore</code> <code>impl</code>. </p>
<h3 id="taskstores-delete-implemented">
<p>  TaskStore’s <code>delete</code> Implemented<br />
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Delete</span><span class="p">(</span><span class="n">id</span> <span class="kt">uint32</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">t</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span> <span class="p">{</span>
        <span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">ID</span> <span class="o">==</span> <span class="n">id</span> <span class="p">{</span>
            <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Removed task %d: %s</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Title</span><span class="p">)</span>
            <span class="n">s</span><span class="o">.</span><span class="n">tasks</span> <span class="o">=</span> <span class="nb">append</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="o">:</span><span class="n">i</span><span class="p">],</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="m">1</span><span class="o">:</span><span class="p">]</span><span class="o">...</span><span class="p">)</span>
            <span class="k">return</span> <span class="no">nil</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"task %d not found"</span><span class="p">,</span> <span class="n">id</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">delete</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">id</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-></span> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span> <span class="nb">String</span><span class="o">></span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">pos</span> <span class="o">=</span> <span class="k">self</span><span class="py">.tasks</span><span class="nf">.iter</span><span class="p">()</span>       <span class="c1">// get an iterator</span>
        <span class="nf">.position</span><span class="p">(|</span><span class="n">t</span><span class="p">|</span> <span class="n">t</span><span class="py">.id</span> <span class="o">==</span> <span class="n">id</span><span class="p">)</span>     <span class="c1">// find the index of the id</span>
        <span class="nf">.ok_or_else</span><span class="p">(||</span> 
            <span class="nd">format!</span><span class="p">(</span><span class="s">"Task {} not found"</span><span class="p">,</span> <span class="n">id</span><span class="p">)</span>
        <span class="p">)</span><span class="o">?</span><span class="p">;</span>

    <span class="k">let</span> <span class="n">removed</span> <span class="o">=</span> <span class="k">self</span><span class="py">.tasks</span><span class="nf">.remove</span><span class="p">(</span><span class="n">pos</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Removed task {}: {}"</span><span class="p">,</span> <span class="n">removed</span><span class="py">.id</span><span class="p">,</span> <span class="n">removed</span><span class="py">.title</span><span class="p">);</span> 
    <span class="nf">Ok</span><span class="p">(())</span> 
<span class="p">}</span>
</code></pre>
</div>
<p>As you can see – these methods look so <em>similar</em> and that’s because <strong>Go</strong> and <strong>Rust</strong> compliment each other, like <strong>C</strong> and <strong>C++</strong> complimented each other. They are designed to be similar, but one for more lower level work and the other for more higher level data driven work.  Either way, when you implement these methods, you see their implementations even look similar.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">case</span> <span class="s">"delete"</span><span class="o">:</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o"><</span> <span class="m">3</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintln</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="s">"Usage: taskr delete <id>"</span><span class="p">)</span>
        <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">store</span><span class="o">.</span><span class="n">Delete</span><span class="p">(</span><span class="n">parseID</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="m">2</span><span class="p">]));</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintln</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
        <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="n">mustSave</span><span class="p">(</span><span class="n">store</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="s">"delete"</span> <span class="k">=></span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">args</span><span class="nf">.len</span><span class="p">()</span> <span class="o"><</span> <span class="mi">3</span> <span class="p">{</span>
        <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Usage: taskr delete"</span><span class="p">);</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">let</span> <span class="n">id</span><span class="p">:</span> <span class="nb">u32</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="nf">.parse</span><span class="p">()</span><span class="nf">.unwrap_or_else</span><span class="p">(|</span><span class="n">_</span><span class="p">|</span> <span class="p">{</span>
        <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Invalid task ID: {}"</span><span class="p">,</span> <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="p">});</span>
    <span class="k">if</span> <span class="k">let</span> <span class="nf">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=</span> <span class="n">store</span><span class="nf">.delete</span><span class="p">(</span><span class="n">id</span><span class="p">)</span> <span class="p">{</span>
        <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// SIGTERM 1</span>
    <span class="p">}</span>
    <span class="n">store</span><span class="nf">.save</span><span class="p">()</span><span class="o">?</span><span class="p">;</span>
    <span class="nf">Ok</span><span class="p">(())</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Most notably in the differences between these two implementations, you can see the <strong>Go</strong> helper method <code>parseID</code> being used here where <strong>Rust</strong> just leverages <code>.parse().unwrap_or_else(|_| {} )</code> instead. </p>
<h3 id="taskstores-complete-done-implemented">
<p>  TaskStore’s <code>complete</code> | <code>done</code> Implemented<br />
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Complete</span><span class="p">(</span><span class="n">id</span> <span class="kt">uint32</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
    <span class="k">for</span> <span class="n">i</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span> <span class="p">{</span>
        <span class="k">if</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">ID</span> <span class="o">==</span> <span class="n">id</span> <span class="p">{</span>
            <span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">Status</span> <span class="o">=</span> <span class="n">StatusDone</span>
            <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Completed task %d: %s</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">Title</span><span class="p">)</span>
            <span class="k">return</span> <span class="no">nil</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"task %d not found"</span><span class="p">,</span> <span class="n">id</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">delete</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">id</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-></span> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span> <span class="nb">String</span><span class="o">></span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">pos</span> <span class="o">=</span> <span class="k">self</span><span class="py">.tasks</span><span class="nf">.iter</span><span class="p">()</span>    <span class="c1">// get an iterator</span>
        <span class="nf">.position</span><span class="p">(|</span><span class="n">t</span><span class="p">|</span> <span class="n">t</span><span class="py">.id</span> <span class="o">==</span> <span class="n">id</span><span class="p">)</span>  <span class="c1">// find the index of the id</span>
        <span class="nf">.ok_or_else</span><span class="p">(||</span> 
            <span class="nd">format!</span><span class="p">(</span><span class="s">"Task {} not found"</span><span class="p">,</span> <span class="n">id</span><span class="p">)</span>
        <span class="p">)</span><span class="o">?</span><span class="p">;</span>

    <span class="k">let</span> <span class="n">removed</span> <span class="o">=</span> <span class="k">self</span><span class="py">.tasks</span><span class="nf">.remove</span><span class="p">(</span><span class="n">pos</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Removed task {}: {}"</span><span class="p">,</span> <span class="n">removed</span><span class="py">.id</span><span class="p">,</span> <span class="n">removed</span><span class="py">.title</span><span class="p">);</span> 
    <span class="nf">Ok</span><span class="p">(())</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The conventions between <strong>Rust</strong> and <strong>Go</strong> become very visibly noticeable in this manner of presentation.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">case</span> <span class="s">"done"</span><span class="o">:</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o"><</span> <span class="m">3</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintln</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="s">"Usage: taskr done <id>"</span><span class="p">)</span>
        <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">store</span><span class="o">.</span><span class="n">Complete</span><span class="p">(</span><span class="n">parseID</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="m">2</span><span class="p">]));</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintln</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
        <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="n">mustSave</span><span class="p">(</span><span class="n">store</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="s">"done"</span> <span class="k">=></span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">args</span><span class="nf">.len</span><span class="p">()</span> <span class="o"><</span> <span class="mi">3</span> <span class="p">{</span>
        <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Usage: taskr done"</span><span class="p">);</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// SIGTERM 1</span>
    <span class="p">}</span>
    <span class="k">let</span> <span class="n">id</span><span class="p">:</span> <span class="nb">u32</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="nf">.parse</span><span class="p">()</span><span class="nf">.unwrap_or_else</span><span class="p">(|</span><span class="n">_</span><span class="p">|</span> <span class="p">{</span>
        <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Invalid task ID: {}"</span><span class="p">,</span> <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// SIGTERM 1</span>
    <span class="p">});</span>
    <span class="k">if</span> <span class="k">let</span> <span class="nf">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=</span> <span class="n">store</span><span class="nf">.complete</span><span class="p">(</span><span class="n">id</span><span class="p">)</span> <span class="p">{</span>
        <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// SIGTERM 1</span>
    <span class="p">}</span>
    <span class="n">store</span><span class="nf">.save</span><span class="p">()</span><span class="o">?</span><span class="p">;</span>
    <span class="nf">Ok</span><span class="p">(())</span>
<span class="p">}</span>
</code></pre>
</div>
<h3 id="taskstores-search-implemented">
<p>  TaskStore’s <code>search</code> Implemented<br />
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">func</span> <span class="p">(</span><span class="n">s</span> <span class="o">*</span><span class="n">TaskStore</span><span class="p">)</span> <span class="n">Search</span><span class="p">(</span><span class="n">query</span> <span class="kt">string</span><span class="p">)</span> <span class="p">[]</span><span class="o">*</span><span class="n">Task</span> <span class="p">{</span>
    <span class="n">queryLower</span> <span class="o">:=</span> <span class="n">strings</span><span class="o">.</span><span class="n">ToLower</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
    <span class="k">var</span> <span class="n">results</span> <span class="p">[]</span><span class="o">*</span><span class="n">Task</span>
    <span class="k">for</span> <span class="n">i</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">s</span><span class="o">.</span><span class="n">tasks</span> <span class="p">{</span>
        <span class="k">if</span> <span class="n">strings</span><span class="o">.</span><span class="n">Contains</span><span class="p">(</span><span class="n">strings</span><span class="o">.</span><span class="n">ToLower</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">Title</span><span class="p">),</span> <span class="n">queryLower</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">results</span> <span class="o">=</span> <span class="nb">append</span><span class="p">(</span><span class="n">results</span><span class="p">,</span> <span class="o">&</span><span class="n">s</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">results</span>
<span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="k">fn</span> <span class="nf">search</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="o">&</span><span class="nb">str</span><span class="p">)</span> <span class="k">-></span> <span class="nb">Vec</span><span class="o"><&</span><span class="n">Task</span><span class="o">></span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">query_lower</span> <span class="o">=</span> <span class="n">query</span><span class="nf">.to_lowercase</span><span class="p">();</span>

    <span class="k">self</span><span class="py">.tasks</span><span class="nf">.iter</span><span class="p">()</span>                    <span class="c1">// get an iterator</span>
        <span class="nf">.filter</span><span class="p">(|</span><span class="n">task</span><span class="p">|</span>                   <span class="c1">// each task loop</span>
            <span class="n">task</span><span class="py">.title</span><span class="nf">.to_lowercase</span><span class="p">()</span>    <span class="c1">// get lowercase title</span>
                <span class="nf">.contains</span><span class="p">(</span><span class="o">&</span><span class="n">query_lower</span><span class="p">)</span>  <span class="c1">// match with query_lower</span>
        <span class="p">)</span>
        <span class="nf">.collect</span><span class="p">()</span>                       <span class="c1">// gather into vector</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Specifically, the <strong>Rust</strong> is returning <code>Vec<&Task></code> which is a referenced object explicitly from the <code>.collect()</code> output.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight go"><code><span class="k">case</span> <span class="s">"search"</span><span class="o">:</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o"><</span> <span class="m">3</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Fprintln</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="s">"Usage: taskr search <query>"</span><span class="p">)</span>
        <span class="n">os</span><span class="o">.</span><span class="n">Exit</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="n">query</span> <span class="o">:=</span> <span class="n">strings</span><span class="o">.</span><span class="n">Join</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="m">2</span><span class="o">:</span><span class="p">],</span> <span class="s">" "</span><span class="p">)</span>
    <span class="n">results</span> <span class="o">:=</span> <span class="n">store</span><span class="o">.</span><span class="n">Search</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">results</span><span class="p">)</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"No tasks found matching %q</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">query</span><span class="p">)</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Found %d tasks matching: %s</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">results</span><span class="p">),</span> <span class="n">query</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">task</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">results</span> <span class="p">{</span>
            <span class="n">marker</span> <span class="o">:=</span> <span class="s">"[ ]"</span>
            <span class="k">if</span> <span class="n">task</span><span class="o">.</span><span class="n">Status</span> <span class="o">==</span> <span class="n">StatusDone</span> <span class="p">{</span>
                <span class="n">marker</span> <span class="o">=</span> <span class="s">"[X]"</span>
            <span class="p">}</span>
            <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"%s %d: %s</span><span class="se">n</span><span class="s">"</span><span class="p">,</span> <span class="n">marker</span><span class="p">,</span> <span class="n">task</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span> <span class="n">task</span><span class="o">.</span><span class="n">Title</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight rust"><code><span class="s">"search"</span> <span class="k">=></span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">args</span><span class="nf">.len</span><span class="p">()</span> <span class="o"><</span> <span class="mi">3</span> <span class="p">{</span>
        <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Usage: taskr search <query>"</span><span class="p">);</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="nf">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// SIGTERM 1</span>
    <span class="p">}</span>

    <span class="k">let</span> <span class="n">query</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="o">..</span><span class="p">]</span><span class="nf">.join</span><span class="p">(</span><span class="s">" "</span><span class="p">);</span> 
    <span class="k">let</span> <span class="n">results</span> <span class="o">=</span> <span class="n">store</span><span class="nf">.search</span><span class="p">(</span><span class="o">&</span><span class="n">query</span><span class="p">);</span>

    <span class="k">if</span> <span class="n">results</span><span class="nf">.is_empty</span><span class="p">()</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"No tasks found matching </span><span class="se">"</span><span class="s">{}</span><span class="se">"</span><span class="s">"</span><span class="p">,</span> <span class="n">query</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"Found {} tasks matching: {}"</span><span class="p">,</span> <span class="n">results</span><span class="nf">.len</span><span class="p">(),</span> <span class="n">query</span><span class="p">);</span>
        <span class="k">for</span> <span class="n">task</span> <span class="k">in</span> <span class="o">&</span><span class="n">results</span> <span class="p">{</span> 
            <span class="k">let</span> <span class="n">marker</span> <span class="o">=</span> <span class="k">match</span> <span class="n">task</span><span class="py">.status</span> <span class="p">{</span> 
                <span class="nn">Status</span><span class="p">::</span><span class="n">Todo</span> <span class="k">=></span> <span class="s">"[ ]"</span><span class="p">,</span> <span class="c1">// incomplete items</span>
                <span class="nn">Status</span><span class="p">::</span><span class="n">Done</span> <span class="k">=></span> <span class="s">"[X]"</span><span class="p">,</span> <span class="c1">// completed items</span>
            <span class="p">};</span>
            <span class="nd">println!</span><span class="p">(</span><span class="s">"{} {}: {}"</span><span class="p">,</span> <span class="n">marker</span><span class="p">,</span> <span class="n">task</span><span class="py">.id</span><span class="p">,</span> <span class="n">task</span><span class="py">.title</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="nf">Ok</span><span class="p">(())</span>
<span class="p">}</span>
</code></pre>
</div>
<h2 id="conclusion">
<p>  Conclusion<br />
</h2>
<p>You can view the <a href="https://gist.github.com/andreimerlescu/82332b73f37fdc45b99ce5ea8e909c8b" rel="noopener noreferrer">Go</a> and <a href="https://gist.github.com/andreimerlescu/1e807d841aceb8d73ca32b9309895b35" rel="noopener noreferrer">Rust</a> full source code respectively at either link provided. </p>
<p>This tutorial was designed to help bring <strong>Go</strong> engineers over to <strong>Rust</strong> by completing a command line task manager application in both languages to see how they are both the <em>similar</em> and <em>different</em>. </p>
<p>Are you coming into <strong>Rust</strong> from <strong>Go</strong> like I am? If so, what are some of your favorite resources to use and learn from?</p>
			</div>

			<div class="cs-entry__tags"><ul><li><a href="https://prodsens.live/tag/discuss/" rel="tag">discuss</a></li><li><a href="https://prodsens.live/tag/go/" rel="tag">go</a></li><li><a href="https://prodsens.live/tag/prodsens-live/" rel="tag">prodsens live</a></li><li><a href="https://prodsens.live/tag/rust/" rel="tag">rust</a></li><li><a href="https://prodsens.live/tag/software/" rel="tag">Software</a></li><li><a href="https://prodsens.live/tag/tutorial/" rel="tag">tutorial</a></li></ul></div>			<div class="cs-entry__after-share-buttons">
						<div class="pk-share-buttons-wrap pk-share-buttons-layout-simple pk-share-buttons-scheme-simple-light pk-share-buttons-has-counts pk-share-buttons-has-total-counts pk-share-buttons-after-post pk-share-buttons-mode-php pk-share-buttons-mode-rest" data-post-id="51172" data-share-url="https://prodsens.live/2026/07/09/go-to-do-rust/" >

							<div class="pk-share-buttons-total pk-share-buttons-total-no-count">
												<div class="pk-share-buttons-title pk-font-primary">Total</div>
							<div class="pk-share-buttons-count pk-font-heading">0</div>
							<div class="pk-share-buttons-label pk-font-secondary">Shares</div>
										</div>
				
			<div class="pk-share-buttons-items">

										<div class="pk-share-buttons-item pk-share-buttons-facebook pk-share-buttons-no-count" data-id="facebook">

							<a href="https://www.facebook.com/sharer.php?u=https://prodsens.live/2026/07/09/go-to-do-rust/" class="pk-share-buttons-link" target="_blank">

																	<i class="pk-share-buttons-icon pk-icon pk-icon-facebook"></i>
								
								
																	<span class="pk-share-buttons-label pk-font-primary">Share</span>
								
																	<span class="pk-share-buttons-count pk-font-secondary">0</span>
															</a>

							
							
													</div>
											<div class="pk-share-buttons-item pk-share-buttons-twitter pk-share-buttons-no-count" data-id="twitter">

							<a href="https://twitter.com/share?&text=Go%20To%20Do%20Rust&via=prodsens_pro&url=https://prodsens.live/2026/07/09/go-to-do-rust/" class="pk-share-buttons-link" target="_blank">

																	<i class="pk-share-buttons-icon pk-icon pk-icon-twitter"></i>
								
								
																	<span class="pk-share-buttons-label pk-font-primary">Tweet</span>
								
																	<span class="pk-share-buttons-count pk-font-secondary">0</span>
															</a>

							
							
													</div>
											<div class="pk-share-buttons-item pk-share-buttons-pinterest pk-share-buttons-no-count" data-id="pinterest">

							<a href="https://pinterest.com/pin/create/bookmarklet/?url=https://prodsens.live/2026/07/09/go-to-do-rust/" class="pk-share-buttons-link" target="_blank">

																	<i class="pk-share-buttons-icon pk-icon pk-icon-pinterest"></i>
								
								
																	<span class="pk-share-buttons-label pk-font-primary">Pin it</span>
								
																	<span class="pk-share-buttons-count pk-font-secondary">0</span>
															</a>

							
							
													</div>
								</div>
		</div>
				</div>
			


<div class="cs-entry__comments cs-entry__comments-collapse" id="comments-hidden">

	
	
		<div id="respond" class="comment-respond">
		<h5 class="cs-section-heading cnvs-block-section-heading is-style-cnvs-block-section-heading-default halignleft  "><span class="cnvs-section-title"><span>Leave a Reply <small><a rel="nofollow" id="cancel-comment-reply-link" href="/2026/07/09/go-to-do-rust/?utm_source=rss&utm_medium=rss&utm_campaign=go-to-do-rust#respond" style="display:none;">Cancel reply</a></small></span></span></h5><form action="https://prodsens.live/wp-comments-post.php" method="post" id="commentform" class="comment-form"><p class="comment-notes"><span id="email-notes">Your email address will not be published.</span> <span class="required-field-message">Required fields are marked <span class="required">*</span></span></p><p class="comment-form-comment"><label for="comment">Comment <span class="required">*</span></label> <textarea autocomplete="new-password"  id="i402533545"  name="i402533545"   cols="45" rows="8" maxlength="65525" required></textarea><textarea id="comment" aria-label="hp-comment" aria-hidden="true" name="comment" autocomplete="new-password" style="padding:0 !important;clip:rect(1px, 1px, 1px, 1px) !important;position:absolute !important;white-space:nowrap !important;height:1px !important;width:1px !important;overflow:hidden !important;" tabindex="-1"></textarea><script data-noptimize>document.getElementById("comment").setAttribute( "id", "ad2a67412f013b56c619a364b01c2a93" );document.getElementById("i402533545").setAttribute( "id", "comment" );</script></p><p class="comment-form-author"><label for="author">Name <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" autocomplete="name" required /></p>
<p class="comment-form-email"><label for="email">Email <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" autocomplete="email" required /></p>
<p class="comment-form-url"><label for="url">Website</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" autocomplete="url" /></p>
<p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time I comment.</label></p>
<p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Post Comment" /> <input type='hidden' name='comment_post_ID' value='51172' id='comment_post_ID' />
<input type='hidden' name='comment_parent' id='comment_parent' value='0' />
</p></form>	</div><!-- #respond -->
	
</div>

	<div class="cs-entry__comments-show" id="comments">
		<button>View Comments (0)</button>
	</div>

	<div class="cs-entry__prev-next">
					<div class="cs-entry__prev-next-item cs-entry__prev">

				<a class="cs-entry__prev-next-link" href="https://prodsens.live/2026/07/09/i-shipped-an-angular-v22-book-update-with-a-crew-of-ai-agents-heres-the-system/"></a>

				<div class="cs-entry__prev-next-label">
					<h5 class="cs-section-heading cnvs-block-section-heading is-style-cnvs-block-section-heading-default halignleft  "><span class="cnvs-section-title"><span><span class="cs-section-subheadings">Previous Post</span></span></span></h5>				</div>

				<div class="cs-entry">
					<div class="cs-entry__outer">
						
						<div class="cs-entry__inner cs-entry__content">
							<div class="cs-entry__post-meta" ><div class="cs-meta-category"><ul class="post-categories">
	<li><a href="https://prodsens.live/category/software/" rel="category tag">Software</a></li></ul></div></div>
							<h2 class="cs-entry__title"><a href="https://prodsens.live/2026/07/09/i-shipped-an-angular-v22-book-update-with-a-crew-of-ai-agents-heres-the-system/">I Shipped an Angular v22 Book Update with a Crew of AI Agents. Here’s the System</a></h2>
							<div class="cs-entry__post-meta" ><div class="cs-meta-date">July 9, 2026</div></div>						</div>
					</div>
				</div>
			</div>
						<div class="cs-entry__prev-next-item cs-entry__next">

				<a class="cs-entry__prev-next-link" href="https://prodsens.live/2026/07/09/99736-every-thread-counts-eyevision-automated-inspection/"></a>

				<div class="cs-entry__prev-next-label">
					<h5 class="cs-section-heading cnvs-block-section-heading is-style-cnvs-block-section-heading-default halignleft  "><span class="cnvs-section-title"><span><span class="cs-section-subheadings">Next Post</span></span></span></h5>				</div>

				<div class="cs-entry">
					<div class="cs-entry__outer">
						
						<div class="cs-entry__inner cs-entry__content">
							<div class="cs-entry__post-meta" ><div class="cs-meta-category"><ul class="post-categories">
	<li><a href="https://prodsens.live/category/quality-assurance/" rel="category tag">Quality Assurance</a></li></ul></div></div>
							<h2 class="cs-entry__title"><a href="https://prodsens.live/2026/07/09/99736-every-thread-counts-eyevision-automated-inspection/">Every Thread Counts: EyeVision Automated Inspection</a></h2>
							<div class="cs-entry__post-meta" ><div class="cs-meta-date">July 9, 2026</div></div>						</div>
					</div>
				</div>
			</div>
				</div>
			</div>

		
	</div>

	</div>

		
	
	
</div>


	<aside id="secondary" class="cs-widget-area cs-sidebar__area">
		<div class="cs-sidebar__inner">
						<div class="widget block-2 widget_block widget_search"><form role="search" method="get" action="https://prodsens.live/" class="wp-block-search__button-outside wp-block-search__text-button wp-block-search"    ><label class="wp-block-search__label" for="wp-block-search__input-1" >Search</label><div class="wp-block-search__inside-wrapper " ><input class="wp-block-search__input" id="wp-block-search__input-1" placeholder="Type your text" value="" type="search" name="s" required /><button aria-label="search" class="wp-block-search__button wp-element-button" type="submit" >search</button></div></form></div><div class="widget block-3 widget_block">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h2 class="wp-block-heading">Recent Posts</h2>


<ul class="wp-block-latest-posts__list wp-block-latest-posts"><li><a class="wp-block-latest-posts__post-title" href="https://prodsens.live/2026/07/09/99736-every-thread-counts-eyevision-automated-inspection/">Every Thread Counts: EyeVision Automated Inspection</a></li>
<li><a class="wp-block-latest-posts__post-title" href="https://prodsens.live/2026/07/09/go-to-do-rust/">Go To Do Rust</a></li>
<li><a class="wp-block-latest-posts__post-title" href="https://prodsens.live/2026/07/09/i-shipped-an-angular-v22-book-update-with-a-crew-of-ai-agents-heres-the-system/">I Shipped an Angular v22 Book Update with a Crew of AI Agents. Here’s the System</a></li>
<li><a class="wp-block-latest-posts__post-title" href="https://prodsens.live/2026/07/09/data-quality-debt-ai-business-risk/">Is your Data Quality Debt Turning AI Investments into Business Risk</a></li>
<li><a class="wp-block-latest-posts__post-title" href="https://prodsens.live/2026/07/09/from-covid-pivot-to-ai-world-building-how-snapbar-reinvented-the-photo-experience/">From COVID Pivot to AI World Building: How Snapbar Reinvented the Photo Experience</a></li>
</ul></div></div>
</div><div class="widget block-4 widget_block">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h2 class="wp-block-heading">Recent Comments</h2>


<ol class="wp-block-latest-comments"><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><a class="wp-block-latest-comments__comment-author" href="https://www.villagetalkies.com">Village Talkies</a> on <a class="wp-block-latest-comments__comment-link" href="https://prodsens.live/2024/08/01/ai-media-planning-6-expert-tactics-you-cant-ignore/#comment-18570">AI Media Planning: 6 Expert Tactics You Can’t Ignore</a></footer></article></li><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><a class="wp-block-latest-comments__comment-author" href="https://www.villagetalkies.com">Village Talkies</a> on <a class="wp-block-latest-comments__comment-link" href="https://prodsens.live/2023/11/03/online-advertising-all-you-need-to-know-in-2023/#comment-18459">Online Advertising: All You Need to Know in 2023</a></footer></article></li><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><a class="wp-block-latest-comments__comment-author" href="https://www.villagetalkies.com">Village Talkies</a> on <a class="wp-block-latest-comments__comment-link" href="https://prodsens.live/2025/03/11/how-marketers-can-use-retail-media-networks-to-get-in-front-of-customers-expert-tips/#comment-14690">How Marketers Can Use Retail Media Networks to Get In Front of Customers [Expert Tips]</a></footer></article></li><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><a class="wp-block-latest-comments__comment-author" href="https://www.villagetalkies.com">Village Talkies</a> on <a class="wp-block-latest-comments__comment-link" href="https://prodsens.live/2023/12/13/2024-creator-economy-predictions/#comment-12243">2024 Creator Economy Predictions</a></footer></article></li><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><a class="wp-block-latest-comments__comment-author" href="https://www.villagetalkies.com">Village Talkies</a> on <a class="wp-block-latest-comments__comment-link" href="https://prodsens.live/2023/05/31/the-ultimate-guide-to-hiring-a-pr-agency-in-2023/#comment-11411">The Ultimate Guide to Hiring a PR Agency in 2023</a></footer></article></li></ol></div></div>
</div><div class="widget block-12 widget_block">
<h2 class="wp-block-heading">Tags</h2>
</div><div class="widget block-8 widget_block widget_tag_cloud"><p class="wp-block-tag-cloud"><a href="https://prodsens.live/tag/ai/" class="tag-cloud-link tag-link-419 tag-link-position-1" style="font-size: 14.776595744681pt;" aria-label="ai (1,671 items)">ai</a>
<a href="https://prodsens.live/tag/api/" class="tag-cloud-link tag-link-297 tag-link-position-2" style="font-size: 8.5957446808511pt;" aria-label="api (242 items)">api</a>
<a href="https://prodsens.live/tag/architecture/" class="tag-cloud-link tag-link-406 tag-link-position-3" style="font-size: 8pt;" aria-label="architecture (204 items)">architecture</a>
<a href="https://prodsens.live/tag/articles/" class="tag-cloud-link tag-link-1061 tag-link-position-4" style="font-size: 11.127659574468pt;" aria-label="Articles (538 items)">Articles</a>
<a href="https://prodsens.live/tag/artificial-intelligence/" class="tag-cloud-link tag-link-775 tag-link-position-5" style="font-size: 9.2659574468085pt;" aria-label="Artificial Intelligence (303 items)">Artificial Intelligence</a>
<a href="https://prodsens.live/tag/aws/" class="tag-cloud-link tag-link-229 tag-link-position-6" style="font-size: 10.159574468085pt;" aria-label="aws (395 items)">aws</a>
<a href="https://prodsens.live/tag/beginners/" class="tag-cloud-link tag-link-184 tag-link-position-7" style="font-size: 14.925531914894pt;" aria-label="beginners (1,752 items)">beginners</a>
<a href="https://prodsens.live/tag/career/" class="tag-cloud-link tag-link-190 tag-link-position-8" style="font-size: 9.7872340425532pt;" aria-label="career (356 items)">career</a>
<a href="https://prodsens.live/tag/cloud/" class="tag-cloud-link tag-link-308 tag-link-position-9" style="font-size: 8.7446808510638pt;" aria-label="cloud (258 items)">cloud</a>
<a href="https://prodsens.live/tag/company-news/" class="tag-cloud-link tag-link-573 tag-link-position-10" style="font-size: 8.8191489361702pt;" aria-label="Company News (263 items)">Company News</a>
<a href="https://prodsens.live/tag/content-marketing/" class="tag-cloud-link tag-link-267 tag-link-position-11" style="font-size: 10.159574468085pt;" aria-label="Content Marketing (400 items)">Content Marketing</a>
<a href="https://prodsens.live/tag/css/" class="tag-cloud-link tag-link-171 tag-link-position-12" style="font-size: 8.968085106383pt;" aria-label="css (275 items)">css</a>
<a href="https://prodsens.live/tag/database/" class="tag-cloud-link tag-link-415 tag-link-position-13" style="font-size: 8.5957446808511pt;" aria-label="database (244 items)">database</a>
<a href="https://prodsens.live/tag/devops/" class="tag-cloud-link tag-link-195 tag-link-position-14" style="font-size: 11.425531914894pt;" aria-label="devops (582 items)">devops</a>
<a href="https://prodsens.live/tag/discuss/" class="tag-cloud-link tag-link-163 tag-link-position-15" style="font-size: 10.755319148936pt;" aria-label="discuss (477 items)">discuss</a>
<a href="https://prodsens.live/tag/expertise/" class="tag-cloud-link tag-link-1350 tag-link-position-16" style="font-size: 8.2234042553191pt;" aria-label="Expertise (216 items)">Expertise</a>
<a href="https://prodsens.live/tag/frontend/" class="tag-cloud-link tag-link-338 tag-link-position-17" style="font-size: 8.2978723404255pt;" aria-label="frontend (223 items)">frontend</a>
<a href="https://prodsens.live/tag/guest-post/" class="tag-cloud-link tag-link-2939 tag-link-position-18" style="font-size: 8.3723404255319pt;" aria-label="Guest Post (229 items)">Guest Post</a>
<a href="https://prodsens.live/tag/java/" class="tag-cloud-link tag-link-283 tag-link-position-19" style="font-size: 8.4468085106383pt;" aria-label="java (234 items)">java</a>
<a href="https://prodsens.live/tag/javascript/" class="tag-cloud-link tag-link-160 tag-link-position-20" style="font-size: 14.925531914894pt;" aria-label="javascript (1,752 items)">javascript</a>
<a href="https://prodsens.live/tag/learning/" class="tag-cloud-link tag-link-221 tag-link-position-21" style="font-size: 9.2659574468085pt;" aria-label="learning (300 items)">learning</a>
<a href="https://prodsens.live/tag/machinelearning/" class="tag-cloud-link tag-link-386 tag-link-position-22" style="font-size: 8.8936170212766pt;" aria-label="machinelearning (268 items)">machinelearning</a>
<a href="https://prodsens.live/tag/marketing/" class="tag-cloud-link tag-link-81 tag-link-position-23" style="font-size: 15.670212765957pt;" aria-label="Marketing (2,195 items)">Marketing</a>
<a href="https://prodsens.live/tag/node/" class="tag-cloud-link tag-link-238 tag-link-position-24" style="font-size: 8.8191489361702pt;" aria-label="node (261 items)">node</a>
<a href="https://prodsens.live/tag/opensource/" class="tag-cloud-link tag-link-161 tag-link-position-25" style="font-size: 11.872340425532pt;" aria-label="opensource (674 items)">opensource</a>
<a href="https://prodsens.live/tag/planing/" class="tag-cloud-link tag-link-2955 tag-link-position-26" style="font-size: 9.1170212765957pt;" aria-label="planing (288 items)">planing</a>
<a href="https://prodsens.live/tag/planning/" class="tag-cloud-link tag-link-130 tag-link-position-27" style="font-size: 8.5212765957447pt;" aria-label="Planning (237 items)">Planning</a>
<a href="https://prodsens.live/tag/podcast/" class="tag-cloud-link tag-link-104 tag-link-position-28" style="font-size: 8.2978723404255pt;" aria-label="podcast (224 items)">podcast</a>
<a href="https://prodsens.live/tag/podcasts/" class="tag-cloud-link tag-link-1063 tag-link-position-29" style="font-size: 9.6382978723404pt;" aria-label="Podcasts (335 items)">Podcasts</a>
<a href="https://prodsens.live/tag/prodsens-live/" class="tag-cloud-link tag-link-2926 tag-link-position-30" style="font-size: 22pt;" aria-label="prodsens live (15,488 items)">prodsens live</a>
<a href="https://prodsens.live/tag/productivity/" class="tag-cloud-link tag-link-157 tag-link-position-31" style="font-size: 12.393617021277pt;" aria-label="Productivity (787 items)">Productivity</a>
<a href="https://prodsens.live/tag/product-management/" class="tag-cloud-link tag-link-79 tag-link-position-32" style="font-size: 15.297872340426pt;" aria-label="Product Management (1,969 items)">Product Management</a>
<a href="https://prodsens.live/tag/product-managment/" class="tag-cloud-link tag-link-2930 tag-link-position-33" style="font-size: 11.797872340426pt;" aria-label="product managment (655 items)">product managment</a>
<a href="https://prodsens.live/tag/programming/" class="tag-cloud-link tag-link-162 tag-link-position-34" style="font-size: 15.670212765957pt;" aria-label="programming (2,194 items)">programming</a>
<a href="https://prodsens.live/tag/project-management/" class="tag-cloud-link tag-link-132 tag-link-position-35" style="font-size: 10.010638297872pt;" aria-label="Project Management (378 items)">Project Management</a>
<a href="https://prodsens.live/tag/projectmanager-blog/" class="tag-cloud-link tag-link-131 tag-link-position-36" style="font-size: 9.7872340425532pt;" aria-label="ProjectManager Blog (354 items)">ProjectManager Blog</a>
<a href="https://prodsens.live/tag/python/" class="tag-cloud-link tag-link-259 tag-link-position-37" style="font-size: 11.5pt;" aria-label="python (602 items)">python</a>
<a href="https://prodsens.live/tag/quality-management/" class="tag-cloud-link tag-link-1110 tag-link-position-38" style="font-size: 15.968085106383pt;" aria-label="Quality Management (2,406 items)">Quality Management</a>
<a href="https://prodsens.live/tag/react/" class="tag-cloud-link tag-link-158 tag-link-position-39" style="font-size: 11.723404255319pt;" aria-label="react (645 items)">react</a>
<a href="https://prodsens.live/tag/security/" class="tag-cloud-link tag-link-271 tag-link-position-40" style="font-size: 9.2659574468085pt;" aria-label="security (303 items)">security</a>
<a href="https://prodsens.live/tag/software/" class="tag-cloud-link tag-link-151 tag-link-position-41" style="font-size: 19.914893617021pt;" aria-label="Software (8,219 items)">Software</a>
<a href="https://prodsens.live/tag/tutorial/" class="tag-cloud-link tag-link-168 tag-link-position-42" style="font-size: 13.585106382979pt;" aria-label="tutorial (1,151 items)">tutorial</a>
<a href="https://prodsens.live/tag/typescript/" class="tag-cloud-link tag-link-239 tag-link-position-43" style="font-size: 9.6382978723404pt;" aria-label="typescript (338 items)">typescript</a>
<a href="https://prodsens.live/tag/uncategorized/" class="tag-cloud-link tag-link-1029 tag-link-position-44" style="font-size: 8.968085106383pt;" aria-label="Uncategorized (272 items)">Uncategorized</a>
<a href="https://prodsens.live/tag/webdev/" class="tag-cloud-link tag-link-172 tag-link-position-45" style="font-size: 16.563829787234pt;" aria-label="webdev (2,892 items)">webdev</a></p></div><div class="widget block-14 widget_block widget_calendar"><div class="wp-block-calendar"><table id="wp-calendar" class="wp-calendar-table">
	<caption>July 2026</caption>
	<thead>
	<tr>
		<th scope="col" aria-label="Monday">M</th>
		<th scope="col" aria-label="Tuesday">T</th>
		<th scope="col" aria-label="Wednesday">W</th>
		<th scope="col" aria-label="Thursday">T</th>
		<th scope="col" aria-label="Friday">F</th>
		<th scope="col" aria-label="Saturday">S</th>
		<th scope="col" aria-label="Sunday">S</th>
	</tr>
	</thead>
	<tbody>
	<tr>
		<td colspan="2" class="pad"> </td><td><a href="https://prodsens.live/2026/07/01/" aria-label="Posts published on July 1, 2026">1</a></td><td><a href="https://prodsens.live/2026/07/02/" aria-label="Posts published on July 2, 2026">2</a></td><td><a href="https://prodsens.live/2026/07/03/" aria-label="Posts published on July 3, 2026">3</a></td><td><a href="https://prodsens.live/2026/07/04/" aria-label="Posts published on July 4, 2026">4</a></td><td><a href="https://prodsens.live/2026/07/05/" aria-label="Posts published on July 5, 2026">5</a></td>
	</tr>
	<tr>
		<td><a href="https://prodsens.live/2026/07/06/" aria-label="Posts published on July 6, 2026">6</a></td><td><a href="https://prodsens.live/2026/07/07/" aria-label="Posts published on July 7, 2026">7</a></td><td><a href="https://prodsens.live/2026/07/08/" aria-label="Posts published on July 8, 2026">8</a></td><td id="today"><a href="https://prodsens.live/2026/07/09/" aria-label="Posts published on July 9, 2026">9</a></td><td>10</td><td>11</td><td>12</td>
	</tr>
	<tr>
		<td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td>
	</tr>
	<tr>
		<td>20</td><td>21</td><td>22</td><td>23</td><td>24</td><td>25</td><td>26</td>
	</tr>
	<tr>
		<td>27</td><td>28</td><td>29</td><td>30</td><td>31</td>
		<td class="pad" colspan="2"> </td>
	</tr>
	</tbody>
	</table><nav aria-label="Previous and next months" class="wp-calendar-nav">
		<span class="wp-calendar-nav-prev"><a href="https://prodsens.live/2026/06/">« Jun</a></span>
		<span class="pad"> </span>
		<span class="wp-calendar-nav-next"> </span>
	</nav></div></div>					</div>
	</aside>
	
							
						</div>

								<div class="cs-entry__post-related">
			<h5 class="cs-section-heading cnvs-block-section-heading is-style-cnvs-block-section-heading-default halignleft  "><span class="cnvs-section-title"><span><span class="cs-section-subheadings">Related Posts</span></span></span></h5>
			<div class="cs-entry__post-wrap">
				

	<article class="cs-entry-default post-2813 post type-post status-publish format-standard has-post-thumbnail category-software tag-angular tag-css tag-javascript tag-typescript cs-entry cs-video-wrap">
		<div class="cs-entry__outer">
							<div class="cs-entry__inner cs-entry__thumbnail cs-entry__overlay cs-overlay-ratio cs-ratio-original" data-scheme="inverse">

											<div class="cs-overlay-background">
							<img width="380" height="250" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXwAAAD6AQMAAACYt274AAAAA1BMVEUAAP+KeNJXAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAACNJREFUaN7twTEBAAAAwqD1T20MH6AAAAAAAAAAAAAAAICfAS/aAAH7Vn1zAAAAAElFTkSuQmCC" class="attachment-csco-thumbnail size-csco-thumbnail pk-lazyload wp-post-image" alt="angular:-design-pop-over" decoding="async" loading="lazy" data-pk-sizes="auto" data-ls-sizes="auto, (max-width: 380px) 100vw, 380px" data-pk-src="https://prodsens.live/wp-content/uploads/2022/08/2813-angular-design-pop-over-380x250.png" data-pk-srcset="https://prodsens.live/wp-content/uploads/2022/08/2813-angular-design-pop-over-380x250.png 380w, https://prodsens.live/wp-content/uploads/2022/08/2813-angular-design-pop-over-230x150.png 230w, https://prodsens.live/wp-content/uploads/2022/08/2813-angular-design-pop-over-260x170.png 260w" />						</div>
					
					
					
											<div class="cs-overlay-content">
							<div class="cs-entry__post-meta" ><div class="cs-meta-comments"><span class="cs-meta-icon"><i class="cs-icon cs-icon-message-square"></i></span><a href="https://prodsens.live/2022/08/16/angular-design-pop-over/#respond" class="comments-link" >0</a></div><div class="cs-meta-reading-time"><span class="cs-meta-icon"><i class="cs-icon cs-icon-clock"></i></span>1 min</div></div>						</div>
					
					<a href="https://prodsens.live/2022/08/16/angular-design-pop-over/" class="cs-overlay-link"></a>
				</div>
			
			<div class="cs-entry__inner cs-entry__content">

				<div class="cs-entry__post-meta" ><div class="cs-meta-category"><ul class="post-categories">
	<li><a href="https://prodsens.live/category/software/" rel="category tag">Software</a></li></ul></div></div>
				<h2 class="cs-entry__title"><a href="https://prodsens.live/2022/08/16/angular-design-pop-over/">Angular: Design Pop Over</a></h2>
									<div class="cs-entry__excerpt">
						In almost every SPA, popover is very much used component in Angular. Here, I am going to design…					</div>
				
							<div class="cs-entry__details ">
									<div class="cs-entry__details-data">
																<a class="cs-author-avatar" href="https://prodsens.live/author/gerard-metrailler/"><img alt='' src='https://secure.gravatar.com/avatar/9bb717a660909690e642baeda892cfcea365d7bc3a1f17005e0e8057d77f1ced?s=40&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/9bb717a660909690e642baeda892cfcea365d7bc3a1f17005e0e8057d77f1ced?s=80&d=mm&r=g 2x' class='avatar avatar-40 photo' height='40' width='40' loading='lazy' decoding='async'/></a>
															<div class="cs-entry__details-meta">
							<div class="cs-entry__author-meta"><a href="https://prodsens.live/author/gerard-metrailler/">Gerard Metrailler</a></div><div class="cs-entry__post-meta" ><div class="cs-meta-date">August 16, 2022</div></div>						</div>
					</div>
				
									<div class="cs-entry__read-more">
						<a href="https://prodsens.live/2022/08/16/angular-design-pop-over/">
							Read More						</a>
					</div>
				
							</div>
						</div>
		</div>
	</article>



	<article class="cs-entry-default post-28048 post type-post status-publish format-standard has-post-thumbnail category-software tag-prodsens-live tag-software cs-entry cs-video-wrap">
		<div class="cs-entry__outer">
							<div class="cs-entry__inner cs-entry__thumbnail cs-entry__overlay cs-overlay-ratio cs-ratio-original" data-scheme="inverse">

											<div class="cs-overlay-background">
							<img width="380" height="250" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXwAAAD6AQMAAACYt274AAAAA1BMVEUAAP+KeNJXAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAACNJREFUaN7twTEBAAAAwqD1T20MH6AAAAAAAAAAAAAAAICfAS/aAAH7Vn1zAAAAAElFTkSuQmCC" class="attachment-csco-thumbnail size-csco-thumbnail pk-lazyload wp-post-image" alt="updated-production-ready-gemini-models,-reduced-1.5-pro-pricing,-increased-rate-limits,-and-more" decoding="async" loading="lazy" data-pk-sizes="auto" data-ls-sizes="auto, (max-width: 380px) 100vw, 380px" data-pk-src="https://prodsens.live/wp-content/uploads/2024/09/28048-updated-production-ready-gemini-models-reduced-1-5-pro-pricing-increased-rate-limits-and-more-380x250.png" data-pk-srcset="https://prodsens.live/wp-content/uploads/2024/09/28048-updated-production-ready-gemini-models-reduced-1-5-pro-pricing-increased-rate-limits-and-more-380x250.png 380w, https://prodsens.live/wp-content/uploads/2024/09/28048-updated-production-ready-gemini-models-reduced-1-5-pro-pricing-increased-rate-limits-and-more-230x150.png 230w, https://prodsens.live/wp-content/uploads/2024/09/28048-updated-production-ready-gemini-models-reduced-1-5-pro-pricing-increased-rate-limits-and-more-260x170.png 260w" />						</div>
					
					
					
											<div class="cs-overlay-content">
							<div class="cs-entry__post-meta" ><div class="cs-meta-comments"><span class="cs-meta-icon"><i class="cs-icon cs-icon-message-square"></i></span><a href="https://prodsens.live/2024/09/26/updated-gemini-models-reduced-15-pro-pricing-increased-rate-limits-and-more/#respond" class="comments-link" >0</a></div><div class="cs-meta-reading-time"><span class="cs-meta-icon"><i class="cs-icon cs-icon-clock"></i></span>1 min</div></div>						</div>
					
					<a href="https://prodsens.live/2024/09/26/updated-gemini-models-reduced-15-pro-pricing-increased-rate-limits-and-more/" class="cs-overlay-link"></a>
				</div>
			
			<div class="cs-entry__inner cs-entry__content">

				<div class="cs-entry__post-meta" ><div class="cs-meta-category"><ul class="post-categories">
	<li><a href="https://prodsens.live/category/software/" rel="category tag">Software</a></li></ul></div></div>
				<h2 class="cs-entry__title"><a href="https://prodsens.live/2024/09/26/updated-gemini-models-reduced-15-pro-pricing-increased-rate-limits-and-more/">Updated production-ready Gemini models, reduced 1.5 Pro pricing, increased rate limits, and more</a></h2>
									<div class="cs-entry__excerpt">
						Learn about the latest updates to Google’s Gemini models, including reduced pricing for Gemini 1.5 Pro, increased rate…					</div>
				
							<div class="cs-entry__details ">
									<div class="cs-entry__details-data">
																<a class="cs-author-avatar" href="https://prodsens.live/author/admin123/"><img  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAP+KeNJXAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII="  width="40"  height="40"  alt="admin123"  class="avatar avatar-40 wp-user-avatar wp-user-avatar-40 alignnone photo pk-lazyload"  data-pk-sizes="auto"  data-pk-src="https://prodsens.live/wp-content/uploads/2026/04/prodsens_live_icon-80x80.jpg"  data-pk-srcset="https://prodsens.live/wp-content/uploads/2026/04/prodsens_live_icon-80x80.jpg 2x" ></a>
															<div class="cs-entry__details-meta">
							<div class="cs-entry__author-meta"><a href="https://prodsens.live/author/admin123/">admin123</a></div><div class="cs-entry__post-meta" ><div class="cs-meta-date">September 26, 2024</div></div>						</div>
					</div>
				
									<div class="cs-entry__read-more">
						<a href="https://prodsens.live/2024/09/26/updated-gemini-models-reduced-15-pro-pricing-increased-rate-limits-and-more/">
							Read More						</a>
					</div>
				
							</div>
						</div>
		</div>
	</article>



	<article class="cs-entry-default post-48078 post type-post status-publish format-standard category-software tag-claude tag-prodsens-live tag-productivity tag-python tag-showdev tag-software cs-entry cs-video-wrap">
		<div class="cs-entry__outer">
			
			<div class="cs-entry__inner cs-entry__content">

				<div class="cs-entry__post-meta" ><div class="cs-meta-category"><ul class="post-categories">
	<li><a href="https://prodsens.live/category/software/" rel="category tag">Software</a></li></ul></div></div>
				<h2 class="cs-entry__title"><a href="https://prodsens.live/2026/05/02/i-put-claude-inside-blenders-text-editor/">I put Claude inside Blender’s Text Editor</a></h2>
									<div class="cs-entry__excerpt">
						I got tired of the alt-tab loop. Write a Blender script. Hit an error. Switch to a browser.…					</div>
				
							<div class="cs-entry__details ">
									<div class="cs-entry__details-data">
																<a class="cs-author-avatar" href="https://prodsens.live/author/aileen-mcgraw/"><img alt='' src='https://secure.gravatar.com/avatar/771e8cf92db5ad1a0b64df8e633c5d229ba1631eff9dbcdd5075ade45b81f389?s=40&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/771e8cf92db5ad1a0b64df8e633c5d229ba1631eff9dbcdd5075ade45b81f389?s=80&d=mm&r=g 2x' class='avatar avatar-40 photo' height='40' width='40' loading='lazy' decoding='async'/></a>
															<div class="cs-entry__details-meta">
							<div class="cs-entry__author-meta"><a href="https://prodsens.live/author/aileen-mcgraw/">Aileen McGraw</a></div><div class="cs-entry__post-meta" ><div class="cs-meta-date">May 2, 2026</div></div>						</div>
					</div>
				
									<div class="cs-entry__read-more">
						<a href="https://prodsens.live/2026/05/02/i-put-claude-inside-blenders-text-editor/">
							Read More						</a>
					</div>
				
							</div>
						</div>
		</div>
	</article>

			</div>
		</div>
	
	
	
					</div>

					
				</div>

				
			</main>

		
		
<footer data-rocket-location-hash="2c6cbd98bb2d03e13a6ca52edce2d693" class="cs-footer cs-footer-two" data-scheme="dark">
	<div class="cs-container">
		<div class="cs-footer__item">
			<div class="cs-footer__col  cs-col-left">
				<div class="cs-footer__inner">
							<div class="cs-logo">
			<a class="cs-footer__logo cs-logo-once" href="https://prodsens.live/">
				prodSens.live			</a>

					</div>
		
								<div class="cs-footer__desc">
				Designed & Developed by <a href="https://prodsens.live/">Xezero.com</a>			</div>
							</div>
			</div>
			<div class="cs-footer__col cs-col-center">
							<div class="footer-nav-menu">
				<ul id="menu-primary" class="cs-footer__nav cs-nav-grid"><li id="menu-item-198" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-privacy-policy menu-item-198"><a rel="privacy-policy" href="https://prodsens.live/privacy-policy-2/">Privacy Policy</a></li>
<li id="menu-item-1494" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1494"><a href="https://prodsens.live/terms-conditions/">Terms & Conditions</a></li>
<li id="menu-item-1493" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1493"><a href="https://prodsens.live/contact-us/">Contact us</a></li>
</ul>			</div>
						</div>
			<div class="cs-footer__col cs-col-right">
				<div class="cs-footer-social-links">
							<div class="cs-footer-social-links">
				<div class="pk-social-links-wrap  pk-social-links-template-nav pk-social-links-align-default pk-social-links-scheme-bold pk-social-links-titles-disabled pk-social-links-counts-disabled pk-social-links-labels-disabled">
		<div class="pk-social-links-items">
								<div class="pk-social-links-item pk-social-links-facebook  pk-social-links-no-count" data-id="facebook">
						<a href="https://facebook.com/prodsenslive" class="pk-social-links-link" target="_blank" rel="nofollow noopener" aria-label="Facebook">
							<i class="pk-social-links-icon pk-icon pk-icon-facebook"></i>
							
							
							
													</a>
					</div>
										<div class="pk-social-links-item pk-social-links-linkedin  pk-social-links-no-count" data-id="linkedin">
						<a href="https://www.linkedin.com/company/prodsens-live" class="pk-social-links-link" target="_blank" rel="nofollow noopener" aria-label="LinkedIn">
							<i class="pk-social-links-icon pk-icon pk-icon-linkedin"></i>
							
							
							
													</a>
					</div>
										<div class="pk-social-links-item pk-social-links-twitter  pk-social-links-no-count" data-id="twitter">
						<a href="https://twitter.com/prodsens_pro" class="pk-social-links-link" target="_blank" rel="nofollow noopener" aria-label="Twitter">
							<i class="pk-social-links-icon pk-icon pk-icon-twitter"></i>
							
							
							
													</a>
					</div>
							</div>
	</div>
			</div>
						</div>
			</div>
		</div>
	</div>
</footer>

		
	</div>

	
</div>


<script type="speculationrules">
{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"\/*"},{"not":{"href_matches":["\/wp-*.php","\/wp-admin\/*","\/wp-content\/uploads\/*","\/wp-content\/*","\/wp-content\/plugins\/*","\/wp-content\/themes\/networker\/*","\/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}
</script>

<style type="text/css" media="all" id="canvas-widget-blocks-dynamic-styles">

</style>
<!--googleoff: all--><div id="cookie-law-info-bar" data-nosnippet="true"><span><div class="cli-bar-container cli-style-v2"><div class="cli-bar-message">We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.</div><div class="cli-bar-btn_container"><a role='button' class="medium cli-plugin-button cli-plugin-main-button cli_settings_button" style="margin:0px 5px 0px 0px">Cookie Settings</a><a id="wt-cli-accept-all-btn" role='button' data-cli_action="accept_all" class="wt-cli-element medium cli-plugin-button wt-cli-accept-all-btn cookie_action_close_header cli_action_button">Accept All</a></div></div></span></div><div id="cookie-law-info-again" data-nosnippet="true"><span id="cookie_hdr_showagain">Manage consent</span></div><div class="cli-modal" data-nosnippet="true" id="cliSettingsPopup" tabindex="-1" role="dialog" aria-labelledby="cliSettingsPopup" aria-hidden="true">
  <div class="cli-modal-dialog" role="document">
	<div class="cli-modal-content cli-bar-popup">
		  <button type="button" class="cli-modal-close" id="cliModalClose">
			<svg class="" viewBox="0 0 24 24"><path d="M19 6.41l-1.41-1.41-5.59 5.59-5.59-5.59-1.41 1.41 5.59 5.59-5.59 5.59 1.41 1.41 5.59-5.59 5.59 5.59 1.41-1.41-5.59-5.59z"></path><path d="M0 0h24v24h-24z" fill="none"></path></svg>
			<span class="wt-cli-sr-only">Close</span>
		  </button>
		  <div class="cli-modal-body">
			<div class="cli-container-fluid cli-tab-container">
	<div class="cli-row">
		<div class="cli-col-12 cli-align-items-stretch cli-px-0">
			<div class="cli-privacy-overview">
				<h4>Privacy Overview</h4>				<div class="cli-privacy-content">
					<div class="cli-privacy-content-text">This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.</div>
				</div>
				<a class="cli-privacy-readmore" aria-label="Show more" role="button" data-readmore-text="Show more" data-readless-text="Show less"></a>			</div>
		</div>
		<div class="cli-col-12 cli-align-items-stretch cli-px-0 cli-tab-section-container">
												<div class="cli-tab-section">
						<div class="cli-tab-header">
							<a role="button" tabindex="0" class="cli-nav-link cli-settings-mobile" data-target="necessary" data-toggle="cli-toggle-tab">
								Necessary							</a>
															<div class="wt-cli-necessary-checkbox">
									<input type="checkbox" class="cli-user-preference-checkbox"  id="wt-cli-checkbox-necessary" data-id="checkbox-necessary" checked="checked"  />
									<label class="form-check-label" for="wt-cli-checkbox-necessary">Necessary</label>
								</div>
								<span class="cli-necessary-caption">Always Enabled</span>
													</div>
						<div class="cli-tab-content">
							<div class="cli-tab-pane cli-fade" data-id="necessary">
								<div class="wt-cli-cookie-description">
									Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
<table class="cookielawinfo-row-cat-table cookielawinfo-winter"><thead><tr><th class="cookielawinfo-column-1">Cookie</th><th class="cookielawinfo-column-3">Duration</th><th class="cookielawinfo-column-4">Description</th></tr></thead><tbody><tr class="cookielawinfo-row"><td class="cookielawinfo-column-1">cookielawinfo-checkbox-analytics</td><td class="cookielawinfo-column-3">11 months</td><td class="cookielawinfo-column-4">This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".</td></tr><tr class="cookielawinfo-row"><td class="cookielawinfo-column-1">cookielawinfo-checkbox-functional</td><td class="cookielawinfo-column-3">11 months</td><td class="cookielawinfo-column-4">The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".</td></tr><tr class="cookielawinfo-row"><td class="cookielawinfo-column-1">cookielawinfo-checkbox-necessary</td><td class="cookielawinfo-column-3">11 months</td><td class="cookielawinfo-column-4">This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".</td></tr><tr class="cookielawinfo-row"><td class="cookielawinfo-column-1">cookielawinfo-checkbox-others</td><td class="cookielawinfo-column-3">11 months</td><td class="cookielawinfo-column-4">This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.</td></tr><tr class="cookielawinfo-row"><td class="cookielawinfo-column-1">cookielawinfo-checkbox-performance</td><td class="cookielawinfo-column-3">11 months</td><td class="cookielawinfo-column-4">This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".</td></tr><tr class="cookielawinfo-row"><td class="cookielawinfo-column-1">viewed_cookie_policy</td><td class="cookielawinfo-column-3">11 months</td><td class="cookielawinfo-column-4">The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.</td></tr></tbody></table>								</div>
							</div>
						</div>
					</div>
																	<div class="cli-tab-section">
						<div class="cli-tab-header">
							<a role="button" tabindex="0" class="cli-nav-link cli-settings-mobile" data-target="functional" data-toggle="cli-toggle-tab">
								Functional							</a>
															<div class="cli-switch">
									<input type="checkbox" id="wt-cli-checkbox-functional" class="cli-user-preference-checkbox"  data-id="checkbox-functional" />
									<label for="wt-cli-checkbox-functional" class="cli-slider" data-cli-enable="Enabled" data-cli-disable="Disabled"><span class="wt-cli-sr-only">Functional</span></label>
								</div>
													</div>
						<div class="cli-tab-content">
							<div class="cli-tab-pane cli-fade" data-id="functional">
								<div class="wt-cli-cookie-description">
									Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
								</div>
							</div>
						</div>
					</div>
																	<div class="cli-tab-section">
						<div class="cli-tab-header">
							<a role="button" tabindex="0" class="cli-nav-link cli-settings-mobile" data-target="performance" data-toggle="cli-toggle-tab">
								Performance							</a>
															<div class="cli-switch">
									<input type="checkbox" id="wt-cli-checkbox-performance" class="cli-user-preference-checkbox"  data-id="checkbox-performance" />
									<label for="wt-cli-checkbox-performance" class="cli-slider" data-cli-enable="Enabled" data-cli-disable="Disabled"><span class="wt-cli-sr-only">Performance</span></label>
								</div>
													</div>
						<div class="cli-tab-content">
							<div class="cli-tab-pane cli-fade" data-id="performance">
								<div class="wt-cli-cookie-description">
									Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
								</div>
							</div>
						</div>
					</div>
																	<div class="cli-tab-section">
						<div class="cli-tab-header">
							<a role="button" tabindex="0" class="cli-nav-link cli-settings-mobile" data-target="analytics" data-toggle="cli-toggle-tab">
								Analytics							</a>
															<div class="cli-switch">
									<input type="checkbox" id="wt-cli-checkbox-analytics" class="cli-user-preference-checkbox"  data-id="checkbox-analytics" />
									<label for="wt-cli-checkbox-analytics" class="cli-slider" data-cli-enable="Enabled" data-cli-disable="Disabled"><span class="wt-cli-sr-only">Analytics</span></label>
								</div>
													</div>
						<div class="cli-tab-content">
							<div class="cli-tab-pane cli-fade" data-id="analytics">
								<div class="wt-cli-cookie-description">
									Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
								</div>
							</div>
						</div>
					</div>
																	<div class="cli-tab-section">
						<div class="cli-tab-header">
							<a role="button" tabindex="0" class="cli-nav-link cli-settings-mobile" data-target="advertisement" data-toggle="cli-toggle-tab">
								Advertisement							</a>
															<div class="cli-switch">
									<input type="checkbox" id="wt-cli-checkbox-advertisement" class="cli-user-preference-checkbox"  data-id="checkbox-advertisement" />
									<label for="wt-cli-checkbox-advertisement" class="cli-slider" data-cli-enable="Enabled" data-cli-disable="Disabled"><span class="wt-cli-sr-only">Advertisement</span></label>
								</div>
													</div>
						<div class="cli-tab-content">
							<div class="cli-tab-pane cli-fade" data-id="advertisement">
								<div class="wt-cli-cookie-description">
									Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
								</div>
							</div>
						</div>
					</div>
																	<div class="cli-tab-section">
						<div class="cli-tab-header">
							<a role="button" tabindex="0" class="cli-nav-link cli-settings-mobile" data-target="others" data-toggle="cli-toggle-tab">
								Others							</a>
															<div class="cli-switch">
									<input type="checkbox" id="wt-cli-checkbox-others" class="cli-user-preference-checkbox"  data-id="checkbox-others" />
									<label for="wt-cli-checkbox-others" class="cli-slider" data-cli-enable="Enabled" data-cli-disable="Disabled"><span class="wt-cli-sr-only">Others</span></label>
								</div>
													</div>
						<div class="cli-tab-content">
							<div class="cli-tab-pane cli-fade" data-id="others">
								<div class="wt-cli-cookie-description">
									Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.
								</div>
							</div>
						</div>
					</div>
										</div>
	</div>
</div>
		  </div>
		  <div class="cli-modal-footer">
			<div class="wt-cli-element cli-container-fluid cli-tab-container">
				<div class="cli-row">
					<div class="cli-col-12 cli-align-items-stretch cli-px-0">
						<div class="cli-tab-footer wt-cli-privacy-overview-actions">
						
															<a id="wt-cli-privacy-save-btn" role="button" tabindex="0" data-cli-action="accept" class="wt-cli-privacy-btn cli_setting_save_button wt-cli-privacy-accept-btn cli-btn">SAVE & ACCEPT</a>
													</div>
						
					</div>
				</div>
			</div>
		</div>
	</div>
  </div>
</div>
<div data-rocket-location-hash="79966eb1feae7497261e26fa757919a1" class="cli-modal-backdrop cli-fade cli-settings-overlay"></div>
<div data-rocket-location-hash="8202117e2b044c4659c14be121bd0f3c" class="cli-modal-backdrop cli-fade cli-popupbar-overlay"></div>
<!--googleon: all-->			<a href="#top" class="pk-scroll-to-top">
				<i class="pk-icon pk-icon-up"></i>
			</a>
					<div data-rocket-location-hash="e27696f9f27f9766352e7eca75bf6b23" class="pk-mobile-share-overlay">
							</div>
					<div data-rocket-location-hash="0d86fd5afa4658b1f9669ebe1d4f91f1" id="fb-root"></div>
		<script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v17.0&appId=prodsenslive&autoLogAppEvents=1" nonce="Ci8te34e"></script>
	        <script>
            var _SEARCHWP_LIVE_AJAX_SEARCH_BLOCKS = true;
            var _SEARCHWP_LIVE_AJAX_SEARCH_ENGINE = 'default';
            var _SEARCHWP_LIVE_AJAX_SEARCH_CONFIG = 'default';
        </script>
        <link rel='stylesheet' id='cookie-law-info-table-css' href='https://prodsens.live/wp-content/plugins/cookie-law-info/legacy/public/css/cookie-law-info-table.css?ver=3.3.6' media='all' />
<script src="https://prodsens.live/wp-content/plugins/canvas/components/basic-elements/block-alert/public-block-alert.js?ver=2.5.1" id="canvas-block-alert-script-js"></script>
<script src="https://prodsens.live/wp-content/plugins/canvas/components/basic-elements/block-collapsibles/public-block-collapsibles.js?ver=2.5.1" id="canvas-block-collapsibles-script-js"></script>
<script src="https://prodsens.live/wp-content/plugins/canvas/components/basic-elements/block-tabs/public-block-tabs.js?ver=2.5.1" id="canvas-block-tabs-script-js"></script>
<script src="https://prodsens.live/wp-content/plugins/canvas/components/justified-gallery/block/jquery.justifiedGallery.min.js?ver=2.5.1" id="justifiedgallery-js"></script>
<script id="canvas-justified-gallery-js-extra">
var canvasJG = {"rtl":""};
</script>
<script src="https://prodsens.live/wp-content/plugins/canvas/components/justified-gallery/block/public-block-justified-gallery.js?ver=2.5.1" id="canvas-justified-gallery-js"></script>
<script src="https://prodsens.live/wp-includes/js/imagesloaded.min.js?ver=5.0.0" id="imagesloaded-js"></script>
<script src="https://prodsens.live/wp-content/plugins/canvas/components/slider-gallery/block/flickity.pkgd.min.js?ver=2.5.1" id="flickity-js"></script>
<script id="canvas-slider-gallery-js-extra">
var canvas_sg_flickity = {"page_info_sep":" of "};
</script>
<script src="https://prodsens.live/wp-content/plugins/canvas/components/slider-gallery/block/public-block-slider-gallery.js?ver=2.5.1" id="canvas-slider-gallery-js"></script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/basic-elements/public/js/public-powerkit-basic-elements.js?ver=4.0.0" id="powerkit-basic-elements-js"></script>
<script id="powerkit-justified-gallery-js-extra">
var powerkitJG = {"rtl":""};
</script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/justified-gallery/public/js/public-powerkit-justified-gallery.js?ver=3.0.2" id="powerkit-justified-gallery-js"></script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/lazyload/public/js/lazysizes.config.js?ver=6.8.5" id="lazysizes.config-js"></script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/lazyload/public/js/lazysizes.min.js?ver=6.8.5" id="lazysizes-js"></script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/lightbox/public/js/glightbox.min.js?ver=3.0.2" id="glightbox-js"></script>
<script id="powerkit-lightbox-js-extra">
var powerkit_lightbox_localize = {"text_previous":"Previous","text_next":"Next","text_close":"Close","text_loading":"Loading","text_counter":"of","single_image_selectors":".entry-content img","gallery_selectors":".wp-block-gallery,.gallery","exclude_selectors":"","zoom_icon":"1"};
</script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/lightbox/public/js/public-powerkit-lightbox.js?ver=3.0.2" id="powerkit-lightbox-js"></script>
<script id="powerkit-opt-in-forms-js-extra">
var opt_in = {"ajax_url":"https:\/\/prodsens.live\/wp-admin\/admin-ajax.php","warning_privacy":"Please confirm that you agree with our policies.","is_admin":"","server_error":"Server error occurred. Please try again later."};
</script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/opt-in-forms/public/js/public-powerkit-opt-in-forms.js?ver=3.0.2" id="powerkit-opt-in-forms-js"></script>
<script async="async" defer="defer" src="//assets.pinterest.com/js/pinit.js?ver=6.8.5" id="powerkit-pinterest-js"></script>
<script id="powerkit-pin-it-js-extra">
var powerkit_pinit_localize = {"image_selectors":".entry-content img","exclude_selectors":".cnvs-block-row,.cnvs-block-section,.cnvs-block-posts .entry-thumbnail,.cnvs-post-thumbnail,.pk-block-author,.pk-featured-categories img,.pk-inline-posts-container img,.pk-instagram-image,.pk-subscribe-image,.wp-block-cover,.pk-block-posts,.cs-posts-area__main,.cs-entry","only_hover":"1"};
</script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/pinterest/public/js/public-powerkit-pin-it.js?ver=3.0.2" id="powerkit-pin-it-js"></script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/scroll-to-top/public/js/public-powerkit-scroll-to-top.js?ver=3.0.2" id="powerkit-scroll-to-top-js"></script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/share-buttons/public/js/public-powerkit-share-buttons.js?ver=3.0.2" id="powerkit-share-buttons-js"></script>
<script id="powerkit-slider-gallery-js-extra">
var powerkit_sg_flickity = {"page_info_sep":" of "};
</script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/slider-gallery/public/js/public-powerkit-slider-gallery.js?ver=3.0.2" id="powerkit-slider-gallery-js"></script>
<script id="powerkit-table-of-contents-js-extra">
var powerkit_toc_config = {"label_show":"Show","label_hide":"Hide"};
</script>
<script src="https://prodsens.live/wp-content/plugins/powerkit/modules/table-of-contents/public/js/public-powerkit-table-of-contents.js?ver=3.0.2" id="powerkit-table-of-contents-js"></script>
<script id="csco-scripts-js-extra">
var csLocalize = {"siteSchemeMode":"system","siteSchemeToogle":"1"};
var csco_mega_menu = {"rest_url":"https:\/\/prodsens.live\/wp-json\/csco\/v1\/menu-posts"};
</script>
<script src="https://prodsens.live/wp-content/themes/networker/assets/js/scripts.js?ver=1.0.7" id="csco-scripts-js"></script>
<script src="https://prodsens.live/wp-includes/js/comment-reply.min.js?ver=6.8.5" id="comment-reply-js" async data-wp-strategy="async"></script>
<script id="swp-live-search-client-js-extra">
var searchwp_live_search_params = [];
searchwp_live_search_params = {"ajaxurl":"https:\/\/prodsens.live\/wp-admin\/admin-ajax.php","origin_id":51172,"config":{"default":{"engine":"default","input":{"delay":300,"min_chars":3},"results":{"position":"bottom","width":"auto","offset":{"x":0,"y":5}},"spinner":{"lines":12,"length":8,"width":3,"radius":8,"scale":1,"corners":1,"color":"#424242","fadeColor":"transparent","speed":1,"rotate":0,"animation":"searchwp-spinner-line-fade-quick","direction":1,"zIndex":2000000000,"className":"spinner","top":"50%","left":"50%","shadow":"0 0 1px transparent","position":"absolute"}}},"msg_no_config_found":"No valid SearchWP Live Search configuration found!","aria_instructions":"When autocomplete results are available use up and down arrows to review and enter to go to the desired page. Touch device users, explore by touch or with swipe gestures."};;
</script>
<script src="https://prodsens.live/wp-content/plugins/searchwp-live-ajax-search/assets/javascript/dist/script.min.js?ver=1.8.6" id="swp-live-search-client-js"></script>
	<script type="text/javascript">
		"use strict";

		(function($) {

			$( window ).on( 'load', function() {

				// Get all links.
				var powerkitSLinksIds = [];

				var powerkitSLinksRestBox = $( '.pk-social-links-mode-rest' );

				// Generate links Ids.
				$( powerkitSLinksRestBox ).each( function( index, wrap ) {

					if ( ! $( wrap ).hasClass( 'pk-social-links-counts-disabled' ) ) {

						$( wrap ).find( '.pk-social-links-item' ).each( function() {
							if ( $( this ).attr( 'data-id' ).length > 0 ) {
								powerkitSLinksIds.push( $( this ).attr( 'data-id' ) );
							}
						});
					}
				});

				// Generate links data.
				var powerkitSLinksData = {};

				if( powerkitSLinksIds.length > 0 ) {
					powerkitSLinksData = { 'ids' : powerkitSLinksIds.join() };
				}

				// Check data.
				if ( ! Object.entries( powerkitSLinksData ).length ) {
					return;
				}

				// Get results by REST API.
				$.ajax({
					type: 'GET',
					url: 'https://prodsens.live/wp-json/social-counts/v1/get-counts',
					data: powerkitSLinksData,
					beforeSend: function(){

						// Add Loading Class.
						powerkitSLinksRestBox.addClass( 'pk-social-links-loading' );
					},
					success: function( response ) {

						if ( ! $.isEmptyObject( response ) && ! response.hasOwnProperty( 'code' ) ) {

							// SLinks loop.
							$.each( response, function( index, data ) {

								// Find Bsa Item.
								var powerkitSLinksItem = powerkitSLinksRestBox.find( '.pk-social-links-item[data-id="' + index + '"]');

								// Set Class.
								if ( data.hasOwnProperty( 'class' ) ) {
									powerkitSLinksItem.addClass( data.class );
								}

								// Set Count.
								if ( data.hasOwnProperty( 'result' ) && data.result !== null && data.result.hasOwnProperty( 'count' ) ) {

									if ( data.result.count ) {
										// Class Item.
										powerkitSLinksItem.removeClass( 'pk-social-links-no-count' ).addClass( 'pk-social-links-item-count' );

										// Count item.
										powerkitSLinksItem.find( '.pk-social-links-count' ).not( '.pk-tippy' ).html( data.result.count );
									}
								} else {
									powerkitSLinksItem.addClass( 'pk-social-links-no-count' );
								}

							});
						}

						// Remove Loading Class.
						powerkitSLinksRestBox.removeClass( 'pk-social-links-loading' );
					},
					error: function() {

						// Remove Loading Class.
						powerkitSLinksRestBox.removeClass( 'pk-social-links-loading' );
					}
				});
			});

		})(jQuery);
	</script>
		<script type="text/javascript">
		"use strict";

		(function($) {

			$( window ).on( 'load', function() {

				// Each All Share boxes.
				$( '.pk-share-buttons-mode-rest' ).each( function() {

					var powerkitButtonsIds = [],
						powerkitButtonsBox = $( this );

					// Check Counts.
					if ( ! powerkitButtonsBox.hasClass( 'pk-share-buttons-has-counts' ) && ! powerkitButtonsBox.hasClass( 'pk-share-buttons-has-total-counts' ) ) {
						return;
					}

					powerkitButtonsBox.find( '.pk-share-buttons-item' ).each( function() {
						if ( $( this ).attr( 'data-id' ).length > 0 ) {
							powerkitButtonsIds.push( $( this ).attr( 'data-id' ) );
						}
					});

					// Generate accounts data.
					var powerkitButtonsData = {};

					if( powerkitButtonsIds.length > 0 ) {
						powerkitButtonsData = {
							'ids'     : powerkitButtonsIds.join(),
							'post_id' : powerkitButtonsBox.attr( 'data-post-id' ),
							'url'     : powerkitButtonsBox.attr( 'data-share-url' ),
						};
					}

					// Get results by REST API.
					$.ajax({
						type: 'GET',
						url: 'https://prodsens.live/wp-json/social-share/v1/get-shares',
						data: powerkitButtonsData,
						beforeSend: function(){

							// Add Loading Class.
							powerkitButtonsBox.addClass( 'pk-share-buttons-loading' );
						},
						success: function( response ) {

							if ( ! $.isEmptyObject( response ) && ! response.hasOwnProperty( 'code' ) ) {

								// Accounts loop.
								$.each( response, function( index, data ) {

									if ( index !== 'total_count' ) {

										// Find Bsa Item.
										var powerkitButtonsItem = powerkitButtonsBox.find( '.pk-share-buttons-item[data-id="' + index + '"]');

										// Set Count.
										if ( data.hasOwnProperty( 'count' ) && data.count  ) {

											powerkitButtonsItem.removeClass( 'pk-share-buttons-no-count' ).addClass( 'pk-share-buttons-item-count' );
											powerkitButtonsItem.find( '.pk-share-buttons-count' ).html( data.count );

										} else {
											powerkitButtonsItem.addClass( 'pk-share-buttons-no-count' );
										}
									}
								});

								if ( powerkitButtonsBox.hasClass( 'pk-share-buttons-has-total-counts' ) && response.hasOwnProperty( 'total_count' ) ) {
									var powerkitButtonsTotalBox = powerkitButtonsBox.find( '.pk-share-buttons-total' );

									if ( response.total_count ) {
										powerkitButtonsTotalBox.find( '.pk-share-buttons-count' ).html( response.total_count );
										powerkitButtonsTotalBox.show().removeClass( 'pk-share-buttons-total-no-count' );
									}
								}
							}

							// Remove Loading Class.
							powerkitButtonsBox.removeClass( 'pk-share-buttons-loading' );
						},
						error: function() {

							// Remove Loading Class.
							powerkitButtonsBox.removeClass( 'pk-share-buttons-loading' );
						}
					});
				});
			});

		})(jQuery);
	</script>
	    <script>
    (function() {
        var urlMap = {
            'Product Management': '/category/product-management',
			'Project Management': '/category/project-management',
            'Marketing': '/category/marketing',
            'Software': '/category/software',
            'Quality Assurance': '/category/quality-assurance',
            'Planning': '/category/planning',
            'AI': '/category/artificial-intelligence/',
			'Analytics': '/category/analytics'
        };
        
        function fixLinks() {
            // Header menu
            document.querySelectorAll('.cs-header__nav-inner a').forEach(function(link) {
                var text = link.textContent.trim();
                if (urlMap[text] && !link.getAttribute('href')) {
                    link.setAttribute('href', urlMap[text]);
//                     console.log('✓ Fixed:', text);
                }
            });
            
            // Mobile menu
            document.querySelectorAll('.cs-offcanvas__sidebar a').forEach(function(link) {
                var text = link.textContent.trim();
                if (urlMap[text] && !link.getAttribute('href')) {
                    link.setAttribute('href', urlMap[text]);
                }
            });
        }
        
        // Запускаем сразу
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', fixLinks);
        } else {
            fixLinks();
        }
    })();
    </script>
        <script>
    (function() {
        function addTelegram() {
            var allLists = document.querySelectorAll('.pk-social-links-items');
            var headerLists = [allLists[1], allLists[2], allLists[3]];
            
            headerLists.forEach(function(socialList) {
                if (socialList && !socialList.querySelector('.pk-social-links-telegram')) {
                    var telegramItem = document.createElement('div');
                    telegramItem.className = 'pk-social-links-item pk-social-links-telegram pk-social-links-no-count';
                    telegramItem.setAttribute('data-id', 'telegram');
                    telegramItem.innerHTML = '<a href="https://t.me/prodsens_live" class="pk-social-links-link" target="_blank" rel="nofollow noopener" aria-label="Telegram"><i class="pk-social-links-icon pk-icon pk-icon-telegram"></i><span class="pk-social-links-count pk-font-secondary">0</span></a>';
                    socialList.appendChild(telegramItem);
                }
            });
        }
        
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', addTelegram);
        } else {
            addTelegram();
        }
    })();
    </script>
    
<script>var rocket_beacon_data = {"ajax_url":"https:\/\/prodsens.live\/wp-admin\/admin-ajax.php","nonce":"8dcdfa6bad","url":"https:\/\/prodsens.live\/2026\/07\/09\/go-to-do-rust","is_mobile":false,"width_threshold":1600,"height_threshold":700,"delay":500,"debug":null,"status":{"atf":true,"lrc":true,"preconnect_external_domain":true},"elements":"img, video, picture, p, main, div, li, svg, section, header, span","lrc_threshold":1800,"preconnect_external_domain_elements":["link","script","iframe"],"preconnect_external_domain_exclusions":["static.cloudflareinsights.com","rel=\"profile\"","rel=\"preconnect\"","rel=\"dns-prefetch\"","rel=\"icon\""]}</script><script data-name="wpr-wpr-beacon" src='https://prodsens.live/wp-content/plugins/clsop/assets/js/wpr-beacon.min.js' async></script></body>
</html>
<!--
Performance optimized by Redis Object Cache. Learn more: https://wprediscache.com

Retrieved 15284 objects (3 MB) from Redis using PhpRedis (v6.3.0).
-->

<!-- Performance optimized by AccelerateWP. - Debug: cached@1783610847 -->