<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Praveen Chaudhary</title>
    <description>The latest articles on DEV Community by Praveen Chaudhary (@chaudharypraveen98).</description>
    <link>https://dev.to/chaudharypraveen98</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F557207%2F7e291a24-cd02-4747-8a53-edca0351c76c.png</url>
      <title>DEV Community: Praveen Chaudhary</title>
      <link>https://dev.to/chaudharypraveen98</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chaudharypraveen98"/>
    <language>en</language>
    <item>
      <title>Build Your Own curl - Rust</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Sat, 23 Mar 2024 17:26:08 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/build-your-own-curl-rust-5cj6</link>
      <guid>https://dev.to/chaudharypraveen98/build-your-own-curl-rust-5cj6</guid>
      <description>&lt;p&gt;We will build curl from scratch by accepting the coding challenge posted on &lt;a href="https://codingchallenges.fyi/challenges/challenge-curl/" rel="noopener noreferrer"&gt;Coding Challenges FYI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before moving ahead, you must know how TCP client-server connections work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.geeksforgeeks.org%2Fwp-content%2Fuploads%2FSocket_server-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.geeksforgeeks.org%2Fwp-content%2Fuploads%2FSocket_server-1.png" alt="client server socket connection" width="330" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can read more about &lt;a href="https://www.geeksforgeeks.org/tcp-server-client-implementation-in-c/" rel="noopener noreferrer"&gt;GeeksforGeeks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On Server Side: -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Socket&lt;/strong&gt;:- Socket object to expose our endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;setsockopt&lt;/strong&gt;:- This function sets the extra options for the sockets if needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bind&lt;/strong&gt;:- It binds the socket with the IP and port.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listen&lt;/strong&gt;:- Socket is now in &lt;em&gt;listening&lt;/em&gt; state, and listen at the specified port for the incoming connection request. Here it queues incoming client requests to connect. The second argument specifies the maximum number of requests it can queue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accept&lt;/strong&gt;:- In this phase, the server calls the accept function, which initiates the 3-way handshaking. The client sends a &lt;strong&gt;SYN&lt;/strong&gt; packet to the server, the server responds with the &lt;strong&gt;SYN-ACK&lt;/strong&gt; packet, and blocks(waits) the connection until it finally gets the &lt;strong&gt;ACK&lt;/strong&gt; packet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send/Recv&lt;/strong&gt;:- Once &lt;strong&gt;ACK&lt;/strong&gt; is received from the client, communication can proceed to and fro.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On Client Side: -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Socket initialization&lt;/strong&gt;:- In this setup, the socket is defined with all the configurations needed to connect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect&lt;/strong&gt;:- In this phase, the client calls the connect function, which sends the SYN packet to the server with the intent to connect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send/Recv&lt;/strong&gt;: Once the connection is established, the client can send and receive the data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We are doing to achieve in a few steps: - &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Getting the CLI arguments&lt;/li&gt;
&lt;li&gt;Creation of socket connection&lt;/li&gt;
&lt;li&gt;Sending the request&lt;/li&gt;
&lt;li&gt;Parsing the response&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Getting the CLI arguments.
&lt;/h2&gt;

&lt;p&gt;We will be using the library for &lt;a href="https://crates.io/crates/clap" rel="noopener noreferrer"&gt;Clap&lt;/a&gt; - A simple-to-use, efficient, and full-featured library for parsing command line arguments and subcommands.&lt;/p&gt;

&lt;p&gt;The clap library provides two different ways to build parse objects. First is the &lt;strong&gt;Builder&lt;/strong&gt; pattern(a creational design pattern to create complex things by the step-by-step process) and second &lt;strong&gt;Derive&lt;/strong&gt; pattern in which the library automatically generates code based on the macros.&lt;/p&gt;

&lt;p&gt;We are using the &lt;strong&gt;Builder&lt;/strong&gt; pattern for our CLI tool.&lt;/p&gt;

&lt;p&gt;But you can implement &lt;strong&gt;Derive pattern&lt;/strong&gt; at &lt;a href="https://docs.rs/clap/latest/clap/_derive/_tutorial/chapter_0/index.html" rel="noopener noreferrer"&gt;doc.rs/clap/_derive&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;'&lt;a href="//"&gt;cli.rs&lt;/a&gt;'&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use clap::{Arg, ArgMatches, Command};

pub fn get_arguments()-&amp;gt; ArgMatches{
    Command::new("Ccurl - custom curl")
        .about("It helps to make HTTP methods")
        .version("1.0")
        .author("Praveen Chaudhary &amp;lt;chaudharypraveen98@gmail.com&amp;gt;")
        .arg(Arg::new("url").index(1).required(true))
        .arg(
            Arg::new("x-method")
                .help("Http method which you want to use")
                .long("x-method")
                .short('X'),
        )
        .arg(
            Arg::new("data")
                .help("Payload you want to send with the request")
                .long("data")
                .short('d'),
        )
        .arg(
            Arg::new("headers")
                .help("Request header")
                .long("header")
                .short('H')
                .action(ArgAction::Append),
        )
        .arg(
            Arg::new("verbose")
                .help("verbose mode")
                .long("verbose")
                .short('v')
                .action(clap::ArgAction::SetTrue),
        )
        .get_matches()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firstly, we have to define the basic info like about, author, and version. &lt;/p&gt;

&lt;p&gt;We have defined all the arguments needed for our curl. We have made one positional required argument &lt;strong&gt;url&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Argument matching or parsing
&lt;/h3&gt;

&lt;p&gt;Clap makes it easier to match arguments.&lt;br&gt;&lt;br&gt;
For &lt;strong&gt;verbose&lt;/strong&gt;, we have used &lt;a href="https://docs.rs/clap/4.5.3/clap/struct.Arg.html#method.action" rel="noopener noreferrer"&gt;action&lt;/a&gt; method &lt;code&gt;.action(clap::ArgAction::SetTrue)&lt;/code&gt;  because it will not contain any subsequent value.&lt;br&gt;
For &lt;strong&gt;headers&lt;/strong&gt;, similarly, we have used &lt;a href="https://docs.rs/clap/4.5.3/clap/struct.Arg.html#method.action" rel="noopener noreferrer"&gt;action&lt;/a&gt; method &lt;code&gt;.action(ArgAction::Append)&lt;/code&gt;, &lt;strong&gt;Append&lt;/strong&gt; will append new values to the previous value if any value has already encountered.&lt;br&gt;
For others, we have simply used &lt;a href="https://docs.rs/clap/4.5.3/clap/struct.ArgMatches.html#method.get_one" rel="noopener noreferrer"&gt;get_one&lt;/a&gt; method to get the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let verbose_enabled = matches.contains_id("verbose") &amp;amp;&amp;amp; matches.get_flag("verbose");
    let url = matches.get_one::&amp;lt;String&amp;gt;("url").unwrap();
    let data = matches.get_one::&amp;lt;String&amp;gt;("data");
    let method = matches.get_one::&amp;lt;String&amp;gt;("x-method");
    let headers: Vec&amp;lt;&amp;amp;str&amp;gt; = matches
        .get_many::&amp;lt;String&amp;gt;("headers")
        .unwrap_or_default()
        .map(|s| s.as_str())
        .collect();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Drafting request with input information [ HTTP 1.1 - RFC9110.]
&lt;/h2&gt;

&lt;p&gt;We will be using the &lt;a href="https://datatracker.ietf.org/doc/html/rfc9110" rel="noopener noreferrer"&gt;RFC9110&lt;/a&gt; for HTTP 1.1 client. &lt;/p&gt;

&lt;p&gt;we will start with an empty string, and append all the information needed for the Request according to RFC.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn populate_get_request(
    protocol: &amp;amp;str,
    host: &amp;amp;str,
    path: &amp;amp;str,
    data: Option&amp;lt;&amp;amp;String&amp;gt;,
    method: Option&amp;lt;&amp;amp;String&amp;gt;,
    headers: Vec&amp;lt;&amp;amp;str&amp;gt;,
) -&amp;gt; String {
    let default_method = String::from("GET");
    let method = method.unwrap_or(&amp;amp;default_method);
    let mut res = String::new();
    res += &amp;amp;format!("{} /{} {}\r\n", method, path, protocol);
    res += &amp;amp;format!("Host: {}\r\n", host);
    res += "Accept: */*\r\n";
    res += "Connection: close\r\n";
    ....
    ....
    ....
    res += "\r\n";
    res
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;strong&gt;PUT&lt;/strong&gt; and &lt;strong&gt;POST&lt;/strong&gt;, we need to add headers and data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn populate_get_request(
    protocol: &amp;amp;str,
    host: &amp;amp;str,
    path: &amp;amp;str,
    data: Option&amp;lt;&amp;amp;String&amp;gt;,
    method: Option&amp;lt;&amp;amp;String&amp;gt;,
    headers: Vec&amp;lt;&amp;amp;str&amp;gt;,
) -&amp;gt; String {
    ....
    ....

    if method == "POST" || method == "PUT" {
        if headers.len() &amp;gt; 0 {
            for head in headers {
                res += head;
            }
            res += "\r\n"
        } else {
            res += "Content-Type: application/json\r\n";
        }
        if let Some(data_str) = data {
            let data_bytes = data_str.as_bytes();
            res += &amp;amp;format!("Content-Length: {}\r\n\r\n", data_bytes.len());
            res += data_str;
            res += "\r\n";
        }
    }

    ....
    res
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to RFC, for POST or PUT, we need to provide &lt;strong&gt;Content-Length&lt;/strong&gt; and &lt;strong&gt;Content-Type&lt;/strong&gt; header.&lt;/p&gt;

&lt;p&gt;So now we have a complete request string. Let's move to the socket connection, sending this request string to the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn populate_get_request(
    protocol: &amp;amp;str,
    host: &amp;amp;str,
    path: &amp;amp;str,
    data: Option&amp;lt;&amp;amp;String&amp;gt;,
    method: Option&amp;lt;&amp;amp;String&amp;gt;,
    headers: Vec&amp;lt;&amp;amp;str&amp;gt;,
) -&amp;gt; String {
    let default_method = String::from("GET");
    let method = method.unwrap_or(&amp;amp;default_method);
    let mut res = String::new();
    res += &amp;amp;format!("{} /{} {}\r\n", method, path, protocol);
    res += &amp;amp;format!("Host: {}\r\n", host);
    res += "Accept: */*\r\n";
    res += "Connection: close\r\n";

    if method == "POST" || method == "PUT" {
        if headers.len() &amp;gt; 0 {
            for head in headers {
                res += head;
            }
            res += "\r\n"
        } else {
            res += "Content-Type: application/json\r\n";
        }
        if let Some(data_str) = data {
            let data_bytes = data_str.as_bytes();
            res += &amp;amp;format!("Content-Length: {}\r\n\r\n", data_bytes.len());
            res += data_str;
            res += "\r\n";
        }
    }

    res += "\r\n";
    res
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Creation of socket connection
&lt;/h2&gt;

&lt;p&gt;We will be using the standard &lt;a href="https://doc.rust-lang.org/std/net/" rel="noopener noreferrer"&gt;rust network library&lt;/a&gt; for socket connection with the host server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main() {
    ....
    ....

    let tcp_socket = TcpStream::connect(socket_addr);

    match tcp_socket {
        Ok(mut stream) =&amp;gt; {
            ....
            ....
        }
        Err(e) =&amp;gt; {
            eprintln!("Failed to establish connection: {}", e);
        }
    }
    ....
    ....
}

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

&lt;/div&gt;



&lt;p&gt;Once we are successfully connected, we can listen and send your request to the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Sending the request
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;First we have to check if verbose mode is enabled, and then we print out the request.&lt;/li&gt;
&lt;li&gt;We have used the &lt;a href="https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all" rel="noopener noreferrer"&gt;write_all&lt;/a&gt; to ensure our that our whole buffer is added to the stream.&lt;/li&gt;
&lt;li&gt;Create a new empty buffer, and provide this buffer to the stream, to read the response data from the host.&lt;/li&gt;
&lt;li&gt;Converts that bytes string to UTF-8 string using the &lt;a href="https://doc.rust-lang.org/std/string/struct.String.html#method.from_utf8_lossy" rel="noopener noreferrer"&gt;from_utf8_lossy&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Print the response header and body.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main() {
    ....
    ....

    match tcp_socket {
        Ok(mut stream) =&amp;gt; {
            if verbose_enabled {
                let lines = buffer_str.lines();
                for line in lines {
                    println!("&amp;gt; {}", line)
                }
            }
            stream
                .write_all(buffer_str.as_bytes())
                .expect("Failed to write data to stream");

            //initializing the buffer reads data from the stream and stores it in the buffer.
            let mut buffer = [0; 1024];
            stream
                .read(&amp;amp;mut buffer)
                .expect("Failed to read from response from host!");

            // converts buffer data into a UTF-8 encoded string (lossy ensures invalid data can be truncated).
            let response = String::from_utf8_lossy(&amp;amp;buffer[..]);

            // dividing the response headers and body
            let (response_header, response_data) = parse_resp(&amp;amp;response);
            if verbose_enabled {
                let lines = response_header.split("\r\n");
                for line in lines {
                    println!("&amp;lt; {}", line)
                }
            }
            println!("{}", response_data);
        }
        Err(e) =&amp;gt; {
            eprintln!("Failed to establish connection: {}", e);
        }
    }
    ....
    ....
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Time for Testing
&lt;/h2&gt;

&lt;p&gt;cli - &lt;code&gt;cargo run -- http://eu.httpbin.org:80/get&lt;/code&gt;&lt;br&gt;
response -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "eu.httpbin.org", 
    "X-Amzn-Trace-Id": "Root=1-65fec214-25771a3e732101c433ce67a7"
  }, 
  "origin": "49.36.177.79", 
  "url": "http://eu.httpbin.org/get"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, you can test others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hurray!! We have been able to make our curl.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;If this helps you, Do &lt;strong&gt;star&lt;/strong&gt; and contribute.&lt;br&gt;
&lt;a href="https://github.com/chaudharypraveen98/ccurl" rel="noopener noreferrer"&gt;Ccurl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Hacking&lt;/strong&gt;&lt;br&gt;
Rustaceans!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>curl</category>
      <category>claprs</category>
      <category>cli</category>
    </item>
    <item>
      <title>Web Assembly With Rust</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Sun, 22 Jan 2023 12:45:52 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/web-assembly-with-rust-4gaf</link>
      <guid>https://dev.to/chaudharypraveen98/web-assembly-with-rust-4gaf</guid>
      <description>&lt;p&gt;It is a universal binary code that is designed for the web.&lt;/p&gt;

&lt;p&gt;Wasm uses a low virtual machine with linear memory. It executes safely inside the sandbox.&lt;/p&gt;

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

&lt;p&gt;Image Source :→ &lt;a href="https://tapadoo.com/wasm-the-future-of-the-web-and-how-affect-the-app-market/" rel="noopener noreferrer"&gt;Tapadoo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When should we use WASM?
&lt;/h2&gt;

&lt;p&gt;Whenever we need to do the heavy computation, we should use wasm as they are efficient and fast. &lt;/p&gt;

&lt;h2&gt;
  
  
  But why Rust?
&lt;/h2&gt;

&lt;p&gt;You can choose any language that you wish to, but &lt;a href="https://rustwasm.github.io/docs/book/why-rust-and-webassembly.html" rel="noopener noreferrer"&gt;Rust&lt;/a&gt; provides low-level control over the memory and is free from non-deterministic garbage collection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's create our Fibonacci wasm package
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Creating/ Initializing our first lib
&lt;/h3&gt;

&lt;p&gt;Make sure rust is installed. You can install it from &lt;a href="https://www.rust-lang.org/tools/install" rel="noopener noreferrer"&gt;here&lt;/a&gt; if not installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$  cargo new fibonacci-wasm --lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Writing our Fibonacci function in Rust
&lt;/h3&gt;

&lt;p&gt;It's pretty easy to write a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn fibonacci(n: i64) -&amp;gt; i64 {
    if n == 0 {
        return 0;
    } else if n == 1 {
        return 1;
    } else {
        let mut a = 0;
        let mut b = 1;
        for _i in 2..n {
            let c = a + b;
            a = b;
            b = c;
        }
        return b;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apart from this, you can do whatever you can do in the browser like consoling, alerting etc.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can use the &lt;a href="https://rustwasm.github.io/wasm-bindgen/api/web_sys/" rel="noopener noreferrer"&gt;web_sys&lt;/a&gt; which provides the web browser APIs in the Rust code. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;web_sys&lt;/strong&gt; is a part of &lt;strong&gt;wasm-bindgen&lt;/strong&gt; which extends the functionality that you can do with the Rust code. &lt;/li&gt;
&lt;li&gt;For JS bindings you can use the &lt;a href="https://docs.rs/js-sys/0.3.60/js_sys/" rel="noopener noreferrer"&gt;js_sys&lt;/a&gt; which provides binding to JavaScript’s standard, built-in objects, including their methods and properties&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use the &lt;a href="https://rustwasm.github.io/wasm-bindgen/api/web_sys/" rel="noopener noreferrer"&gt;web_sys&lt;/a&gt; and &lt;a href="https://docs.rs/js-sys/0.3.60/js_sys/" rel="noopener noreferrer"&gt;js_sys&lt;/a&gt; to do whatever you thought of doing in the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Let's create JS binding with our Rust code
&lt;/h3&gt;

&lt;p&gt;It is a difficult part but we have crate/library to do this. &lt;/p&gt;

&lt;p&gt;We will be using it to  Facilitate high-level interactions between Wasm modules and JavaScript.&lt;/p&gt;

&lt;p&gt;Binding our rust code with js is simple with the help of the &lt;strong&gt;wasm_bindgen&lt;/strong&gt; macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn fibonacci(n: i64) -&amp;gt; i64 {
    ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of the things are done. &lt;/p&gt;

&lt;h3&gt;
  
  
  4. Let's compile and generate wasm package with wasm-pack
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;wasm-pack&lt;/strong&gt; -&amp;gt; one-stop solution for working with rust-generated wasm code with the javascript.&lt;/p&gt;

&lt;p&gt;YOu can use the &lt;strong&gt;wasm-pack&lt;/strong&gt; to easily publish to &lt;strong&gt;npm registry&lt;/strong&gt; or use it inside in &lt;strong&gt;node_modules&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;You can install wasm-pack &lt;a href="https://rustwasm.github.io/wasm-pack/installer/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wasm-pack build --target web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can find a new folder created with the name &lt;strong&gt;pkg&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can just import WebAssembly modules the same way you would import JavaScript modules. &lt;/p&gt;

&lt;h3&gt;
  
  
  5. Testing our package in the browser
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create a basic Html page and in the body, section adds the &lt;strong&gt;script tag&lt;/strong&gt; with type &lt;strong&gt;module&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script type="module"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Importing the wasm package.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;script type="module"&amp;gt;
    import init, { fibonacci } from "./pkg/fibonacci_wasm.js";
    ....
    &amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Initializing our wasm code&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script type="module"&amp;gt;
  import init, { fibonacci } from "./pkg/fibonacci_wasm.js";

  await init();
  ....
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Running our Fibonacci function&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script type="module"&amp;gt;
  import init, { fibonacci } from "./pkg/fibonacci_wasm.js";

  await init();
  console.log(fibonacci(10));
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=zq4s3LAUz4A" rel="noopener noreferrer"&gt;iJS 2021: WebAssembly, Rust, and TypeScript – a Match Made in Heaven&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feel free to ask queries and make pull requests for changes and suggestions in GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/fibonacci_wasm" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy Hacking&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Rustaceans!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>webassembly</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Server-Sent Events in Rust</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Sun, 01 Jan 2023 08:36:21 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/server-sent-events-in-rust-3lk0</link>
      <guid>https://dev.to/chaudharypraveen98/server-sent-events-in-rust-3lk0</guid>
      <description>&lt;h2&gt;
  
  
  What is a Server-Sent Events?
&lt;/h2&gt;

&lt;p&gt;It is a standard that enables the servers to send a stream of events to the subscribed clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need SSE?
&lt;/h2&gt;

&lt;p&gt;SSE helps to get real-time data from the server. Web sockets can do the same but they are bidirectional and the client can also send the data to the server. &lt;/p&gt;

&lt;p&gt;They can be overkill for the applications which need to send updates to the clients only. So we need SSE for that purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some of the Uses Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Twitter feeds&lt;/li&gt;
&lt;li&gt;Score Updates&lt;/li&gt;
&lt;li&gt;Stocks rates&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does SSE works?
&lt;/h2&gt;

&lt;p&gt;When a client requests, it forms an EventSource Object with the url of the server endpoint over the regular HTTP request. &lt;/p&gt;

&lt;p&gt;The server responds back with an event stream and keeps the connection until it feels that it has no events to send (or stable) or the client explicitly close the connection.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  How to implement SSE with actix-web?
&lt;/h2&gt;

&lt;p&gt;Let's follow the easy steps:-&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Libraries required:-&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;actix-web&lt;/a&gt;:- A powerful, pragmatic, and extremely fast web framework for Rust&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/actix-web-lab" rel="noopener noreferrer"&gt;actix-web-lab&lt;/a&gt;:- Experimental extractors, middleware, and other extras for possible inclusion in Actix Web.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Setting Up Actix-web
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Initializing the Rust Project
&lt;/h4&gt;

&lt;p&gt;Start a new project with the following &lt;code&gt;cargo new &amp;lt;file-name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementing basic actix server
&lt;/h4&gt;

&lt;p&gt;Let's clone the sample code from &lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;actix official docs&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Add dependency in cargo.toml
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;....
[dependencies]
actix-web = "4"
#sse
actix-web-lab = "0.18.5"
parking_lot = "0.12.1"
futures-util = { version = "0.3.25", default-features = false, features = ["std"] }
....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Let's write code for actix server.
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use actix_web::{web, App, HttpServer};

#[actix_web::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    HttpServer::new(|| {
        App::new()
            .route("/hello", web::get().to(|| async { "Hello World!" }))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Implementing SSE using actix-web-lab
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Broadcaster&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Initialise the client struct&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Debug, Clone, Default)]
struct BroadcasterInner {
    clients: Vec&amp;lt;sse::Sender&amp;gt;,
}
&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;
&lt;li&gt;The Debug trait is used for printing or debugging&lt;/li&gt;
&lt;li&gt;The Clone trait let you clone the BroadcasterInner/ clients&lt;/li&gt;
&lt;li&gt;Default trait lets you assign default value on initialisation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Initialise the Broadcaster struct&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    pub struct Broadcaster {
        inner: Mutex&amp;lt;BroadcasterInner&amp;gt;,
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have used the Mutex to mutate the value safely across the threads.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Creating methods to implement ping, create a new instance, remove stale client, create new client, and broadcast message.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create a new broadcaster instance&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl Broadcaster {
    ....
    pub fn create() -&amp;gt; Arc&amp;lt;Self&amp;gt; {
        let this = Arc::new(Broadcaster {
            inner: Mutex::new(BroadcasterInner::default()),
        });
        Broadcaster::spawn_ping(Arc::clone(&amp;amp;this));
        this
    }
    ....
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This method will create a broadcaster instance which will ping the clients.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ping client&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn spawn_ping(this: Arc&amp;lt;Self&amp;gt;) {
    actix_web::rt::spawn(async move {
        let mut interval = interval(Duration::from_secs(10));

        loop {
            interval.tick().await;
            this.remove_stale_clients().await;
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This ping method is used to know the active clients and remove the stable ones. You can modify the logic as per your requirement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove stale clients&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async fn remove_stale_clients(&amp;amp;self) {
    let clients = self.inner.lock().clients.clone();
    println!("active client {:?}",clients);

    let mut ok_clients = Vec::new();

    println!("okay active client {:?}",ok_clients);

    for client in clients {
        if client
            .send(sse::Event::Comment("ping".into()))
            .await
            .is_ok()
        {
            ok_clients.push(client.clone());
        }
    }

    self.inner.lock().clients = ok_clients;
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This method will revalidate the client list and removes stale one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new client&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn new_client(&amp;amp;self) -&amp;gt; Sse&amp;lt;ChannelStream&amp;gt; {
    println!("starting creation");
    let (tx, rx) = sse::channel(10);

    tx.send(sse::Data::new("connected")).await.unwrap();
    println!("creating new clients success {:?}",tx);
    self.inner.lock().clients.push(tx);
    rx
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;sse::channel will create sender and receiver pair. The channel will take a buffer parameter which is the count of unsend messages stored without waiting.&lt;/p&gt;

&lt;p&gt;The first part -&amp;gt; sender can be cloned and shared across threads.&lt;/p&gt;

&lt;p&gt;The second part -&amp;gt; receiver is the regular event stream.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Broadcast new message&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn broadcast(&amp;amp;self, msg: &amp;amp;str) {
    let clients = self.inner.lock().clients.clone();

    let send_futures = clients
        .iter()
        .map(|client| client.send(sse::Data::new(msg)));

    // try to send to all clients, ignoring failures
    // disconnected clients will get swept up by `remove_stale_clients`
    let _ = future::join_all(send_futures).await;
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;It will broadcast messages to the active clients.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Complete Broadcaster&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use std::{sync::Arc, time::Duration};
use actix_web::rt::time::interval;
use actix_web_lab::sse::{self, ChannelStream, Sse};
use futures_util::future;
use parking_lot::Mutex;

pub struct Broadcaster {
    inner: Mutex&amp;lt;BroadcasterInner&amp;gt;,
}

#[derive(Debug, Clone, Default)]
struct BroadcasterInner {
    clients: Vec&amp;lt;sse::Sender&amp;gt;,
}

impl Broadcaster {
    /// Constructs new broadcaster and spawns ping loop.
    pub fn create() -&amp;gt; Arc&amp;lt;Self&amp;gt; {
        let this = Arc::new(Broadcaster {
            inner: Mutex::new(BroadcasterInner::default()),
        });
        Broadcaster::spawn_ping(Arc::clone(&amp;amp;this));
        // println!("created success");

        this
    }

    /// Pings clients every 10 seconds to see if they are alive and remove them from the broadcast list if not.
    fn spawn_ping(this: Arc&amp;lt;Self&amp;gt;) {
        actix_web::rt::spawn(async move {
            let mut interval = interval(Duration::from_secs(10));

            loop {
                interval.tick().await;
                this.remove_stale_clients().await;
            }
        });
    }

    /// Removes all non-responsive clients from broadcast list.
    async fn remove_stale_clients(&amp;amp;self) {
        let clients = self.inner.lock().clients.clone();
        println!("active client {:?}",clients);

        let mut ok_clients = Vec::new();

        println!("okay active client {:?}",ok_clients);

        for client in clients {
            if client
                .send(sse::Event::Comment("ping".into()))
                .await
                .is_ok()
            {
                ok_clients.push(client.clone());
            }
        }

        self.inner.lock().clients = ok_clients;
    }

    /// Registers client with broadcaster, returning an SSE response body.
    pub async fn new_client(&amp;amp;self) -&amp;gt; Sse&amp;lt;ChannelStream&amp;gt; {
        println!("starting creation");
        let (tx, rx) = sse::channel(10);

        tx.send(sse::Data::new("connected")).await.unwrap();
        println!("creating new clients success {:?}",tx);
        self.inner.lock().clients.push(tx);
        rx
    }

    /// Broadcasts `msg` to all clients.
    pub async fn broadcast(&amp;amp;self, msg: &amp;amp;str) {
        let clients = self.inner.lock().clients.clone();

        let send_futures = clients
            .iter()
            .map(|client| client.send(sse::Data::new(msg)));

        // try to send to all clients, ignoring failures
        // disconnected clients will get swept up by `remove_stale_clients`
        let _ = future::join_all(send_futures).await;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Creating a route for the sse stream and broadcast message&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[actix_web::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    let broadcaster = Broadcaster::create();

    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(AppState {
                broadcaster: Arc::clone(&amp;amp;broadcaster)
            }))
            // This route is used to listen events/ sse events
            .route("/events{_:/?}", web::get().to(sse_client))
            // This route will create notification
            .route("/events/{msg}", web::get().to(broadcast_msg))
    })
    .bind(format!("{}:{}","127.0.0.1", "8000"))?
    .run()
    .await
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Let's implement the sse_client and broadcast_msg&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;sse_client&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn sse_client(state: web::Data&amp;lt;AppState&amp;gt;) -&amp;gt; impl Responder {
    state.broadcaster.new_client().await
}

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

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;broadcast_msg&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn broadcast_msg(
    state: web::Data&amp;lt;AppState&amp;gt;,
    Path((msg,)): Path&amp;lt;(String,)&amp;gt;,
) -&amp;gt; impl Responder {
    state.broadcaster.broadcast(&amp;amp;msg).await;
    HttpResponse::Ok().body("msg sent")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Complete &lt;a href="//./src/main.rs"&gt;main.rs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use actix_web::HttpResponse;
use actix_web::Responder;
use actix_web::{web, App, HttpServer};
mod broadcast;
use self::broadcast::Broadcaster;
use std::{io, sync::Arc};
use actix_web_lab::extract::Path;

pub struct  AppState{
    broadcaster:Arc&amp;lt;Broadcaster&amp;gt;
}

// SSE
pub async fn sse_client(state: web::Data&amp;lt;AppState&amp;gt;) -&amp;gt; impl Responder {
    state.broadcaster.new_client().await
}

pub async fn broadcast_msg(
    state: web::Data&amp;lt;AppState&amp;gt;,
    Path((msg,)): Path&amp;lt;(String,)&amp;gt;,
) -&amp;gt; impl Responder {
    state.broadcaster.broadcast(&amp;amp;msg).await;
    HttpResponse::Ok().body("msg sent")
}

#[actix_web::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    let broadcaster = Broadcaster::create();

    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(AppState {
                broadcaster: Arc::clone(&amp;amp;broadcaster)
            }))
            // This route is used to listen to events/ sse events
            .route("/events{_:/?}", web::get().to(sse_client))
            // This route will create a notification
            .route("/events/{msg}", web::get().to(broadcast_msg))
    })
    .bind(format!("{}:{}","127.0.0.1", "8000"))?
    .run()
    .await
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Testing the SSE&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the /events to subscribe to the event stream&lt;/li&gt;
&lt;li&gt;Then hit the /events/ to send a message to the clients.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;Hurray! we have finally implemented the Server-Sent Events.&lt;/p&gt;

&lt;p&gt;Feel free to ask queries and make pull request for changes and suggestion in GitHub.&lt;/p&gt;

&lt;p&gt;Source Code &lt;a href="https://github.com/chaudharypraveen98/actix-sse-example" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy Hacking&lt;br&gt;
Rustaceans!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>actixweb</category>
      <category>sse</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Rust Generics</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Sun, 09 Oct 2022 11:44:57 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/rust-generics-c11</link>
      <guid>https://dev.to/chaudharypraveen98/rust-generics-c11</guid>
      <description>&lt;p&gt;It is a way of writing generalised algorithms in such a way that can be used for the types specified later. It can be initialised for a specified type with help of parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we use generics:-
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Abstract Types:&lt;/strong&gt; Instead of writing explicit type like i32 or float we can use the generics for different types by writing different code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adds Flexibility:&lt;/strong&gt; We can use different data types with the same piece of code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduces Code Duplication:&lt;/strong&gt; We can have the same piece of code or both for any two types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Runtime Cost:&lt;/strong&gt; Unlike Object Traits, generics don't have runtime costs. The compiler generates the different types in the background during compile time.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;h2&gt;
  
  
  Let's get started
&lt;/h2&gt;

&lt;p&gt;Usually the &lt;strong&gt;generics type parameter&lt;/strong&gt; is represented by &lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt;. But you are free to use any.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structs
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Single placeholder type
&lt;/h4&gt;

&lt;p&gt;Defining the struct with the  placeholder/generic type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Point&amp;lt;T&amp;gt; {
    x: T,
    y: T,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's try to use this for i32&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
    let i32_point = Point { x: 45, y: 90 };
    println!("x is {} and y is {}", i32_point.x, i32_point.y);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you hover on the &lt;strong&gt;i32_point&lt;/strong&gt; then you can find the type of variable is Point i32 i32. But it is not limited. You can even use the float for both x and y but they must be the same.&lt;/p&gt;

&lt;p&gt;So how can we use the different types for the two fields x and y?&lt;/p&gt;

&lt;p&gt;It can be done using the two placeholder&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Two placeholder
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;struct definition&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct TwoPoint&amp;lt;T, U&amp;gt; {
    x: T,
    y: U,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;let's test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
    let explicit_point = TwoPoint { x: 9, y: 90.3 };
    println!(
        "explicit_point x is {} and y is {}",
        explicit_point.x, explicit_point.y
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly we can two different data types for the x and y, even vectors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enums
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Generics with Enum
&lt;/h4&gt;

&lt;p&gt;creating a result enum that will store the result whether pass, fail, or awaiting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Debug)]
enum Result&amp;lt;T&amp;gt; {
    Passed(T),
    Failed(T),
    Pending,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Used the &lt;code&gt;Debug&lt;/code&gt; trait because the enum is not primitive because all the primitives include the debug capabilities/trait. &lt;/p&gt;

&lt;p&gt;Testing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
  let result = Result::Passed(43);
  match result {
      Result::Passed(a) =&amp;gt; println!("Student Passed with {}", a),
      Result::Failed(b) =&amp;gt; println!("Student Failed with {}", b),
      Result::Pending =&amp;gt; println!("Student result is pending"),
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use different generics types for Passed and Failed as shown in the above case.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Using struct and enums together with generics
&lt;/h4&gt;

&lt;p&gt;we are using the Result enum from the above example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Student&amp;lt;T&amp;gt; {
    name: String,
    roll_no: T,
    result: Result&amp;lt;T&amp;gt;,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's use it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
  let student = Student {
      name: "Praveen".to_string(),
      roll_no: 78,
      result: Result::Passed(98),
  };

  match student.result {
      Result::Passed(a) =&amp;gt; println!("Student Passed with {}", a),
      Result::Failed(b) =&amp;gt; println!("Student Failed with {}", b),
      Result::Pending =&amp;gt; println!("Student result is pending"),
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Functions with Generics
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Function with single generic type parameter and single trait
&lt;/h4&gt;

&lt;p&gt;function definition&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn custom_add&amp;lt;T: std::ops::Add&amp;lt;Output = T&amp;gt;&amp;gt;(a: T, b: T) -&amp;gt; T {
    a + b
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;strong&gt;Output=T&lt;/strong&gt; ensures that after the &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt; result must be the same. It can be different if you wish too like the addition of two atoms can result in the molecule(&lt;code&gt;T+T=U&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let a = 4;
let b = 5;
println!("sum of {} and {} is {}", a, b, custom_add(a, b));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Function with single generic type parameter and multiple traits
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn custom_add_sub&amp;lt;T: std::ops::Add&amp;lt;Output = T&amp;gt; + std::ops::Sub&amp;lt;Output = T&amp;gt; + std::fmt::Debug&amp;gt;(
    a: T,
    b: T,
) -&amp;gt; T {
    // Debug trait is needed for this print statement
    println!("{:?} {:?}", a, b);
    a + b
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
  println!("sub of {} and {} is {}", a, b, custom_add_sub(a, b));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I know it's easy for you now&lt;/p&gt;

&lt;h4&gt;
  
  
  3.Function with multiple generic type parameters and multiple traits and where keyword
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// using the where to define a generic type
fn custom_add_sub_mul&amp;lt;T, E&amp;gt;(a: T, b: T, c: E) -&amp;gt; T
where
    T: std::ops::Mul&amp;lt;Output = T&amp;gt; + std::ops::Add&amp;lt;Output = T&amp;gt; + std::ops::Sub&amp;lt;Output = T&amp;gt;,
    E: std::fmt::Debug,
{
    println!("{:?}", c);
    a * b
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;where&lt;/code&gt; keyword makes our code clearer. It doesn't have any impact on how the code run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
  println!("mul of {} and {} is {}", a, b, custom_add_sub_mul(a, b, b));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Functions with custom trait
&lt;/h4&gt;

&lt;p&gt;Instead of using the predefined trait, we can use the custom trait as we like to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trait SomeCustomTrait {
    fn bla_bla(&amp;amp;self, a: &amp;amp;str, b: &amp;amp;str) -&amp;gt; String;
}
#[derive(Debug)]
struct TestStruct {
    something: i32,
}

impl SomeCustomTrait for TestStruct {
    fn bla_bla(&amp;amp;self, a: &amp;amp;str, b: &amp;amp;str) -&amp;gt; String {
        self.something.to_string() + "-" + a + "-" + b
    }
}

fn do_this&amp;lt;T&amp;gt;(some_var: &amp;amp;T) -&amp;gt; String
where
    T: SomeCustomTrait + std::fmt::Debug,
{
    println!("{:?}", some_var);
    some_var.bla_bla("first", "second")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the function, we have used our &lt;code&gt;SomeCustomTrait&lt;/code&gt; along with the Debug. We can even add more.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
  let test = TestStruct { something: 1000 };
  let result = do_this(&amp;amp;test);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Impl with Generics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ImplStruct&amp;lt;T, U&amp;gt; {
    field1: T,
    field2: U,
}

impl&amp;lt;T, U&amp;gt; ImplStruct&amp;lt;T, U&amp;gt;
where
    T: std::fmt::Debug,
    U: std::fmt::Debug,
{
    fn log_something(&amp;amp;self) {
        println!("{:?} {:?}", self.field1, self.field2);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can notice here the generics type is defined at the &lt;code&gt;impl block&lt;/code&gt; instead of a struct but you can define it at both blocks but Impl block is a must.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
  let impl_test = ImplStruct{
      field1:5.6,
      field2:vec![1,2,3],
  };
  impl_test.log_something();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we have covered the basics of Rust Generics but you can do a  lot more with Generics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://doc.rust-lang.org/rust-by-example/generics.html" rel="noopener noreferrer"&gt;rust-lang by example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=nvur2Ast8hE" rel="noopener noreferrer"&gt;Doug Milford&lt;/a&gt;
&lt;strong&gt;Source code&lt;/strong&gt;
&lt;a href="https://github.com/chaudharypraveen98/RustyRustLessons/" rel="noopener noreferrer"&gt;RustyRustLessons Generics&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Happy Hacking&lt;/strong&gt;&lt;br&gt;
Rustaceans!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>generics</category>
      <category>abstractprogramming</category>
    </item>
    <item>
      <title>React Native Push Notification - Firebase</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Sun, 18 Sep 2022 16:32:40 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/react-native-push-notification-firebase-1aah</link>
      <guid>https://dev.to/chaudharypraveen98/react-native-push-notification-firebase-1aah</guid>
      <description>&lt;p&gt;Notifications play an important role in targeting the right users at the right time. It helps in the following ways:-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increasing App Engagement&lt;/li&gt;
&lt;li&gt;Targeting the right user&lt;/li&gt;
&lt;li&gt;Enhancing the conversion rate&lt;/li&gt;
&lt;li&gt;Engaging user retention for a period of time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Libraries used: -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Firebase Cloud Messaging&lt;/strong&gt;: It is a cross-platform messaging solution that lets you reliably send messages at no cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React Native MMKV (Optional)&lt;/strong&gt;: A library that allows you to easily use MMKV inside your React Native applications. We will need this if we want to store FCM token locally in a fast manner.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What we are going to do?
&lt;/h2&gt;

&lt;p&gt;Let's divide the workflow in easy steps:-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setting up React Native project.&lt;/li&gt;
&lt;li&gt;Installing &lt;strong&gt;Firebase&lt;/strong&gt; libraries needed for FCM Token generation and notification.&lt;/li&gt;
&lt;li&gt;Integrating &lt;strong&gt;React Native MMKV&lt;/strong&gt; for fast storage. (Optional)&lt;/li&gt;
&lt;li&gt;Generating FCM token and storage&lt;/li&gt;
&lt;li&gt;Requesting user permission for the notification.&lt;/li&gt;
&lt;li&gt;Setting up notification Listener&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Setting up React Native project.
&lt;/h2&gt;

&lt;p&gt;React CLI will generate the template for you to get started quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initialize Project
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;npx react-native init SimpleReactNativeNotification&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you are new to React Native, then follow the &lt;a href="https://reactnative.dev/docs/environment-setup" rel="noopener noreferrer"&gt;React Native Official Docs&lt;/a&gt; to setup up the environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Installing Firebase libraries needed for FCM Token generation and notification.
&lt;/h2&gt;

&lt;p&gt;Firebase libraries provide various method to support the firestore, real-time database firebase, Cloud messaging, and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing the React Native Firebase library
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Using npm
npm install --save @react-native-firebase/app

# Using Yarn
yarn add @react-native-firebase/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional steps for setup in Android and IOS
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Android
Visit &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;Firebase console&lt;/a&gt; and start a new project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add a new Android application and enter your project details. &lt;br&gt;
   &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/readme_assets%2Fstart_android_app.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/readme_assets%2Fstart_android_app.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download the &lt;strong&gt;google-services.json&lt;/strong&gt; file and place it inside your project at the following location: &lt;code&gt;/android/app/google-services.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rnfirebase.io/#generating-android-credentials" rel="noopener noreferrer"&gt;For more info&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I don't have a mac device💻. So you can follow &lt;a href="https://rnfirebase.io/#3-ios-setup" rel="noopener noreferrer"&gt;here&lt;/a&gt; 😟&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Adding Firebase messaging libraries along with above parent library
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Install the messaging module

yarn add @react-native-firebase/messaging

or 

npm install --save @react-native-firebase/messaging

# If you're developing your app using iOS, run this command
cd ios/ &amp;amp;&amp;amp; pod install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Integrating &lt;strong&gt;React Native MMKV&lt;/strong&gt; for fast storage. (Optional)
&lt;/h2&gt;

&lt;p&gt;We don't need to generate the FCM token every time, as it is the same most of the time. &lt;/p&gt;

&lt;p&gt;There are some exceptions, but we can handle them and reduce the number of calls to generate the token every time.&lt;/p&gt;

&lt;p&gt;Validity of FCM Token&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app deletes Instance ID&lt;/li&gt;
&lt;li&gt;The app is restored on a new device&lt;/li&gt;
&lt;li&gt;The user uninstalls/reinstalls the app&lt;/li&gt;
&lt;li&gt;The user clears app data.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Installing
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react-native-mmkv
or 
npm install --save react-native-mmkv

cd ios &amp;amp;&amp;amp; pod install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Creating instance to use throughout the app
&lt;/h3&gt;

&lt;p&gt;Create a new file 'storage.js'&lt;/p&gt;

&lt;p&gt;&lt;a href="//storage.js"&gt;storage.js&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MMKV } from 'react-native-mmkv'

export const storage = new MMKV()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hurray! Our mmkv storage is ready to use&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Generate FCM token and store it
&lt;/h2&gt;

&lt;p&gt;Let's write a function to generate the FCM token.&lt;/p&gt;

&lt;p&gt;Importing the messaging library which we installed earlier  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;import messaging from '@react-native-firebase/messaging';&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Without storage
&lt;/h3&gt;

&lt;p&gt;creating a function &lt;strong&gt;getFcmToken&lt;/strong&gt; - &lt;a href="//notifications.js"&gt;'./notifications.js'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getFcmToken = async () =&amp;gt; {
  try {
    const newFcmToken = await messaging().getToken();
    console.log(newFcmToken);
    return newFcmToken;
  } catch (error) {
    console.error(error);
    return null;
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's make changes in &lt;a href="//App.js"&gt;App.js&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {getFcmToken} from './notifications';

const App = () =&amp;gt; {
  ....
  const [generatedToken, setGeneratedToken] = useState();

  useEffect(() =&amp;gt; {
      const fetchToken = async () =&amp;gt; {
        const token = await getFcmToken();
        if (token) {
          setGeneratedToken(token);
        }
      };
      void fetchToken();
    }, []);
  ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. With Storage
&lt;/h3&gt;

&lt;p&gt;creating a function &lt;strong&gt;getFcmTokenFromLocalStorage&lt;/strong&gt; - &lt;a href="//notifications.js"&gt;'./notifications.js'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getFcmTokenFromLocalStorage = async () =&amp;gt; {
  const fcmtoken = localStorage.getString('fcmtoken');
  if (!fcmtoken) {
    try {
      const newFcmToken = await messaging().getToken();
      localStorage.set('fcmtoken', newFcmToken);
    } catch (error) {
      console.error(error);
    }
  } else {
    console.log('token found', fcmtoken);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's make changes in &lt;a href="//App.js"&gt;App.js&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {getFcmToken} from './notifications';

const App = () =&amp;gt; {
  ....
  const fcmToken = localStorage.getString('fcmtoken');

  useEffect(() =&amp;gt; {
      const fetchTokenByLocal = async () =&amp;gt; {
        await getFcmTokenFromLocalStorage();
      };
      void fetchTokenByLocal();
    }, []);
  ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use Hooks to see the tokens&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  console.log('storage', fcmToken, 'newly generated', generatedToken);
}, [fcmToken, generatedToken]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Requesting user permission for the notification.
&lt;/h2&gt;

&lt;p&gt;iOS prevent notification unless explicitly approved by the user.&lt;/p&gt;

&lt;p&gt;On Android, you do not need to request user permission. This method can still be called on Android devices; however, and will always resolve successfully.&lt;/p&gt;

&lt;p&gt;In Android, we don't need any special permission for notification, but this function can still be called and will resolve successfully&lt;/p&gt;

&lt;p&gt;&lt;a href="//notifications.js"&gt;'./notifications.js'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const requestUserPermission = async () =&amp;gt; {
  const authStatus = await messaging().requestPermission();
  const enabled =
    authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
    authStatus === messaging.AuthorizationStatus.PROVISIONAL;

  if (enabled) {
    console.log('Authorization status:', authStatus);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up notification Listener
&lt;/h2&gt;

&lt;p&gt;We can listen for real-time FCM messages on any device.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foreground&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When the application is open and in view.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When the application is open, however, in the background (minimized). This typically occurs when the user has pressed the "home" button on the device or has switched to another app via the app switcher.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Quit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When the device is locked or the application is not active or running. The user can quit an app by "swiping it away" via the app switcher UI on the device.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can read more about &lt;a href="https://rnfirebase.io/messaging/usage#message-handlers" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's Handle these three cases: -&lt;/p&gt;

&lt;p&gt;&lt;a href="//notifications.js"&gt;'./notifications.js'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const notificationListener = () =&amp;gt; {

  messaging().onNotificationOpenedApp(remoteMessage =&amp;gt; {
    console.log(
      'Notification caused app to open from background state:',
      remoteMessage.notification,
    );
  });

  // Quiet and Background State -&amp;gt; Check whether an initial notification is available
  messaging()
    .getInitialNotification()
    .then(remoteMessage =&amp;gt; {
      if (remoteMessage) {
        console.log(
          'Notification caused app to open from quit state:',
          remoteMessage.notification,
        );
      }
    })
    .catch(error =&amp;gt; console.log('failed', error));

  // Foreground State
  messaging().onMessage(async remoteMessage =&amp;gt; {
    console.log('foreground', remoteMessage);
  });
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For handling the Background notification, we need to add a handler at the &lt;a href="//index.js"&gt;'./index.js'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import messaging from '@react-native-firebase/messaging';

// Register background handler
messaging().setBackgroundMessageHandler(async remoteMessage =&amp;gt; {
  console.log('Message handled in the background!', remoteMessage);
});

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Testing
&lt;/h2&gt;

&lt;p&gt;First, grab the token from the terminal generated by console.log.&lt;/p&gt;

&lt;p&gt;Visit &lt;a href="https://testfcm.com/" rel="noopener noreferrer"&gt;TestFcm.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need the server keys to test. We can get this from the firebase console. &lt;/p&gt;

&lt;p&gt;Open the project and get the server key by following the below steps:-&lt;/p&gt;

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

&lt;p&gt;If your cloud messaging API is not enabled then &lt;/p&gt;

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

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Foreground Notification
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Background and Quiet Notification
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyym203qubmehcwx094ra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyym203qubmehcwx094ra.png" alt="Background and Quiet Notification" width="428" height="926"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/chaudharypraveen98/Simple-React-Native-Push-Notification" rel="noopener noreferrer"&gt;Simple-React-Native-Push-Notification&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources: -&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Qcxa6dxfUFo" rel="noopener noreferrer"&gt;Push Notification In React Native Using Firebase - Android &amp;amp; IOS Tutorial 2022&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rnfirebase.io/" rel="noopener noreferrer"&gt;React Native Firebase Official Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For any question, feel free to ask your doubts and open pull request for any changes or suggestion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thank you,&lt;/strong&gt;&lt;br&gt;
Happy Hacking&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>ios</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Rust - Interior mutability - Cell</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Thu, 18 Aug 2022 16:20:00 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/rust-interior-mutability-cell-1fl1</link>
      <guid>https://dev.to/chaudharypraveen98/rust-interior-mutability-cell-1fl1</guid>
      <description>&lt;p&gt;Interior mutability provides the ability to mutate the value even in case of immutable reference.&lt;/p&gt;

&lt;p&gt;There is no legal way to convert the &amp;amp;T(exclusive reference) to the &amp;amp;mut T(mutable reference) and this is called undefined behavior.&lt;br&gt;
But we have UnsafeCell which helps to cope with the immutability constraint of &amp;amp;T, and provides a shared reference &amp;amp;UnsafeCell which points to the value to be mutated called &lt;strong&gt;Interior mutability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UnsafeCell&lt;/strong&gt;&lt;br&gt;
It is the building block of interior mutability. It is used to eliminate some Rust optimizations that assume exclusive mutable access (or aliasing) inside the cell.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwfclre17dr3afsookvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwfclre17dr3afsookvu.png" alt="Shareable Mutable Reference" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://doc.rust-lang.org/std/cell/" rel="noopener noreferrer"&gt;Cell&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;It &lt;strong&gt;abstraction&lt;/strong&gt; over the &lt;strong&gt;UnsafeCell&lt;/strong&gt; (which is unsafe in nature), So it is unsafe, but taking some measures when we ensure the safety.&lt;/p&gt;

&lt;p&gt;It is not suitable for vec, String, or anything that stores data in heap memory as it is expensive to use &lt;strong&gt;Copy&lt;/strong&gt; trait.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why to use Cell?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Suppose we have a cyclic data structure, we are using the mutable reference for accessing the value. Once we reach the end, we start from the first element, then we have two mutable references to a single value. Suppose now we used the mem::swap then bad thing will happen. It is undefined behaviour to ever have multiple mutable references to a single value concurrently, no matter whether you're in a single-threaded or multi-threaded context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why to use UnsafeCell with Cell?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If we try to mutate the value directly through the shared pointer without unsafeCell then it will always result in undefined behaviour because the compiler may try to optimize based on the current assumption that the pointer isn't shared, which would be invalid if it was shared. &lt;/p&gt;

&lt;p&gt;It can be done using the UnsafeCell if you know it was truly not shared (even on the same thread), because that prevents some of those optimizations such is it safe to cache when we have &lt;code&gt;&amp;amp;self&lt;/code&gt;and when you have &lt;code&gt;&amp;amp;mut self&lt;/code&gt; it makes sure that no two &lt;code&gt;&amp;amp;mut T&lt;/code&gt; never points to same &lt;code&gt;T&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How to mutate in Rust&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Immutability&lt;/strong&gt; can be possible by &lt;code&gt;&amp;amp;T&lt;/code&gt; reference known as &lt;strong&gt;aliasing&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mutability&lt;/strong&gt; can be only possible by having &lt;code&gt;&amp;amp;mut T&lt;/code&gt; reference. This type of reference is exclusive in nature.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;So what does shareable mutable reference means?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
It means we have shared references(i.e &lt;code&gt;&amp;amp;T&lt;/code&gt; type) but with the extra power to mutate in a controlled manner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do shared references allow mutation?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Interior mutability types which uses the shared references let you do because they maintain additional, special-case invariants that the compiler cannot check, that ensure that no conflicts arise even if you modify through a shared reference. There are lots of ways to do so with the help of CPU atomics, Mutexes, Cell, RefCell, etc.&lt;/p&gt;
&lt;h4&gt;
  
  
  How to ensure that we are using it in a controlled manner?
&lt;/h4&gt;

&lt;p&gt;&lt;span&gt;&lt;strong&gt;1.&lt;/strong&gt;&lt;/span&gt; Not using &lt;strong&gt;Sync&lt;/strong&gt; trait&lt;br&gt;&lt;br&gt;
Cell &lt;strong&gt;must not implement&lt;/strong&gt; the &lt;strong&gt;Sync&lt;/strong&gt; trait as it enables the usage of sharing references across threads which can result in adverse conditions as they can try to overwrite the value at the same time which leads to corrupted results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Base code to understand the explanation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use std::cell::UnsafeCell;

pub struct Cell&amp;lt;T&amp;gt; {
    value: UnsafeCell&amp;lt;T&amp;gt;,
}

impl&amp;lt;T&amp;gt; Cell&amp;lt;T&amp;gt; {
    pub fn new(value: T) -&amp;gt; Self {
        Cell {
            value: UnsafeCell::new(value),
        }
    }

    pub fn set(&amp;amp;self, value: T) {
        unsafe { *self.value.get() = value };
    }

    pub fn get(&amp;amp;self) -&amp;gt; T
    where
        T: Copy,
    {
        unsafe { *self.value.get() }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's implement some changes in the code to understand the working.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing Sync Method for testing&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unsafe impl&amp;lt;T&amp;gt; Sync for Cell&amp;lt;T&amp;gt;{}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Writing Test Case&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[cfg(test)]
mod test {

  use super::Cell;

  #[test]
  fn bad2(){
    use std::sync::Arc;
    let x = Arc::new(Cell::new(0));
    let x1 = Arc::clone(&amp;amp;x);
    let j1 = std::thread::spawn(move || {
      for _ in 0..1000000{
        let x = x1.get();
        x1.set(x+1);
      }
    });
    let x2 = Arc::clone(&amp;amp;x);
    let j2 = std::thread::spawn(move || {
      for _ in 0..1000000{
        let x = x2.get();
        x2.set(x+1);
      }
    });
    j1.join().unwrap();
    j2.join().unwrap();
    assert_eq!(x.get(),2000000)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Arc&lt;/strong&gt; is used to share the reference between the threads.&lt;/p&gt;

&lt;p&gt;In the above code, we are spawning two threads and they are simultaneously mutating the value of x in each iteration 0 to 1000000.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Let's run test&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;running 1 test
test cell::test::bad2 ... FAILED

failures:

---- cell::test::bad2 stdout ----
thread 'cell::test::bad2' panicked at 'assertion failed: `(left == right)`
  left: `1170776`,
 right: `2000000`', src/cell.rs:96:5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why does the assertion fail?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Instead, of getting 2000000, we get only 1170776. Because one or another thread read the old value of x and incremented and set it to a new value obtained.&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;strong&gt;2.&lt;/strong&gt;&lt;/span&gt; The &lt;strong&gt;get&lt;/strong&gt; method must implement the &lt;strong&gt;Copy&lt;/strong&gt; trait which will give the cloned value, not the exclusive reference to it. If we don't use the Copy trait, then what happens?&lt;/p&gt;

&lt;p&gt;For example:- &lt;/p&gt;

&lt;p&gt;Let's try to understand by code&lt;/p&gt;

&lt;p&gt;Returning the pointer to the value inside the Cell&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn get(&amp;amp;self)-&amp;gt;&amp;amp;T{
  unsafe {&amp;amp;*self.value.get()}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's write some test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[test]
fn bad1() {
  let x = Cell::new(true);
  let y = x.get();
  x.set(false);
  eprintln!("{}",y);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have something in Cell and let it assign to a variable x then store the reference to y by making some change in &lt;strong&gt;get&lt;/strong&gt; method. Then we try to change the value by &lt;strong&gt;set&lt;/strong&gt; method. &lt;/p&gt;

&lt;p&gt;Now, if we try to access the y. It should fail because once we set a new value, then the previous memory must be released.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⇒&lt;/strong&gt; If the test doesn't fail, it might be because the system might not free the memory instantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Always use Cell when you have an immutable struct with numerous fields, and you want to change only 1-2 two fields.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It can be used for setting a flag in a single thread to know the status of something.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Special shoutout to &lt;a href="https://www.youtube.com/watch?v=8O0Nt9qY_vo" rel="noopener noreferrer"&gt;Jon Gjengset&lt;br&gt;
&lt;/a&gt;. It inspires me to write simple cron scheduler.&lt;/p&gt;

&lt;p&gt;Reference taken:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=8O0Nt9qY_vo" rel="noopener noreferrer"&gt;Jon Gjengset
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.rust-lang.org/std/cell/" rel="noopener noreferrer"&gt;Rust Org&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feel free to ask queries. You can connect to me on [LinkedIn].(&lt;a href="https://www.linkedin.com/in/chaudharypraveen98/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/chaudharypraveen98/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Hacking&lt;/strong&gt;&lt;br&gt;
Rustaceans!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>mutability</category>
      <category>cell</category>
      <category>mutex</category>
    </item>
    <item>
      <title>Scheduling Async Tasks made easy with Actix Cron.</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Sun, 24 Jul 2022 09:52:35 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/scheduling-async-tasks-made-easy-with-actix-cron-1omi</link>
      <guid>https://dev.to/chaudharypraveen98/scheduling-async-tasks-made-easy-with-actix-cron-1omi</guid>
      <description>&lt;p&gt;Cron is simply a scheduling daemon that executes the task at a specified interval. We usually use cron for backing up the data, report generation, synchronizing setting in background etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What will we learn : -&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setting Up Actix-web.&lt;/li&gt;
&lt;li&gt;Adding duration for periodic tasks.&lt;/li&gt;
&lt;li&gt;Adding cron parser for scheduling flexibility.&lt;/li&gt;
&lt;li&gt;Performing DB operations using cronjobs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Libraries required :-&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;actix-web&lt;/a&gt; :- A powerful, pragmatic, and extremely fast web framework for Rust&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/reqwest" rel="noopener noreferrer"&gt;reqwest&lt;/a&gt; :- higher level HTTP client library&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/actix-rt" rel="noopener noreferrer"&gt;actix-rt&lt;/a&gt; :- Tokio-based single-threaded async runtime for the Actix ecosystem&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/cron" rel="noopener noreferrer"&gt;cron&lt;/a&gt; :- A cron expression parser and schedule explorer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/chrono" rel="noopener noreferrer"&gt;chrono&lt;/a&gt; :- Date and time library for Rust&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Setting Up Actix-web
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initializing the Rust Project
&lt;/h3&gt;

&lt;p&gt;Start a new project with following &lt;code&gt;cargo new &amp;lt;file-name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing basic actix server
&lt;/h3&gt;

&lt;p&gt;Let's clone the sample code from &lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;actix official docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add dependency in cargo.toml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;....
[dependencies]
actix-web = "4"
....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's write code for actix server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use actix_web::{web, App, HttpServer};

#[actix_web::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    HttpServer::new(|| {
        App::new()
            .route("/hello", web::get().to(|| async { "Hello World!" }))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Adding duration for periodic tasks.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use std::{collections::HashMap, time::Duration};
use reqwest;
use actix_rt::time;

// async function to get data from url using reqwest library

async fn get_ips() -&amp;gt; HashMap&amp;lt;String, String&amp;gt; {
    let resp = reqwest::get("https://httpbin.org/ip")
        .await.unwrap()
        .json::&amp;lt;HashMap&amp;lt;String, String&amp;gt;&amp;gt;()
        .await.unwrap();
    resp
}

async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {

  actix_rt::spawn(async {
      let mut interval = time::interval(Duration::from_secs(20));
      loop {
          interval.tick().await;
          let result = get_ips().await;
          println!("20 sec {:?}",result);
      }
  });
  ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Confused??
&lt;/h3&gt;

&lt;p&gt;No, need to get confused. Let's try to understand step by step code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;actix_rt ()&lt;/strong&gt;&lt;br&gt;
It is a tokio-based single threaded async runtime for actix system. &lt;/p&gt;

&lt;p&gt;Single threaded means only one command get executed at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;actix_rt::spawn&lt;/strong&gt; : Spawns a future on the current thread as a new task. If not immediately awaited, the task can be cancelled using JoinHandle::abort (it detaches the current thread when dropped).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;actix_rt::spawn(async move {})&lt;/strong&gt; :  move will let you capture closure's environment variable.&lt;/p&gt;

&lt;p&gt;Closures are simple anonymous function &lt;br&gt;
that can be store in variable and doesn't require you to annotate the types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tokio time::interval&lt;/strong&gt; : Creates new Interval that yields with interval of duration. The first tick completes immediately.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;interval.tick()&lt;/strong&gt; : Completes when the next instant in the interval has been reached.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Duration::from_secs(20)&lt;/strong&gt; : Creates a new Duration with the input whole number in seconds.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Adding cron parser for scheduling flexibility.
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use std::{collections::HashMap, time::Duration, str::FromStr};
use chrono::{Local, FixedOffset};
use cron::Schedule;
use reqwest;
use actix_rt::{self, time};

use actix_web::{web, App, HttpServer};

async fn get_ips() -&amp;gt; HashMap&amp;lt;String, String&amp;gt; {
    let resp = reqwest::get("https://httpbin.org/ip")
        .await.unwrap()
        .json::&amp;lt;HashMap&amp;lt;String, String&amp;gt;&amp;gt;()
        .await.unwrap();
    resp
}

#[actix_web::main] // or #[tokio::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    actix_rt::spawn(async move {
        let expression = "1/50   *   *     *       *  *  *";
        let schedule = Schedule::from_str(expression).unwrap();
        let offset = Some(FixedOffset::east(0)).unwrap();

        loop {
            let mut upcoming = schedule.upcoming(offset).take(1);
            actix_rt::time::sleep(Duration::from_millis(500)).await;
            let local = &amp;amp;Local::now();

            if let Some(datetime) = upcoming.next() {
                if datetime.timestamp() &amp;lt;= local.timestamp() {

                    let result = get_ips().await;
                    println!("{:?}",result);
                }
            }
        }
    });
    HttpServer::new(|| {
        App::new()
            .route("/hello", web::get().to(|| async { "Hello World!" }))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's try to understand what new happening here&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cron expression&lt;/strong&gt; :  do follow the cron pattern. If you want to learn more about it, &lt;a href="https://crontab.guru/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//                  sec  min   hour   day of month   month   day of week   year
  let expression = "0   30   9,12,15     1,15       May-Aug  Mon,Wed,Fri  2018/2";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Schedule::from_str&lt;/strong&gt; : IT will parse the value from string.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FixedOffset&lt;/strong&gt; : The fixed offset is used to create the date instance. Positive secs mean the Northern Hemisphere and negative secs means the Western Hemisphere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;schedule.upcoming(offset).take(1)&lt;/strong&gt; : upcoming will take the offset instance and returns an iterator of the DateTime object which matches the schedule.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;take&lt;/strong&gt; : it returns the first item in iterator.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;thread::sleep&lt;/strong&gt; : it is necessary to sleep before we check conditions because checking condition at every millisecond is not ideal as our use case is in seconds or greater than that. If you want minute milliseconds control over cron you can try lower time too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local::now()&lt;/strong&gt; : It will return the current date time depending on local timezone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;if let Some(datetime) = upcoming.next() {if datetime.timestamp() &amp;lt;= local.timestamp() {} }&lt;/strong&gt; : If we find a datetime object in iterator and local date time(current) is &amp;gt;= the iterator one then it will run the function.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Performing DB operations using cronjobs.
&lt;/h2&gt;

&lt;p&gt;It's pretty similar, just like above two. I will try to give you the glimpse and the example code to understand by your self. &lt;/p&gt;

&lt;p&gt;We will use the clousure(move) over the function to get the DB pool and logger.&lt;/p&gt;

&lt;p&gt;Please find the code here, &lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/main.rs#L74:L96" rel="noopener noreferrer"&gt;actix-question-bank-stackoverflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Special shoutout to &lt;a href="https://crates.io/crates/cronjob" rel="noopener noreferrer"&gt;cronjob&lt;/a&gt;. It inspires me to write simple cron scheduler.&lt;/p&gt;

&lt;p&gt;Feel free to ask queries and make pull request for changes and suggestion in GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-aysnc-cron-scheduler" rel="noopener noreferrer"&gt;Github - Source Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Hacking&lt;/strong&gt;&lt;br&gt;
Rustaceans!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>actix</category>
      <category>cron</category>
      <category>scheduler</category>
    </item>
    <item>
      <title>Form Validation in Rust (Actix-Web)</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Mon, 27 Jun 2022 16:16:36 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/form-validation-in-rust-404l</link>
      <guid>https://dev.to/chaudharypraveen98/form-validation-in-rust-404l</guid>
      <description>&lt;p&gt;Form validation is the important part of Software Development Lifecycle Process. It based on the data type define while creating a form. It basically ensures few things : -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevent form abuse from malicious users.&lt;/li&gt;
&lt;li&gt;Reduce spams.&lt;/li&gt;
&lt;li&gt;Ensure form users enter only legitimate data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tools Used : -
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;Actix-Web&lt;/a&gt; : A powerful, pragmatic, and extremely fast web framework for Rust&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Keats/validator" rel="noopener noreferrer"&gt;Validator&lt;/a&gt; : Macros 1.1 custom derive to simplify struct validation inspired by &lt;a href="http://marshmallow.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;marshmallow&lt;/a&gt; and
&lt;a href="https://docs.djangoproject.com/en/1.10/ref/validators/" rel="noopener noreferrer"&gt;Django validators&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-lang-nursery/lazy-static.rs" rel="noopener noreferrer"&gt;lazy_static&lt;/a&gt; : A macro for declaring lazily evaluated statics in Rust.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-lang/regex" rel="noopener noreferrer"&gt;regex&lt;/a&gt; : An implementation of regular expressions for Rust.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;p&gt;'./Cargo.toml'&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
actix-web = "4"
validator = { version = "0.12", features = ["derive"] }
serde = { version = "1.0.104", features = ["derive"] }
lazy_static = "1.4.0"
regex = "1.5.6"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's get Rusty
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initializing the Rust Project
&lt;/h3&gt;

&lt;p&gt;Start a new project with following &lt;code&gt;cargo new &amp;lt;file-name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing basic actix server
&lt;/h3&gt;

&lt;p&gt;Let's clone the sample code from &lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;actix official docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use actix_web::{get, web, App, HttpServer, Responder};

#[get("/hello/{name}")]
async fn greet(name: web::Path&amp;lt;String&amp;gt;) -&amp;gt; impl Responder {
    format!("Hello {name}!")
}

#[actix_web::main] // or #[tokio::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    HttpServer::new(|| {
        App::new()
            .route("/hello", web::get().to(|| async { "Hello World!" }))
            .service(greet)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating Struct to hold data
&lt;/h3&gt;

&lt;p&gt;In this project, we are creating a student model/struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub struct Student {
    pub name: String,
    pub email: String,
    pub age: u32,
    pub username: String,
    pub password: String,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementing Serde Serialize and Deserailize traits
&lt;/h3&gt;

&lt;p&gt;It will convert the json data to struct and vice versa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct Student {
    pub name: String,
    ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can read more &lt;a href="https://serde.rs/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Route and Handler
&lt;/h3&gt;

&lt;p&gt;It will be a post route which accepts json form data, validate it and return response depending on whether the validation is successful or failed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Route
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-form-validation/blob/master/src/main.rs" rel="noopener noreferrer"&gt;'./src/main.rs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    ....
    HttpServer::new(|| {
        App::new()
            .route("/", web::post().to(create_student))
    })
    ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-form-validation/blob/master/src/main.rs" rel="noopener noreferrer"&gt;'./src/main.rs&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Handler
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn create_student(json: web::Json&amp;lt;Student&amp;gt;) -&amp;gt; impl Responder {
    let is_valid = json.validate();
    match is_valid {
        Ok(_) =&amp;gt; HttpResponse::Ok().json("success"),
        Err(err) =&amp;gt; HttpResponse::BadRequest().json(err),
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the line &lt;code&gt;let is_valid = json.validate();&lt;/code&gt; implements the validator. Now lets define the define validation rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating validation rules
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Lets derive the &lt;a href="https://docs.rs/validator/0.15.0/validator/#" rel="noopener noreferrer"&gt;Validator trait&lt;/a&gt; from validator.rs.
&lt;/h4&gt;

&lt;p&gt;Add the validator trait along with serde Serialize and Deserialize traits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use validator::Validate;

#[derive(Serialize, Deserialize, Validate)]
pub struct Student {
    ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  But what are the requirements for Student Struct.
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt; : It must be greater than 3 characters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt; : It must be valid Gmail address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Age&lt;/strong&gt; :  It must be between 18 to 22 years.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password&lt;/strong&gt; : It must be 8 character with min one lower case alphabet,min one upper case alphabet, min one number and min one special character. Doesn't have white spaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Username&lt;/strong&gt; : It must be alphanumeric and 6 characters long.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Implementing conditions
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Name&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[validate(length(min = 3,message = "Name must be greater than 3 chars"))]
pub name: String
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;length&lt;/strong&gt; : It ensures that the length of data must be greater than or less than defined length.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;message&lt;/strong&gt; : It is that client side message which shows the error.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Email&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[validate(
    email,
    contains(pattern = "gmail", message = "Email must be valid gmail address")
)]
pub email: String,
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;email&lt;/strong&gt; : It ensures that the email contains which requirement like @ symbol,domain name and extension like .com and user-id.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;contains&lt;/strong&gt; and &lt;strong&gt;pattern&lt;/strong&gt; : It ensures that the particular string must contain particular sub word(pattern) and here is gmail.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Age&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[validate(range(min = 18, max = 22, message = "Age must be between 18 to 22"))]
pub age: u32,
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;range&lt;/strong&gt; : It enforces that the size should fall in a particular range.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Username&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lazy_static! {
    static ref RE_USER_NAME: Regex = Regex::new(r"^[a-zA-Z0-9]{6,}$").unwrap();
}
pub struct Student {
    ....
    #[validate(
        regex(
            path = "RE_USER_NAME",
            message = "Username must number and alphabets only and must be 6 characters long"
        )
    )]
    pub username: String,
    ....
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/rust-lang-nursery/lazy-static.rs" rel="noopener noreferrer"&gt;lazy_static&lt;/a&gt;&lt;/strong&gt; : Lazy evaluated statics in Rust. It is executed at the runtime includes anything requiring heap allocations, like vectors or hash maps etc&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;regex&lt;/strong&gt; : It requires a path/pattern to match. To learn more about the regex pattern used , you can refer to this &lt;a href="https://dev.to/ziishaned/learn-regex-the-easy-way-c4g"&gt;article&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Password&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lazy_static! {
    static ref RE_SPECIAL_CHAR: Regex = Regex::new("^.*?[@$!%*?&amp;amp;].*$").unwrap();
}

fn validate_password(password: &amp;amp;str) -&amp;gt; Result&amp;lt;(), ValidationError&amp;gt; {
    let mut has_whitespace = false;
    let mut has_upper = false;
    let mut has_lower = false;
    let mut has_digit = false;

    for c in password.chars() {
        has_whitespace |= c.is_whitespace();
        has_lower |= c.is_lowercase();
        has_upper |= c.is_uppercase();
        has_digit |= c.is_digit(10);
    }
    if !has_whitespace &amp;amp;&amp;amp; has_upper &amp;amp;&amp;amp; has_lower &amp;amp;&amp;amp; has_digit &amp;amp;&amp;amp; password.len() &amp;gt;= 8 {
        Ok(())
    } else {
        return Err(ValidationError::new("Password Validation Failed"));
    }
}
pub struct Student {
....
#[validate(
    custom(
        function = "validate_password",
        message = "Must Contain At Least One Upper Case, Lower Case and Number. Dont use spaces."
    ),
    regex(
        path = "RE_SPECIAL_CHAR",
        message = "Must Contain At Least One Special Character"
    )
)]
pub password: String,
....
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;custom&lt;/strong&gt; : It requires a function which implements validation and we can even add our custom message by message argument.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Complete Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extern crate lazy_static;
extern crate regex;
extern crate serde;

use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use lazy_static::lazy_static;
use regex::Regex;
use serde::{Deserialize, Serialize};
use validator::{Validate, ValidationError};

lazy_static! {
    static ref RE_USER_NAME: Regex = Regex::new(r"^[a-zA-Z0-9]{6,}$").unwrap();
    static ref RE_SPECIAL_CHAR: Regex = Regex::new("^.*?[@$!%*?&amp;amp;].*$").unwrap();
}

#[derive(Serialize, Deserialize, Validate)]
pub struct Student {
    #[validate(length(min = 3, message = "Name must be greater than 3 chars"))]
    pub name: String,
    #[validate(
        email,
        contains(pattern = "gmail", message = "Email must be valid gmail address")
    )]
    pub email: String,
    #[validate(range(min = 18, max = 22, message = "Age must be between 18 to 22"))]
    pub age: u32,
    #[validate(
        regex(
            path = "RE_USER_NAME",
            message = "Username must number and alphabets only and must be 6 characters long"
        )
    )]
    pub username: String,
    #[validate(
        custom(
            function = "validate_password",
            message = "Must Contain At Least One Upper Case, Lower Case and Number. Dont use spaces."
        ),
        regex(
            path = "RE_SPECIAL_CHAR",
            message = "Must Contain At Least One Special Character"
        )
    )]
    pub password: String,
}
fn validate_password(password: &amp;amp;str) -&amp;gt; Result&amp;lt;(), ValidationError&amp;gt; {
    let mut has_whitespace = false;
    let mut has_upper = false;
    let mut has_lower = false;
    let mut has_digit = false;

    for c in password.chars() {
        has_whitespace |= c.is_whitespace();
        has_lower |= c.is_lowercase();
        has_upper |= c.is_uppercase();
        has_digit |= c.is_digit(10);
    }
    if !has_whitespace &amp;amp;&amp;amp; has_upper &amp;amp;&amp;amp; has_lower &amp;amp;&amp;amp; has_digit &amp;amp;&amp;amp; password.len() &amp;gt;= 8 {
        Ok(())
    } else {
        return Err(ValidationError::new("Password Validation Failed"));
    }
}
pub async fn create_student(json: web::Json&amp;lt;Student&amp;gt;) -&amp;gt; impl Responder {
    let is_valid = json.validate();
    match is_valid {
        Ok(_) =&amp;gt; HttpResponse::Ok().json("success"),
        Err(err) =&amp;gt; HttpResponse::BadRequest().json(err),
    }
}

#[actix_web::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    println!("Starting the server at http://127.0.0.1:8080/");
    HttpServer::new(|| App::new().route("/", web::post().to(create_student)))
        .bind(("127.0.0.1", 8080))?
        .run()
        .await
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validating
&lt;/h3&gt;

&lt;p&gt;Let's spin our actix server by &lt;code&gt;cargo run&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Password Validation
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Payload&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name":"prave",
    "email":"praveen@gmail.com",
    "age":19,
    "username":"praveee",
    "password":"123@4aA"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

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

&lt;h4&gt;
  
  
  Name Validation
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Payload&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name":"pr",
    "email":"praveen@gmail.com",
    "age":19,
    "username":"praveee",
    "password":"123d@4aA"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

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

&lt;h4&gt;
  
  
  Email Validation
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Payload&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name":"praveen",
    "email":"praveen@outlook.com",
    "age":19,
    "username":"praveee",
    "password":"123d@4aA"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

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

&lt;h4&gt;
  
  
  Age Validation
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Payload&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "age": [
        {
            "code": "range",
            "message": "Age must be between 18 to 22",
            "params": {
                "min": 18.0,
                "value": 4,
                "max": 22.0
            }
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

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

&lt;h4&gt;
  
  
  Username Validation
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Payload&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name":"praveen",
    "email":"praveen@gmail.com",
    "age":19,
    "username":"prsdfdgfd@e",
    "password":"123d@4aA"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Feel free to ask queries and make pull request for changes and suggestion in GitHub. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/chaudharypraveen98/actix-form-validation" rel="noopener noreferrer"&gt;Github Repo Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Hacking&lt;/strong&gt;&lt;br&gt;
Rustaceans!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>validation</category>
      <category>actix</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Error Handling in Rust (Actix Web)</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Tue, 14 Jun 2022 08:38:51 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/error-handling-in-actix-web-4mm</link>
      <guid>https://dev.to/chaudharypraveen98/error-handling-in-actix-web-4mm</guid>
      <description>&lt;p&gt;Errors are part of software development. There are basically two types of errors in Rust i.e recoverable and unrecoverable. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recoverable errors&lt;/strong&gt; have type &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; and &lt;strong&gt;Unrecoverable errors&lt;/strong&gt; have &lt;code&gt;panic!&lt;/code&gt; macro that stops execution.&lt;/p&gt;

&lt;p&gt;Errors serve two main purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control flow (i.e. determine what to do next);&lt;/li&gt;
&lt;li&gt;Reporting (e.g. investigating, after the fact, what went wrong).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can also distinguish errors based on their location:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal (i.e. a function calling another function within our application);&lt;/li&gt;
&lt;li&gt;At the edge (i.e. an API request that we failed to fulfill).&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Internal&lt;/th&gt;
&lt;th&gt;At the edge&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Control Flow&lt;/td&gt;
&lt;td&gt;Types, methods, fields&lt;/td&gt;
&lt;td&gt;Status codes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reporting&lt;/td&gt;
&lt;td&gt;Logs/traces&lt;/td&gt;
&lt;td&gt;Response body&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can refer more &lt;a href="https://www.lpalmieri.com/posts/error-handling-rust/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first place where we are likely to get an error is &lt;code&gt;pool.get()&lt;/code&gt; . When we are unable to get the pool instance whatever will be the reason like wrong credentials, database instance not running, etc.&lt;/p&gt;

&lt;p&gt;Let's try how to handle it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Unwrap to create panic.
&lt;/h2&gt;

&lt;p&gt;Creating Panic is useful during the prototyping phase when we are more focused on logic implementation. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/api_handlers.rs" rel="noopener noreferrer"&gt;'/src/api_handlers.rs'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn get_tags(state: web::Data&amp;lt;AppState&amp;gt;) -&amp;gt;impl Responder  {
    // Just not handle the error and let the system to Panic (unrecoverable error)
    let client = state.pool
        .get()
        .await.unwrap();
    let result = db::get_tags_unwrap(&amp;amp;client).await;

    match result {
        Ok(tags) =&amp;gt; HttpResponse::Ok().json(tags),
        Err(_) =&amp;gt; HttpResponse::InternalServerError().into(),
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling unwrap will create panic and the execution stops. So, we have discovered that handling errors like this are not ideal in the production server.&lt;/p&gt;

&lt;p&gt;Let's move to another way&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Result
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Handling Single Error
&lt;/h3&gt;

&lt;p&gt;The caller of the execution must be aware of whether the program was completed successfully or failed. For this use case, we can use simple &lt;code&gt;ResultSignal&lt;/code&gt; enum&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/error.rs" rel="noopener noreferrer"&gt;'./src/error.rs'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub enum ResultSignal&amp;lt;Success&amp;gt; {
    Ok(Success),
    Err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will return Ok status on success and an Error on failure. It is helpful now that our user is aware that something mishappen has occurred. It is suitable for a single kind of error but our system consists of different services and they can fail in different ways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;what is the reason? where has failure occurred?&lt;/strong&gt;&lt;br&gt;
To answer this, we need to handle various errors according to our needs like database errors, filter errors, etc&lt;/p&gt;
&lt;h3&gt;
  
  
  Handling Multiple Errors
&lt;/h3&gt;

&lt;p&gt;Let's create an enum for different types of errors. For the sake of simplicity, we just considering two cases only Db Error and Not Found Error&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/error.rs" rel="noopener noreferrer"&gt;'./src/error.rs'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub enum AppErrorType {
    DbError,
    NotFoundError,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we need to implement the &lt;strong&gt;Debug and Display&lt;/strong&gt; trait. It is used to print errors using &lt;em&gt;println&lt;/em&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Debug)]
pub enum AppErrorType {
    DbError,
    NotFoundError,
}

impl fmt::Display for AppErrorType {
    fn fmt(&amp;amp;self, f: &amp;amp;mut fmt::Formatter&amp;lt;'_&amp;gt;) -&amp;gt; fmt::Result {
        write!(f, "{:?}", self)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;#[derive(Debug)]&lt;/strong&gt; :  This macro will enable the Debug trait for the enum AppErrorType.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;fn fmt&lt;/strong&gt; : Display is for user-facing output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;write!&lt;/strong&gt; and &lt;strong&gt;writeln!&lt;/strong&gt; are two macros that are used to emit the format string to a specified stream. This is used to prevent intermediate allocations of format strings and instead directly write the output.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's implement the &lt;strong&gt;From&lt;/strong&gt; trait to convert from one type to another like PoolError to AppErrorType.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl From&amp;lt;PoolError&amp;gt; for AppErrorType {
    fn from(_error: PoolError) -&amp;gt; AppErrorType {
        AppErrorType::DbError
    }
}
impl From&amp;lt;Error&amp;gt; for AppErrorType {
    fn from(_error: Error) -&amp;gt; AppErrorType {
        AppErrorType::DbError
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since, we will be using Result  return type in api handlers then we need overwrite the &lt;strong&gt;ResponseError&lt;/strong&gt; Trait.&lt;/p&gt;

&lt;p&gt;Actix provide two methods &lt;strong&gt;error_response&lt;/strong&gt; and &lt;strong&gt;status_code&lt;/strong&gt; to handle errors response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl ResponseError for AppErrorType {
    fn error_response(&amp;amp;self) -&amp;gt; HttpResponse {
        HttpResponse::build(self.status_code()).finish()
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we need to change the return type from &lt;strong&gt;impl Responder&lt;/strong&gt; or &lt;strong&gt;HttpResponse&lt;/strong&gt; to &lt;strong&gt;Result&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We have used the &lt;code&gt;?&lt;/code&gt; trait already implemented above in error.rs instead to unwrap.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/api_handlers.rs" rel="noopener noreferrer"&gt;'./src/api_handlers.rs'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn get_tags(state: web::Data&amp;lt;AppState&amp;gt;) -&amp;gt;Result&amp;lt;HttpResponse,AppErrorType&amp;gt; {
    let client: Client = state.pool.get().await?;
    let result = db::get_tags(&amp;amp;client).await;
    result.map(|tags| HttpResponse::Ok().json(tags))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of using unwrap in &lt;code&gt;client.prepare("select * from tag limit 10;").await.unwrap()&lt;/code&gt;, we can now use the &lt;code&gt;?&lt;/code&gt; as we have implemented the From trait and update the return type too &lt;code&gt;Result&amp;lt;Vec&amp;lt;Tag&amp;gt;, AppErrorType&amp;gt;&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/db.rs" rel="noopener noreferrer"&gt;'./src/db.rs'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn get_tags(client: &amp;amp;Client) -&amp;gt; Result&amp;lt;Vec&amp;lt;Tag&amp;gt;, AppErrorType&amp;gt; {
    let statement = client.prepare("select * from tag limit 10;").await?;
    let tags = client
        .query(&amp;amp;statement, &amp;amp;[])
        .await
        .expect("Error getting tags")
        .iter()
        .map(|row| Tag::from_row_ref(row).unwrap())
        .collect::&amp;lt;Vec&amp;lt;Tag&amp;gt;&amp;gt;();

    Ok(tags)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's spin our server and hit the endpoint. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flf422vtpmkv6z2te1y6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flf422vtpmkv6z2te1y6d.png" alt="Returned Response" width="800" height="336"&gt;&lt;/a&gt;&lt;br&gt;
The request returned a &lt;code&gt;500&lt;/code&gt; status code. Instead of just panicking we are getting a status code that will help to debug.&lt;/p&gt;
&lt;h4&gt;
  
  
  But is only status code really helpful??
&lt;/h4&gt;

&lt;p&gt;Not, not at all, A good error contains the cause of the error, the error status code, and a message for the client user which is human readable&lt;/p&gt;
&lt;h4&gt;
  
  
  Let's try to improve our error handling
&lt;/h4&gt;

&lt;p&gt;Let's implement the AppError struct which contains our three fields' cause, error type, and message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/error.rs" rel="noopener noreferrer"&gt;'./src/error.rs'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub struct AppError {
    pub cause: Option&amp;lt;String&amp;gt;,
    pub message: Option&amp;lt;String&amp;gt;,
    pub error_type: AppErrorType,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like AppErrorType, Let's implement Debug and Display trait&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Debug)]
pub struct AppError {
    pub cause: Option&amp;lt;String&amp;gt;,
    pub message: Option&amp;lt;String&amp;gt;,
    pub error_type: AppErrorType,
}

impl fmt::Display for AppError {
    fn fmt(&amp;amp;self, f: &amp;amp;mut fmt::Formatter&amp;lt;'_&amp;gt;) -&amp;gt; fmt::Result {
        write!(f, "{:?}", self)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we are done with &lt;code&gt;display&lt;/code&gt; and &lt;code&gt;debug&lt;/code&gt; trait, let's define ResponseError for AppError&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl ResponseError for AppError {

    fn status_code(&amp;amp;self) -&amp;gt; StatusCode {
        match self.error_type {
            AppErrorType::DbError =&amp;gt; (StatusCode::INTERNAL_SERVER_ERROR),
            AppErrorType::NotFoundError =&amp;gt; (StatusCode::NOT_FOUND),
        }
    }

    fn error_response(&amp;amp;self) -&amp;gt; HttpResponse {
        HttpResponse::build(self.status_code()).json(AppErrorResponse {
            error: self.message(),
        })
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we have used &lt;code&gt;status_code&lt;/code&gt; to match different errors and provide a status code according to it.&lt;/p&gt;

&lt;p&gt;As soon the ResponseError is defined, We use From trait for error type conversion&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl From&amp;lt;PoolError&amp;gt; for AppError {
    fn from(error: PoolError) -&amp;gt; AppError {
        AppError {
            message: None,
            cause: Some(error.to_string()),
            error_type: AppErrorType::DbError,
        }
    }
}
impl From&amp;lt;Error&amp;gt; for AppError {
    fn from(error: Error) -&amp;gt; AppError {
        AppError {
            message: None,
            cause: Some(error.to_string()),
            error_type: AppErrorType::DbError,
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's implement a default message for the error types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl AppError {
    // we are handling the none. the function name should match the field name
    fn message(&amp;amp;self) -&amp;gt; String {
        match &amp;amp;*self {
            // Error message is found then clone otherwise default message
            AppError {
                cause: _,
                message: Some(message),
                error_type: _,
            } =&amp;gt; message.clone(),
            AppError {
                cause: _,
                message: None,
                error_type: AppErrorType::NotFoundError,
            } =&amp;gt; "The requested item was not found".to_string(),
            _ =&amp;gt; "An unexpected error has occurred".to_string(),
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are done with all the necessary changes in error.rs file. Let's start with API handlers and DB handlers&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/api_handlers.rs" rel="noopener noreferrer"&gt;'./src/api_handlers.rs'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn get_tags(state: web::Data&amp;lt;AppState&amp;gt;) -&amp;gt; Result&amp;lt;HttpResponse, AppError&amp;gt; {
    let client: Client = state.pool.get().await?;
    let result = db::get_tags(&amp;amp;client).await;
    result.map(|tags| HttpResponse::Ok().json(tags))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to enable the logger to get a vivid description. You can use the &lt;strong&gt;actix default logger&lt;/strong&gt; or the &lt;strong&gt;slog logger&lt;/strong&gt;. You can read more about slog &lt;a href="https://dev.to/chaudharypraveen98/adding-slog-logger-to-actix-web-2332"&gt;here.&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async fn configure_pool(pool: Pool, log: Logger) -&amp;gt; Result&amp;lt;Client, AppError&amp;gt; {
    pool.get().await.map_err(|err| {
        let sublog = log.new(o!("cause"=&amp;gt;err.to_string()));
        crit!(sublog, "Error creating client");
        AppError::from(err)
    })
}


pub async fn get_tags(state: web::Data&amp;lt;AppState&amp;gt;) -&amp;gt; Result&amp;lt;HttpResponse, AppError&amp;gt; {
    let sublog = state.log.new(o!("handler" =&amp;gt; "get_tags"));
    let client: Client = configure_pool(state.pool.clone(), sublog.clone()).await?;
    let result = db::get_tags(&amp;amp;client).await;
    result.map(|tags| HttpResponse::Ok().json(tags))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's change the Db handler file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow/blob/master/src/db.rs" rel="noopener noreferrer"&gt;'./src/db.rs'&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub async fn get_tags(client: &amp;amp;Client) -&amp;gt; Result&amp;lt;Vec&amp;lt;Tag&amp;gt;, AppError&amp;gt; {
    let statement = client.prepare("select * from tag limit 10;").await?;
    let tags = client
        .query(&amp;amp;statement, &amp;amp;[])
        .await
        .expect("Error getting tags")
        .iter()
        .map(|row| Tag::from_row_ref(row).unwrap())
        .collect::&amp;lt;Vec&amp;lt;Tag&amp;gt;&amp;gt;();

    Ok(tags)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start our server and hit the API endpoint. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Client side error&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Server side error&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Wow!! We have now logs and error messages for the client user.&lt;/p&gt;

&lt;p&gt;For Awesome logs, we have used the slog logger. If you want to follow my blog then checkout here &lt;a href="https://dev.to/chaudharypraveen98/adding-slog-logger-to-actix-web-2332"&gt;chaudharypraveen98 - Adding Slog Logger to Actix-web&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-question-bank-stackoverflow" rel="noopener noreferrer"&gt;GitHub Source Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=NHaWAWLgtAw" rel="noopener noreferrer"&gt;Error handling and Logging with Actix Web (Rust)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.lpalmieri.com/posts/error-handling-rust/" rel="noopener noreferrer"&gt;Error Handling In Rust - A Deep Dive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Added Comments for your quick revision and understanding.&lt;/p&gt;

&lt;p&gt;Feel free to ask any questions or provide suggestions. I am too learning. So will be glad to get your feedback. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Hacking&lt;/strong&gt;&lt;br&gt;
Rustaceans!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>actix</category>
      <category>errors</category>
      <category>logging</category>
    </item>
    <item>
      <title>Adding Slog Logger to Actix Web</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Thu, 02 Jun 2022 16:42:45 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/adding-slog-logger-to-actix-web-2332</link>
      <guid>https://dev.to/chaudharypraveen98/adding-slog-logger-to-actix-web-2332</guid>
      <description>&lt;p&gt;We will learn how to use slog logger for logging in Actix web.&lt;br&gt;
&lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;Actix web&lt;/a&gt; is a powerful, pragmatic, and extremely fast web framework for Rust and &lt;a href="https://docs.rs/slog/2.7.0/slog/" rel="noopener noreferrer"&gt;Slog&lt;/a&gt; is an ecosystem of reusable components for structured, extensible, composable logging for Rust. We will be using two crates of slog : &lt;code&gt;slog-async&lt;/code&gt; and &lt;code&gt;slog-term&lt;/code&gt; with the core Slog Core Package.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Slog over default log crate?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;extensible&lt;/li&gt;
&lt;li&gt;composable&lt;/li&gt;
&lt;li&gt;flexible&lt;/li&gt;
&lt;li&gt;structured and both human and machine-readable&lt;/li&gt;
&lt;li&gt;contextual&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Crates used
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;Actix Web&lt;/a&gt; : powerful web framework.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/slog" rel="noopener noreferrer"&gt;Slog Core Crate&lt;/a&gt; : core package to the gateway of logging modules.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/slog-term" rel="noopener noreferrer"&gt;Slog Term&lt;/a&gt; : Unix terminal drain and formatter for slog-rs.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/slog-term" rel="noopener noreferrer"&gt;Slog Term&lt;/a&gt; : Asynchronous drain for slog-rs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Crated Version and Code
&lt;/h3&gt;

&lt;p&gt;Simply paste the code in the &lt;code&gt;cargo.toml&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;slog = "2.7.0"
slog-term = "2.9.0"
slog-async = "2.7.0"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Default template for Actix web
&lt;/h3&gt;

&lt;p&gt;It is a default &lt;a href="https://actix.rs/" rel="noopener noreferrer"&gt;hello world program&lt;/a&gt; of Actix web&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use actix_web::{ web, App, HttpServer};

async fn index() -&amp;gt; &amp;amp;'static str {
    "Hello world!"
}

#[actix_web::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    println!("Starting the server at 127.0.0.1:8080");

    HttpServer::new(|| {
        App::new()
            .service(web::resource("/index.html").to(|| async { "Hello world!" }))
            .service(web::resource("/").to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Logger
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use slog;
use slog::{Logger,o,Drain,info};
use slog_term;
use slog_async;

fn configure_log()-&amp;gt;Logger{
    let decorator = slog_term::TermDecorator::new().build();
    let console_drain = slog_term::FullFormat::new(decorator).build().fuse();

    // It is used for Synchronization
    let console_drain = slog_async::Async::new(console_drain).build().fuse();

    // Root logger
    slog::Logger::root(console_drain,o!("v"=&amp;gt;env!("CARGO_PKG_VERSION")))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break the configuration function and understand what is happening behind the scene.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TermDecorator Decorator&lt;/strong&gt; : IT is used for formatting terminal output implemented using &lt;strong&gt;term crate&lt;/strong&gt;. This decorator will add nice formatting to the logs it’s outputting. &lt;em&gt;Note&lt;/em&gt; It does not deal with serialization so is !Sync. Run in a separate thread with slog_async::Async. We will be using the slog async with it. We can &lt;a href="https://docs.rs/slog-term/2.9.0/slog_term/index.html#structs" rel="noopener noreferrer"&gt;other decorator&lt;/a&gt; like CompactFormat, PlainRecordDecorator etc according to need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FullFormat&lt;/strong&gt; : It is a Drain that will take &lt;em&gt;Decorator&lt;/em&gt; as an argument, used for terminal output. Decorator is for formatting and Drain is for outputting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronization via Async Slog&lt;/strong&gt; : They are three ways slog to do synchronization out of which &lt;strong&gt;PlainSyncDecorator&lt;/strong&gt; and &lt;strong&gt;slog_async&lt;/strong&gt; are the efficient one depending on the need. Other than the two, the last &lt;strong&gt;Synchronization via Mutex&lt;/strong&gt; is not efficient. You can read more &lt;a href="https://docs.rs/slog-term/2.9.0/slog_term/index.html#structs" rel="noopener noreferrer"&gt;here&lt;/a&gt;. We are using the synchronization with slog_async.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logger::root&lt;/strong&gt; :&lt;a href="https://docs.rs/slog/2.7.0/slog/struct.Logger.html#method.root" rel="noopener noreferrer"&gt;Logger&lt;/a&gt; is used to execute logging statements. It takes two arguments 

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;drain&lt;/strong&gt; - destination where to forward logging Records for processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;context&lt;/strong&gt; - list of key-value pairs associated with it.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;o!&lt;/strong&gt; : Macro for building group of key-value pairs used as a content in Logger.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;fuse()&lt;/strong&gt; : It is used for panicking if something went wrong. It is necessary to call fuse as the root logger must take a Drain which is error free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passing log instance to the handlers
&lt;/h3&gt;

&lt;p&gt;Add the following line of code in main function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let log = configure_log();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will configure the logger and ready to use now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passing a log instance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(log.clone()))
            .service(web::resource("/index.html").to(|| async { "Hello world!" }))
            .service(web::resource("/").to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;web::Data::new(log.clone())&lt;/strong&gt; : It is an application data stored with App::app_data() method available through the HttpRequest::app_data method at runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing the Log instance in function handlers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async fn index(log: web::Data&amp;lt;Logger&amp;gt;) -&amp;gt; &amp;amp;'static str {
    info!(log,
        "Inside Hello World"
    );
    "Hello world!"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;info!&lt;/strong&gt; : It is  a macro used for the building Info Level Record Or Context(key-value pair) used by Logger to output. They are a bunch of macros you can be used for &lt;a href="https://docs.rs/slog/2.7.0/slog/index.html#macros" rel="noopener noreferrer"&gt;different level records&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;log: web::Data&lt;/strong&gt; : -&lt;br&gt;
Essentials helper functions and types for application registration.&lt;/p&gt;

&lt;p&gt;Request Extractors&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data: Application data item&lt;/li&gt;
&lt;li&gt;ReqData: Request-local data item&lt;/li&gt;
&lt;li&gt;Path: URL path parameters / dynamic segments&lt;/li&gt;
&lt;li&gt;Query: URL query parameters&lt;/li&gt;
&lt;li&gt;Header: Typed header&lt;/li&gt;
&lt;li&gt;Json: JSON payload&lt;/li&gt;
&lt;li&gt;Form: URL-encoded payload&lt;/li&gt;
&lt;li&gt;Bytes: Raw payload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are using the &lt;code&gt;Data&lt;/code&gt; method to access the application data initialised in server instance in main function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use actix_web::{web, App, HttpServer};
// IT is used as a logging middleware. We can even use the default logger with actix.
use slog;
use slog::{Logger,o,Drain,info};
use slog_term;
use slog_async;

fn configure_log()-&amp;gt;Logger{
    // Formatting the output https://docs.rs/slog-term/2.9.0/slog_term/index.html#
    let decorator = slog_term::TermDecorator::new().build();

    // Drain for outputting https://docs.rs/slog-term/2.9.0/slog_term/index.html#structs
    // fuse is used for panicking if something went wrong. It is necessary to call fuse as the root logger must take a Drain which is error free.
    let console_drain = slog_term::FullFormat::new(decorator).build().fuse();

    // It is used for Synchronization https://docs.rs/slog-term/2.9.0/slog_term/index.html#structs
    let console_drain = slog_async::Async::new(console_drain).build().fuse();
    slog::Logger::root(console_drain,o!("v"=&amp;gt;env!("CARGO_PKG_VERSION")))
}
async fn index(log: web::Data&amp;lt;Logger&amp;gt;) -&amp;gt; &amp;amp;'static str {
    info!(log,
        "Inside Hello World"
    );
    "Hello world!"
}

#[actix_web::main]
async fn main() -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {
    let log = configure_log();

    info!(log,
        "Starting the server at http://127.0.0.1:8080/"
    );

    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(log.clone()))
            .service(web::resource("/index.html").to(|| async { "Hello world!" }))
            .service(web::resource("/").to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Logging Output
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/chaudharypraveen98/actix-slog-logger-setup" rel="noopener noreferrer"&gt;GitHub Source Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Added Comments for your quick revision and understanding.&lt;/p&gt;

&lt;h4&gt;
  
  
  Feel free to ask any questions or provide suggestions. I am too learning. So will be glad to get your feedback. Happy Hacking! Rustaceans!
&lt;/h4&gt;

</description>
      <category>rust</category>
      <category>webdev</category>
      <category>actix</category>
      <category>logging</category>
    </item>
    <item>
      <title>Stackoverflow scraping with rust</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Sat, 26 Jun 2021 07:12:00 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/stackoverflow-scraping-with-rust-4624</link>
      <guid>https://dev.to/chaudharypraveen98/stackoverflow-scraping-with-rust-4624</guid>
      <description>&lt;p&gt;It will extract the title, question link, answers count, view count, and votes from StackOverflow depending on the tag parameter and count. This scraper is inspired by &lt;a href="https://github.com/kadekillary/scraping-with-rust" rel="noopener noreferrer"&gt;Kadekillary Scarper&lt;/a&gt; with updated libraries and some more features added.&lt;/p&gt;

&lt;h4&gt;
  
  
  Libraries Used
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/reqwest" rel="noopener noreferrer"&gt;Reqwest&lt;/a&gt; 
&amp;gt;An ergonomic, batteries-included HTTP Client for Rust.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/select" rel="noopener noreferrer"&gt;Select&lt;/a&gt;
&amp;gt;A Rust library to extract useful data from HTML documents, suitable for web scraping&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/clap" rel="noopener noreferrer"&gt;Clap&lt;/a&gt;
&amp;gt;A simple-to-use, efficient, and full-featured library for parsing command line arguments and subcommands.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Simple and Fast&lt;/li&gt;
&lt;li&gt;Async get request&lt;/li&gt;
&lt;li&gt;Cli mode&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to run
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Build the executable by &lt;code&gt;cargo build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run by &lt;code&gt;./target/debug/stackoverflow-scraping-with-rust -t &amp;lt;tag&amp;gt; -c &amp;lt;count&amp;gt;&lt;/code&gt;
&lt;strong&gt;&amp;lt; tag &amp;gt;&lt;/strong&gt; is the topic from which you want to scrape
&lt;strong&gt;&amp;lt; count &amp;gt;&lt;/strong&gt; is the number of posts/threads to be scraped. Note the maximum limit is &lt;em&gt;16&lt;/em&gt;
Like this
&lt;code&gt;./target/debug/stackoverflow-scraping-with-rust -t java -c 1&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What We are going to do?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Getting argument from the command line using Clap library&lt;/li&gt;
    &lt;li&gt;Make a request using the Reqwest library&lt;/li&gt;
    &lt;li&gt;Scraping using the Selectrs library&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Libraries Used
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/reqwest" rel="noopener noreferrer"&gt;Reqwest&lt;/a&gt; 
&amp;gt;An ergonomic, batteries-included HTTP Client for Rust.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/select" rel="noopener noreferrer"&gt;Select&lt;/a&gt;
&amp;gt;A Rust library to extract useful data from HTML documents, suitable for web scraping&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/clap" rel="noopener noreferrer"&gt;Clap&lt;/a&gt;
&amp;gt;A simple-to-use, efficient, and full-featured library for parsing command line arguments and subcommands.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Installing Libraries&lt;/strong&gt;&lt;br&gt;
&lt;b&gt;Simple add the following libraries in Cargo.toml&lt;/b&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
reqwest = { version = "0.10", features = ["json"] }
tokio = { version = "0.2", features = ["full"] }
select = "0.6.0-alpha.1"
clap = "2.33.3"
rand = "0.8.4"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Before moving ahead, We must be aware of CSS selectors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are selectors/locators?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;b&gt;CSS Selector&lt;/b&gt; is a combination of an element selector and a value that identifies the web element within a web page.&lt;br&gt;
&lt;b&gt;The choice of locator depends largely on your Application Under Test&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Id&lt;/b&gt;&lt;br&gt;
An element’s id in XPATH is defined using: “[&lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt;='example']” and in CSS using: “#” - ID's must be unique within the DOM.&lt;br&gt;
Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XPath: //div[@id='example']
CSS: #example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;b&gt;Element Type&lt;/b&gt;&lt;br&gt;
The previous example showed //div in the XPath. That is the element type, which could be input for a text box or button, img for an image, or "a" for a link.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Xpath: //input or
Css: =input
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;b&gt;Direct Child&lt;/b&gt;&lt;br&gt;
HTML pages are structured like XML, with children nested inside of parents. If you can locate, for example, the first link within a div, you can construct a string to reach it. A direct child in XPATH is defined by the use of a “/“, while on CSS, it’s defined using “&amp;gt;”. &lt;br&gt;
Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XPath: //div/a
CSS: div &amp;gt; a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;b&gt;Child or Sub-Child&lt;/b&gt;&lt;br&gt;
Writing nested divs can get tiring - and result in code that is brittle. Sometimes you expect the code to change, or want to skip layers. If an element could be inside another or one of its children, it’s defined in XPATH using “//” and in CSS just by whitespace.&lt;br&gt;
Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XPath: //div//a
CSS: div a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;b&gt;Class&lt;/b&gt;&lt;br&gt;
For classes, things are pretty similar in XPATH: “[&lt;a class="mentioned-user" href="https://dev.to/class"&gt;@class&lt;/a&gt;='example']” while in CSS it’s just “.” &lt;br&gt;
Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XPath: //div[@class='example']
CSS: .example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1 -&amp;gt; Getting argument from the command line using Clap library
&lt;/h2&gt;

&lt;p&gt;We are using the Clap library to get the argument from the command line.&lt;br&gt;
There are three cases: -&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;
&lt;b&gt;Only tag is provided&lt;/b&gt; =&amp;gt; We will get only the posts from the input tag with default no of post i.e 16&lt;/li&gt;
    &lt;li&gt;
&lt;b&gt;Only count is supplies&lt;/b&gt; =&amp;gt; We will get only input number of post from any random topic using the Rand library&lt;/li&gt;
    &lt;li&gt;
&lt;b&gt;Both count and tag&lt;/b&gt; =&amp;gt; We will get input number of post of input tag&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First, we initialize the command line app names StackOverflow Scraper. Then mention all the three cases with their short and long name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main() {
    let matches = App::new("StackOverflow Scraper")
        .version("1.0")
        .author("Praveen Chaudhary &amp;amp;lt;chaudharypraveen98@gmail.com&amp;amp;gt;")
        .about("It will scrape questions from StackOverflow depending on the tag.")
        .arg(
            Arg::with_name("tag")
                .short("t")
                .long("tag")
                .takes_value(true)
                .help("takes the tag and scrape according to this"),
        )
        .arg(
            Arg::with_name("count")
                .short("c")
                .long("count")
                .takes_value(true)
                .help("gives n count of posts"),
        )
        .get_matches();
        ....
        ....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have mentioned all the cases. Now we need to extract the argument value using the match which helps us to find a particular pattern&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    fn main() {
        .....
        .....

        if matches.is_present("tag") &amp;amp;&amp;amp; matches.is_present("count") {
            let url = format!(
                "https://stackoverflow.com/questions/tagged/{}?tab=Votes",
                matches.value_of("tag").unwrap()
            );
            let count: i32 = matches.value_of("count").unwrap().parse::&amp;lt;i32&amp;gt;().unwrap();
            stackoverflow_post(&amp;amp;url, count as usize);
        } else if matches.is_present("tag") {
            let url = format!(
                "https://stackoverflow.com/questions/tagged/{}?tab=Votes",
                matches.value_of("tag").unwrap()
            );
            stackoverflow_post(&amp;amp;url, 16);
        } else if matches.is_present("count") {
            let url = get_random_url();
            let count: i32 = matches.value_of("count").unwrap().parse::&amp;lt;i32&amp;gt;().unwrap();
            stackoverflow_post(&amp;amp;url, count as usize);
        } else {        
            let url = get_random_url();        
            stackoverflow_post(&amp;amp;url, 16);
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we have used the stackoverflow_post function. We will learn about this in &lt;b&gt;Step 3&lt;/b&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 -&amp;gt; Make a request using the Reqwest library
&lt;/h2&gt;

&lt;p&gt;We will use the reqwest library to make a get request to the StackOverflow website customized with the input tag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[tokio::main]
async fn hacker_news(url: &amp;amp;str, count: usize) -&amp;gt; Result&amp;lt;(), reqwest::Error&amp;gt; {
    let resp = reqwest::get(url).await?;
    ....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3 -&amp;gt; Scraping using the Selectrs library
&lt;/h2&gt;

&lt;p&gt;We will use the CSS selectors to get the question post from the StackOverflow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[tokio::main]
async fn hacker_news(url: &amp;amp;str, count: usize) -&amp;gt; Result&amp;lt;(), reqwest::Error&amp;gt; {
    ..... 
    ..... 

    let document = Document::from(&amp;amp;*resp.text().await?);

    for node in document.select(Class("s-post-summary")).take(count) {
        let question = node
            .select(Class("s-post-summary--content-excerpt"))
            .next()
            .unwrap()
            .text();
        let title_element = node
            .select(Class("s-post-summary--content-title").child(Name("a")))
            .next()
            .unwrap();
        let title = title_element.text();
        let question_link = title_element.attr("href").unwrap();
        let stats = node
            .select(Class("s-post-summary--stats-item-number"))
            .map(|stat| stat.text())
            .collect::&amp;lt;Vec&amp;lt;_&amp;gt;&amp;gt;();
        let votes = &amp;amp;stats[0];
        let answer = &amp;amp;stats[1];
        let views = &amp;amp;stats[2];
        let tags = node
            .select(Class("post-tag"))
            .map(|tag| tag.text())
            .collect::&amp;lt;Vec&amp;lt;_&amp;gt;&amp;gt;();
        println!("Question       =&amp;gt; {}", question);
        println!(
            "Question-link  =&amp;gt; https://stackoverflow.com{}",
            question_link
        );
        println!("Question-title =&amp;gt; {}", title);
        println!("Votes          =&amp;gt; {}", votes);
        println!("Views          =&amp;gt; {}", views);
        println!("Tags           =&amp;gt; {}", tags.join(" ,"));
        println!("Answers        =&amp;gt; {}", answer);
        println!("-------------------------------------------------------------\n");
    }
    Ok(())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extern crate clap;
extern crate reqwest;
extern crate select;
extern crate tokio;

use clap::{App, Arg};
use rand::seq::SliceRandom;
use select::document::Document;
use select::predicate::{Attr, Class, Name, Or, Predicate};

fn main() {
    let matches = App::new("StackOverflow Scraper")
        .version("1.0")
        .author("Praveen Chaudhary &amp;amp;lt;chaudharypraveen98@gmail.com&amp;amp;gt;")
        .about("It will scrape questions from stackoverflow depending on the tag.")
        .arg(
            Arg::with_name("tag")
                .short("t")
                .long("tag")
                .takes_value(true)
                .help("takes the tag and scrape according to this"),
        )
        .arg(
            Arg::with_name("count")
                .short("c")
                .long("count")
                .takes_value(true)
                .help("gives n count of posts"),
        )
        .get_matches();

    if matches.is_present("tag") &amp;amp;&amp;amp; matches.is_present("count") {
        let url = format!(
            "https://stackoverflow.com/questions/tagged/{}?tab=Votes",
            matches.value_of("tag").unwrap()
        );
        let count: i32 = matches.value_of("count").unwrap().parse::&amp;lt;i32&amp;gt;().unwrap();
        hacker_news(&amp;amp;url, count as usize);
    } else if matches.is_present("tag") {
        let url = format!(
            "https://stackoverflow.com/questions/tagged/{}?tab=Votes",
            matches.value_of("tag").unwrap()
        );
        hacker_news(&amp;amp;url, 16);
    } else if matches.is_present("count") {
        let url = get_random_url();
        let count: i32 = matches.value_of("count").unwrap().parse::&amp;lt;i32&amp;gt;().unwrap();
        hacker_news(&amp;amp;url, count as usize);
    } else {        
        let url = get_random_url();        
        hacker_news(&amp;amp;url, 16);
    }
}

#[tokio::main]
async fn hacker_news(url: &amp;amp;str, count: usize) -&amp;gt; Result&amp;amp;lt;(), reqwest::Error&amp;amp;gt; {
    let resp = reqwest::get(url).await?;
    // println!("body = {:?}", resp.text().await?);
    // assert!(resp.status().is_success());
    let document = Document::from(&amp;amp;*resp.text().await?);

    for node in document.select(Class("s-post-summary")).take(count) {
        let question = node
            .select(Class("s-post-summary--content-excerpt"))
            .next()
            .unwrap()
            .text();
        let title_element = node
            .select(Class("s-post-summary--content-title").child(Name("a")))
            .next()
            .unwrap();
        let title = title_element.text();
        let question_link = title_element.attr("href").unwrap();
        let stats = node
            .select(Class("s-post-summary--stats-item-number"))
            .map(|stat| stat.text())
            .collect::&amp;lt;Vec&amp;lt;_&amp;gt;&amp;gt;();
        let votes = &amp;amp;stats[0];
        let answer = &amp;amp;stats[1];
        let views = &amp;amp;stats[2];
        let tags = node
            .select(Class("post-tag"))
            .map(|tag| tag.text())
            .collect::&amp;lt;Vec&amp;lt;_&amp;gt;&amp;gt;();
        println!("Question       =&amp;gt; {}", question);
        println!(
            "Question-link  =&amp;gt; https://stackoverflow.com{}",
            question_link
        );
        println!("Question-title =&amp;gt; {}", title);
        println!("Votes          =&amp;gt; {}", votes);
        println!("Views          =&amp;gt; {}", views);
        println!("Tags           =&amp;gt; {}", tags.join(" ,"));
        println!("Answers        =&amp;gt; {}", answer);
        println!("-------------------------------------------------------------\n");
    }
    Ok(())
}

// Getting random tag
fn get_random_url() -&amp;gt; String {
    let default_tags = vec!["python", "rust", "c#", "android", "html", "javascript"];
    let random_tag = default_tags.choose(&amp;amp;mut rand::thread_rng()).unwrap();
    let url = format!(
        "https://stackoverflow.com/questions/tagged/{}?tab=Votes",
        random_tag
    );
    url.to_string()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to run our scraper?
&lt;/h2&gt;

&lt;ol&gt;
    &lt;li&gt;Build the executable by &lt;code&gt;cargo build&lt;/code&gt;
&lt;/li&gt;
    &lt;li&gt;Run by &lt;code&gt;./target/debug/stackoverflow-scraping-with-rust -t &amp;lt;tag&amp;gt; -c &amp;lt;count&amp;gt;&lt;/code&gt; &amp;lt; tag &amp;gt; is the topic from which you want to scrape &amp;lt; count &amp;gt; is the number of posts/threads to be scraped. Note the maximum limit is 16. Like this &lt;code&gt;./target/debug/stackoverflow-scraping-with-rust -t java -c 1&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;You can deploy on &lt;a href="https://www.heroku.com/" rel="noopener noreferrer"&gt;Heroku&lt;/a&gt; with the help of &lt;a href="https://circleci.com/" rel="noopener noreferrer"&gt;Circle CI&lt;/a&gt;&lt;br&gt;
You can read more about on &lt;a href="https://circleci.com/blog/rust-cd/" rel="noopener noreferrer"&gt;CircleCI Blog&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Preview / Output
&lt;/h2&gt;

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

&lt;p&gt;&lt;a href="https://drive.google.com/file/d/1SjQ0U1JZF6nn74PgpHDnurwvjEGGl-VH/preview" rel="noopener noreferrer"&gt;Google Drive&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Github Link&lt;/strong&gt; = &amp;gt; &lt;a href="https://github.com/chaudharypraveen98/stackoverflow-scraping-with-rust" rel="noopener noreferrer"&gt;https://github.com/chaudharypraveen98/stackoverflow-scraping-with-rust&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>scraping</category>
      <category>cli</category>
      <category>selectrs</category>
    </item>
    <item>
      <title>Farsite</title>
      <dc:creator>Praveen Chaudhary</dc:creator>
      <pubDate>Mon, 31 May 2021 13:37:40 +0000</pubDate>
      <link>https://dev.to/chaudharypraveen98/farsite-hen</link>
      <guid>https://dev.to/chaudharypraveen98/farsite-hen</guid>
      <description>&lt;p&gt;Farsite is a blockchain powered sandbox massively multiplayer online (MMO) real-time strategy (RTS) game. It has the elements of adventure in a science-fiction setting based on a post-apocalyptic story.&lt;/p&gt;

&lt;p&gt;The gaming universe of Farsite is formed by Constellations containing stars, each with unique set of planets. "Homestead" is the first Constellation where all players start the game. By using some Credits, players can travel between Stars on spaceships following interstellar paths in faster than light modes, performing some social media tasks can increase your scores to get a powerful starter ship. If this alone has made you excited or has sparked your interest to the game, you may use this link to register, &lt;a href="https://farsite.club/u/warliezdiaz" rel="noopener noreferrer"&gt;https://farsite.club/u/warliezdiaz&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technology Used
&lt;/h3&gt;

&lt;p&gt;Farsite is built using a mix of distributed ledger technology. The game also features Collateralized Digital Assets (cNFT) which is a proposed standard for ERC-20 collateral staking on non-fungible tokens (NFTs) Most of the in-game operations and trading will take place on Layer 2. Farsite will be open source and open to anyone who wants to play and contribute to the development of the game. It will be available to anyone with a web address and can be played by anyone with an internet connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment
&lt;/h3&gt;

&lt;p&gt;Within the Farsite universe, Constellations play a central role. Only 4 to 5 Planets will be explored on the start of the game. Exploring a Planet will open its Sectors for acquisition and reveal resources spots and deposits. Sectors are a part of a Planet representing a construction site for a Base. These contain valuable resources that can be extracted using special buildings on the surface.&lt;/p&gt;

&lt;p&gt;The ownership of a Sector can be traded or transferred to another player with all the contained Resources and constructed Bases. The construction of Stations can only be done by a player or a Corporation and requires a lot of resources and credits. Without a Station in a Star, players will need to fly to another Star to perform these transactions and require credits. All planets in the 'Homestead' Constellation will be available for colonization. There are 8 to 10 known Planets, unknown Planets and dead Planets.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
