<?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: Sureni Dhanasekara</title>
    <description>The latest articles on DEV Community by Sureni Dhanasekara (@sureni-dhanasekara).</description>
    <link>https://dev.to/sureni-dhanasekara</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%2F3064482%2Fe957ba02-b320-4e97-9566-6c80d2e7c93f.jpg</url>
      <title>DEV Community: Sureni Dhanasekara</title>
      <link>https://dev.to/sureni-dhanasekara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sureni-dhanasekara"/>
    <language>en</language>
    <item>
      <title>Advance Types In Rust</title>
      <dc:creator>Sureni Dhanasekara</dc:creator>
      <pubDate>Fri, 13 Jun 2025 14:51:22 +0000</pubDate>
      <link>https://dev.to/sureni-dhanasekara/advance-types-in-rust-35gg</link>
      <guid>https://dev.to/sureni-dhanasekara/advance-types-in-rust-35gg</guid>
      <description>&lt;p&gt;Rust is known for its powerful type system, which enables memory safety, concurrency, and zero-cost abstractions. Rust basic types like integers, boolean, and strings are straightforward, advanced types provide the foundation for writing expressive and safe code in complex systems.&lt;/p&gt;

&lt;p&gt;Most important advanced types in Rust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Algebraic Data Types (Enums &amp;amp; Structs)&lt;/li&gt;
&lt;li&gt;Type Aliases&lt;/li&gt;
&lt;li&gt;Newtypes&lt;/li&gt;
&lt;li&gt;PhantomData&lt;/li&gt;
&lt;li&gt;Dynamically Sized Types (DSTs)&lt;/li&gt;
&lt;li&gt;Trait Objects&lt;/li&gt;
&lt;li&gt;Function Pointers&lt;/li&gt;
&lt;li&gt;Never Type (!)&lt;/li&gt;
&lt;li&gt;Inferred and Generic Types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Algebraic Data Types (ADTs)&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Algebraic data types is a way to define complex data by combining simpler types.&lt;/p&gt;

&lt;p&gt;There are two main kinds of ADTs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Struct : combine multiple fields together&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    struct Person {
      name: String,
      age: u8,
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enum : define one of many possibilities&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    enum Shape {
      Circle(f64),
      Rectangle(f64, f64),
   }
&lt;/code&gt;&lt;/pre&gt;

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

&lt;p&gt;&lt;strong&gt;Newtypes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A newtype is just a tuple struct with one field which is used to create a new, distinct type from an existing 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 MyType(i32); 

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

&lt;/div&gt;



&lt;p&gt;Why Use Newtypes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type safety :two types with the same inner value not interchangeable, so you can’t accidentally pass Meters when Millimeters is expected.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Millimeters(u32);
struct Meters(u32);

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

&lt;/div&gt;



&lt;p&gt;Example without newtype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn print_length(length_mm: u32) {
    println!("Length is {} millimeters", length_mm);
}

let meters = 5; 
print_length(meters); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we passed 5 meters where the function expected millimeters. But Rust doesn’t catch this, because they’re both just &lt;code&gt;u32&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example with newtype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Millimeters(u32);
struct Meters(u32);

fn print_length(length_mm: Millimeters) {
       println!("Length is {} millimeters", length_mm.0);
}

let meters = Meters(5);
print_length(meters); // ❌ ERROR!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we run this then you will get a compile-time error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expected struct `Millimeters`, found struct `Meters`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Custom Trait Implementations: Rust doesn't let you implement foreign traits for foreign types that means you can't implement a trait like Display for a built-in type like Vec unless you own either the trait or the type. We can solve this issue with newtype.
&lt;/li&gt;
&lt;/ul&gt;

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

struct CommaSeparated(Vec&amp;lt;String&amp;gt;);

impl fmt::Display for CommaSeparated {
    fn fmt(&amp;amp;self, f: &amp;amp;mut fmt::Formatter) -&amp;gt; fmt::Result {
        write!(f, "{}", self.0.join(", "))
    }
}

fn main() {
    let names = CommaSeparated(vec!["Alice".into(), "Bob".into(), "Carol".into()]);
    println!("{}", names); // prints: Alice, Bob, Carol
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Encapsulation: Encapsulation means hiding internal details of a type and exposing only what’s necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a core idea in programming that helps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevent misuse&lt;/li&gt;
&lt;li&gt;Keep your codebase clean&lt;/li&gt;
&lt;li&gt;Make changes without breaking other code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Rust, this is done using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Private fields&lt;/li&gt;
&lt;li&gt;Public methods (getters/setters or controlled logic)
&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 Password(String); // type is public, field is private

impl Password {
    pub fn new(s: &amp;amp;str) -&amp;gt; Self {
        Password(s.to_string())
    }

    pub fn value(&amp;amp;self) -&amp;gt; &amp;amp;str {
        &amp;amp;self.0
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Type Aliases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A type alias in Rust lets you create a new name for an existing type - but it doesn't create a new, distinct type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Kilometers = i32;

fn main() {
    let distance: Kilometers = 5;
    let total: i32 = distance + 10; // Works — because Kilometers is just an alias for i32
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PhantomData&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PhantomData is a zero-sized marker type in Rust that's used to indicate that a type or lifetime parameter is logically "used" by your type, even though it doesn't actually contain any data of that type.&lt;/p&gt;

&lt;p&gt;Key Properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero-sized (no runtime overhead)&lt;/li&gt;
&lt;li&gt;Only used at compile time for type system purposes&lt;/li&gt;
&lt;li&gt;Doesn't affect runtime behavior&lt;/li&gt;
&lt;li&gt;Can be used with any combination of type and lifetime parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Dynamically Sized Types (DSTs)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Rust, most types must have a known size at compile time. But DSTs are types whose size is only known at runtime.&lt;/p&gt;

&lt;p&gt;Key Characteristics of DSTs : &lt;br&gt;
    - Size unknown at compile time&lt;br&gt;
    - Must always be used behind a pointer (&amp;amp;, Box, Rc, etc.)&lt;br&gt;&lt;br&gt;
    - Don't implement the Sized trait&lt;/p&gt;

&lt;p&gt;Common DSTs in Rust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slices ([T])
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let slice: &amp;amp;[i32] = &amp;amp;[1, 2, 3];  // DST - size depends on runtime length
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt; Trait Objects (dyn Trait)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let trait_obj: &amp;amp;dyn Display = &amp;amp;42;  // DST - size depends on concrete type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Structs with DST as last field
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct MyString {
    len: usize,
    data: [u8],  // DST as last field
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Never Type (!)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The ! type in Rust means "this function never returns".&lt;/p&gt;

&lt;p&gt;Key Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Diverging functions: Functions that never return have return type !&lt;/li&gt;
&lt;li&gt;Zero variants: The ! type has no possible values&lt;/li&gt;
&lt;li&gt;Subtype of all types: Can be coerced into any other type&lt;/li&gt;
&lt;li&gt;No runtime representation: Doesn't exist at runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Function That Panics - The return type is ! because this function never returns normally it always panics.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn crash() -&amp;gt; ! {
    panic!("Something went terribly wrong");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;An Infinite Loop
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn loop_forever() -&amp;gt; ! {
    loop {
        // runs forever
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Function Pointers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Function pointers in Rust allow you to store references to functions and pass them around like regular values. They're a fundamental building block for many advanced patterns like callbacks, plugins, and strategy patterns.&lt;/p&gt;

&lt;p&gt;Basic Function Pointer Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn add(a: i32, b: i32) -&amp;gt; i32 {
    a + b
}

fn main() {
    // Create a function pointer
    let operation: fn(i32, i32) -&amp;gt; i32 = add;

    // Use the function pointer
    let result = operation(2, 3);
    println!("Result: {}", result); // Prints "5"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type Signature: Function pointers have the type fn(T1, T2, ...) 
-&amp;gt; R where Tn are argument types and R is the return type&lt;/li&gt;
&lt;li&gt;Zero-Sized: They don't store any data, just point to code
&lt;/li&gt;
&lt;li&gt;Safe: Unlike raw pointers, function pointers are guaranteed to  point to valid functions&lt;/li&gt;
&lt;li&gt;No Capture: They can only point to functions, not closures that capture environment&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Rust Error Handling</title>
      <dc:creator>Sureni Dhanasekara</dc:creator>
      <pubDate>Wed, 30 Apr 2025 04:52:52 +0000</pubDate>
      <link>https://dev.to/sureni-dhanasekara/rust-error-handling-1ikb</link>
      <guid>https://dev.to/sureni-dhanasekara/rust-error-handling-1ikb</guid>
      <description>&lt;p&gt;Rust groups errors into two major categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recoverable errors&lt;/li&gt;
&lt;li&gt;unrecoverable error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recoverable Errors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When it is recoverable error then problem will report to the user and and retry the operation. This errors handle with the type Result since exception is not available in rust. &lt;/p&gt;

&lt;p&gt;Ex: File not found error&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unrecoverable Errors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unrecoverable errors are always symptoms of bugs. This errors handle with the &lt;code&gt;panic!&lt;/code&gt; macro and it will stop execution.&lt;/p&gt;

&lt;p&gt;Ex: trying to access a location beyond the end of an array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recoverable Errors with Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result enum is defined as having two variants, Ok and Err, as follows:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This T and E mention in here &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; are generic type parameters.&lt;br&gt;
T represent the type of value that will be return in success case and E represent the type of value that will be return in error/failure case.&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::fs::File; 
fn main() { 
    let f:u32 = File::open("program.txt"); 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; error[E0308]: mismatched types
 --&amp;gt; src/main.rs:4:18
  |
 4 |     let f: u32 = File::open("hello.txt");
  |                  ^^^^^^^^^^^^^^^^^^^^^^^ expected u32, found enum 
`std::result::Result`
  |
  = note: expected type `u32`
             found type `std::result::Result&amp;lt;std::fs::File, std::io::Error&amp;gt;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can modify code as follows to handle error:&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::fs::File;
use std::io::Error;

fn main() {
    let f = File::open("program.txt");
    match f {
        Ok(_file) =&amp;gt; println!("File opened successfully"),
        Err(e) =&amp;gt; println!("Error opening file: {}", e),
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Unrecoverable Errors with panic!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the &lt;code&gt;panic!&lt;/code&gt; macro executes, your program will print a failure message, unwind and clean up the stack, and then quit.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;unwind&lt;/em&gt; - Rust walks back up the stack and cleans up the data from each function it encounters.&lt;br&gt;
&lt;em&gt;abort&lt;/em&gt; - Ends the program without cleaning up. Memory that the program was using will then need to be cleaned up by the operating system.&lt;/p&gt;

&lt;p&gt;if you are using &lt;code&gt;abort&lt;/code&gt; then need to do modification in &lt;code&gt;Cargo.toml&lt;/code&gt; as follows:&lt;br&gt;
&lt;code&gt;panic = 'abort'&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;fn main() {
    panic!("This is an unrecoverable error!");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compiling testing v0.1.0 (C:\Users\Sanija Methsen\Desktop\Rust\my-projects\testing)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.93s
     Running `target\debug\testing.exe`

thread 'main' panicked at src\main.rs:2:5:
This is an unrecoverable error!
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\testing.exe` (exit code: 101)
PS C:\Users\Sanija Methsen\Desktop\Rust\my-projects\testing&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Using a panic! Backtrace&lt;/strong&gt;&lt;br&gt;
A backtrace is a detailed report showing the sequence of function calls that occurred before the panic, which is extremely helpful for debugging.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable full backtraces:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For Linux/Mac (Bash/Zsh):
RUST_BACKTRACE=1 cargo run

For Windows Command Prompt (CMD):
set RUST_BACKTRACE=1
cargo run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
Running `target\debug\testing.exe`

thread 'main' panicked at src\main.rs:2:5:
This is an unrecoverable error!
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\testing.exe` (exit code: 101)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enable full backtraces with more details:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For Linux/Mac (Bash/Zsh):
RUST_BACKTRACE=full cargo run

For Windows Command Prompt (CMD):
set RUST_BACKTRACE=full
cargo run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compiling testing v0.1.0 (C:\Users\Sanija Methsen\Desktop\Rust\my-projects\testing)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.10s
     Running `target\debug\testing.exe`

thread 'main' panicked at src\main.rs:2:5:
This is an unrecoverable error!
stack backtrace:
   0:     0x7ff767896511 - std::backtrace_rs::backtrace::win64::trace
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\..\..\backtrace\src\backtrace\win64.rs:85
   1:     0x7ff767896511 - std::backtrace_rs::backtrace::trace_unsynchronized
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66
   2:     0x7ff767896511 - std::sys::backtrace::_print_fmt
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\sys\backtrace.rs:66
   3:     0x7ff767896511 - std::sys::backtrace::impl$0::print::impl$0::fmt
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\sys\backtrace.rs:39
   4:     0x7ff7678a299a - core::fmt::rt::Argument::fmt
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\core\src\fmt\rt.rs:177
   5:     0x7ff7678a299a - core::fmt::write
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\core\src\fmt\mod.rs:1449
   6:     0x7ff7678948e7 - std::io::Write::write_fmt&amp;lt;std::sys::pal::windows::stdio::Stderr&amp;gt;
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\io\mod.rs:1890
   7:     0x7ff767896355 - std::sys::backtrace::BacktraceLock::print
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\sys\backtrace.rs:42
   8:     0x7ff767897892 - std::panicking::default_hook::closure$0
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\panicking.rs:298
   9:     0x7ff767897683 - std::panicking::default_hook
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\panicking.rs:325
  10:     0x7ff76789837f - std::panicking::rust_panic_with_hook
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\panicking.rs:831
  11:     0x7ff7678981d2 - std::panicking::begin_panic_handler::closure$0
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\panicking.rs:697
  12:     0x7ff767896c4f - std::sys::backtrace::__rust_end_short_backtrace&amp;lt;std::panicking::begin_panic_handler::closure_env$0,never$&amp;gt;
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\sys\backtrace.rs:168
  13:     0x7ff767897e0e - std::panicking::begin_panic_handler
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\panicking.rs:695
  14:     0x7ff7678a7551 - core::panicking::panic_fmt
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\core\src\panicking.rs:75
  15:     0x7ff76789118b - testing::main
                               at C:\Users\Sanija Methsen\Desktop\Rust\my-projects\testing\src\main.rs:2
  16:     0x7ff76789106b - core::ops::function::FnOnce::call_once&amp;lt;void (*)(),tuple$&amp;lt;&amp;gt; &amp;gt;
                               at C:\Users\Sanija Methsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
  17:     0x7ff76789113e - core::hint::black_box
                               at C:\Users\Sanija Methsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\hint.rs:477   
  18:     0x7ff76789113e - std::sys::backtrace::__rust_begin_short_backtrace&amp;lt;void (*)(),tuple$&amp;lt;&amp;gt; &amp;gt;
                               at C:\Users\Sanija Methsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\sys\backtrace.rs:152
  19:     0x7ff767891121 - std::rt::lang_start::closure$0&amp;lt;tuple$&amp;lt;&amp;gt; &amp;gt;
                               at C:\Users\Sanija Methsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:199      
  20:     0x7ff767892d5c - std::rt::lang_start_internal::closure$0
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\rt.rs:168
  21:     0x7ff767892d5c - std::panicking::try::do_call
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\panicking.rs:587
  22:     0x7ff767892d5c - std::panicking::try
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\panicking.rs:550
  23:     0x7ff767892d5c - std::panic::catch_unwind
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\panic.rs:358
  24:     0x7ff767892d5c - std::rt::lang_start_internal
                               at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\rt.rs:164
  25:     0x7ff76789110a - std::rt::lang_start&amp;lt;tuple$&amp;lt;&amp;gt; &amp;gt;
                               at C:\Users\Sanija Methsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:198      
  26:     0x7ff7678911a9 - main
  27:     0x7ff7678a5ec0 - invoke_main
                               at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
  28:     0x7ff7678a5ec0 - __scrt_common_main_seh
                               at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
  29:     0x7ffe69e0259d - BaseThreadInitThunk
  30:     0x7ffe6b14af38 - RtlUserThreadStart
error: process didn't exit successfully: `target\debug\testing.exe` (exit code: 101)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Disable backtraces:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For Linux/Mac (Bash/Zsh):
RUST_BACKTRACE=0 cargo run

For Windows Command Prompt (CMD):
set RUST_BACKTRACE=0
cargo run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thread 'main' panicked at 'Test panic', src\main.rs:2:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Unwrap and expect&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;unwrap&lt;/code&gt; will return the value inside the Ok. If the Result is the Err variant, unwrap will call the panic! macro for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let num = "42".parse::&amp;lt;i32&amp;gt;().unwrap(); // Panics on Err
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;expect&lt;/code&gt; instead of &lt;code&gt;unwrap&lt;/code&gt; and providing good error messages can convey your intent and make tracking down the source of a panic easier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let num = "42".parse::&amp;lt;i32&amp;gt;().expect("Parsing failed"); // Panics with custom message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Propagating Errors&lt;/strong&gt;&lt;br&gt;
Error propagation is a fundamental concept in Rust that allows errors to be passed up the call stack to be handled by calling functions. The ? operator is Rust's primary mechanism for error propagation:&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::fs;
use std::io;

fn read_config() -&amp;gt; Result&amp;lt;String, io::Error&amp;gt; {
    let content = fs::read_to_string("config.toml")?;
    Ok(content)
}

fn main() -&amp;gt; Result&amp;lt;(), io::Error&amp;gt; {
    let config = read_config()?;
    println!("Config: {}", config);
    Ok(())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Helpful Crates&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;thiserror&lt;/code&gt;: For defining library error types&lt;br&gt;
&lt;code&gt;anyhow&lt;/code&gt;: For application error handling&lt;br&gt;
&lt;code&gt;snafu&lt;/code&gt;: Alternative error handling with backtraces&lt;br&gt;
&lt;code&gt;miette&lt;/code&gt;: Fancy diagnostic error reporting&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Testing Rust</title>
      <dc:creator>Sureni Dhanasekara</dc:creator>
      <pubDate>Tue, 29 Apr 2025 11:41:26 +0000</pubDate>
      <link>https://dev.to/sureni-dhanasekara/testing-rust-2b2i</link>
      <guid>https://dev.to/sureni-dhanasekara/testing-rust-2b2i</guid>
      <description>&lt;p&gt;The two pillars of rust are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;speed&lt;/li&gt;
&lt;li&gt;safety&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rust built in safety features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Borrow checker&lt;/li&gt;
&lt;li&gt;Type system&lt;/li&gt;
&lt;li&gt;Pattern matching&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Borrow checker&lt;/em&gt;&lt;/strong&gt; &lt;br&gt;
The borrow checker is an useful feature of the Rust language. It helps to manage ownership.&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 s1:String = String::from("Hello Rust");
    let s2: String = s1;

    println!("string is : {}", s1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we run this main then it will provide error like follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0382]: borrow of moved value: `s1`
 --&amp;gt; src\main.rs:5:32
  |
2 |     let s1:String = String::from("Hello Rust");
  |         -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
3 |     let s2: String = s1;
  |                      -- value moved here
4 |
5 |     println!("string is : {}", s1);
  |                                ^^ value borrowed here after move
  |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;Type system&lt;/strong&gt;&lt;/em&gt; &lt;br&gt;
Rust type system is designed to guarantee safety and performance in your programs.&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%2Fhk03q5sqn9lb66vsh1n6.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%2Fhk03q5sqn9lb66vsh1n6.jpg" alt="image of type statems" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rust's type system is one of its most powerful features, providing safety, expressiveness, and performance in your programs. Core characteristics of rust are:&lt;br&gt;
       - Statically typed: All types are known at compile time.&lt;br&gt;
       - Strongly typed: No implicit type conversions.&lt;br&gt;
       - Type inference: Compiler can often deduce types.&lt;br&gt;
       - Zero-cost abstractions: High-level constructs compile to &lt;br&gt;
          efficient low-level code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic types of rust are:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Scalar Types&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Integers: i8, i16, i32, i64, i128, isize (signed); u8, 
       u16, u32, u64, u128, usize (unsigned)&lt;/li&gt;
&lt;li&gt;Floats: f32, f64&lt;/li&gt;
&lt;li&gt;Boolean: bool (true/false)&lt;/li&gt;
&lt;li&gt;Character: char&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compound Types&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tuples: Fixed-size, heterogeneous collections&lt;/li&gt;
&lt;li&gt;Arrays: Fixed-size, homogeneous collections&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Custom Types&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Structs&lt;/li&gt;
&lt;li&gt;Enums&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Pattern matching&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Pattern matching enables you to match and destructure data according to its type, structure, or other attributes. It offers a clear and expressive approach to handling various situations and reaching conclusions in light of them. Because of Rust's thorough pattern matching, you must take into consideration every potential pattern to guarantee that your code is comprehensive and error-free.&lt;/p&gt;

&lt;p&gt;Rust's Standard Library gives us three assertion macros that helps us build our testing scenarios.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assert! - evaluates a specific condition, which passes the test if 
        that condition is true, and triggers a failure with a panic 
        if that condition is false.&lt;/li&gt;
&lt;li&gt;assert_eq! - compares two values for equality, passing the test if 
           they're equal and detailing the discrepancy if they're 
           not.&lt;/li&gt;
&lt;li&gt;assert_ne! - checks for inequality between two values, passing the 
           test if they are unequal and detailing if they are equal.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn add(left: u64, right: u64) -&amp;gt; u64 {
    left + right
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let result = add(2, 2);
        assert_eq!(result, 4);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;we can run test by &lt;code&gt;cargo test&lt;/code&gt;. The it will give output as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Compiling rust_testing v0.1.0 (C:\Users\Sanija Methsen\Desktop\Rust\my-projects\rust_testing)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 3.32s
     Running unittests src\lib.rs (target\debug\deps\rust_testing-7cd7699070227f78.exe)

running 1 test
test tests::it_works ... ok

successes:

successes:
    tests::it_works

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if the answer is not correct then it'll display failed message in terminal&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 add(left: u64, right: u64) -&amp;gt; u64 {
    left + right
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let result = add(10, 2);
        assert_eq!(result, 4);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---- tests::it_works stdout ----

thread 'tests::it_works' panicked at src\lib.rs:12:9:
assertion `left == right` failed
  left: 12
 right: 4
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    tests::it_works

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust have the option to tag along a custom message with the failure alert whenever you use the assert!, the assert_eq!, or the assert_ne! macros.&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 sum(left: u64, right: u64) -&amp;gt; u64 {
    left + right
}

pub fn subtract(left: u64, right: u64) -&amp;gt; u64 {
    left - right
}

pub fn is_even(num:i32) -&amp;gt; bool {
    num % 2 == 0
}


#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_sum() {
        assert_eq!(4, sum(2, 2), "calculating sum failed");
    }

    #[test]
    fn test_subtract() {
        assert_eq!(4, subtract(6, 2), "calculating subtraction failed");
    }

    #[test]
    fn test_is_even() {
        assert!(is_even(3), "number is not even");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS C:\Users\Sanija Methsen\Desktop\Rust\my-projects\rust_testing&amp;gt; cargo test
   Compiling rust_testing v0.1.0 (C:\Users\Sanija Methsen\Desktop\Rust\my-projects\rust_testing)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 1.64s
     Running unittests src\lib.rs (target\debug\deps\rust_testing-7cd7699070227f78.exe)

running 3 tests
test tests::test_is_even ... FAILED
test tests::test_subtract ... FAILED
test tests::test_sum ... FAILED

failures:

---- tests::test_is_even stdout ----

thread 'tests::test_is_even' panicked at src\lib.rs:30:9:
number is not even
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- tests::test_subtract stdout ----

thread 'tests::test_subtract' panicked at src\lib.rs:25:9:
assertion `left == right` failed: calculating subtraction failed
  left: 4
 right: 3

---- tests::test_sum stdout ----

thread 'tests::test_sum' panicked at src\lib.rs:20:9:
assertion `left == right` failed: calculating sum failed
  left: 4
 right: 5


failures:
    tests::test_is_even
    tests::test_subtract
    tests::test_sum

test result: FAILED. 0 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a anothor marco for testing. That is &lt;code&gt;panic!&lt;/code&gt;. This verifies that function panics as expected during testing, and checks that the panic message matches specific text.&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 divide(num1:i32, num2:i32) -&amp;gt; i32 {
    if num2 == 0 {
        panic!("divide by zero not allowed");
    }
    num1 / num2
}

#[test]
#[should_panic(expected="Divide by zero not allowed")]
fn test_check_divide() {
   divide(10, 0);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;running 1 test
test tests::test_check_divide - should panic ... ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if &lt;code&gt;#[should_panic(expected="Divide by zero not allowed")]&lt;/code&gt; not included  to test function then it will throw an error. If we use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; #[test]
    #[should_panic(expected="Divide by zero not allowed")]
    fn test_check_divide() {
        divide(10, 2);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then test will be fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;running 1 test
test tests::test_check_divide - should panic ... FAILED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Result type&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Using result type in testing is one clever way to handle success and failure events in tests.&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 is_even(num:i32) -&amp;gt; bool {
    num % 2 == 0
}

#[test]
fn test_even_number() -&amp;gt; Result&amp;lt;(), String&amp;gt; {
    if is_even(4) {
        Ok(())
    } else {
        Err(String::from("Expected 4 to be even"))
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;running 1 test
test tests::test_even_number ... ok

successes:

successes:
    tests::test_even_number

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Test Attributes&lt;/strong&gt;&lt;br&gt;
    &lt;code&gt;#[test]&lt;/code&gt;        - Indicates a function is a test to be run. This function takes no arguments.&lt;br&gt;
    &lt;code&gt;#[bench]&lt;/code&gt;       - Indicates a function is a benchmark to be run. This function takes one argument (test::Bencher).&lt;br&gt;
    &lt;code&gt;#[should_panic]&lt;/code&gt; - This function (also labeled with &lt;code&gt;#[test]&lt;/code&gt;) will only pass if the code causes a panic (an assertion failure or panic!) A message may be provided, which the failure string must contain: &lt;br&gt;
&lt;code&gt;#[should_panic(expected = "foo")]&lt;/code&gt;.&lt;br&gt;
    &lt;code&gt;#[ignore]&lt;/code&gt;- When applied to a function which is already attributed as a test, then the test runner will ignore these tests during normal test runs. Running with --ignored or --include-ignored will run these tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit tests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unit tests are essential elements of Rust's testing framework. They are the primary lines of defense against bugs. They're quick to write, quick to run, and they zero in on the smallest part of our system, our functions and our methods. So their speed and precision make them ideal for very quick iterations, allowing us to confirm that each piece of our code operates exactly as intended. Unit tests are just as important in binary applications as they are in libraries.The standard practice is that you put these test functions in a test module inside each file and you annotate the module with &lt;code&gt;cfg&lt;/code&gt; test. &lt;code&gt;cfg&lt;/code&gt; test attribute is Rust's way of optimizing the testing process. So when we append this attribute to a module, we're telling Rust to compile and execute the code exclusively when we run cargo test not when you run cargo build.&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 tests {
    use super::*;
    #[test]
    #[should_panic]
    fn greater_than_100() {
        Guess::new(200);
    }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Running single test&lt;/strong&gt;&lt;br&gt;
 We can pass the name of any test function to cargo test to run only that test:&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 tests {
    use super::*;
    #[test]
    fn add_two_and_two() {
        assert_eq!(4, add_two(2));
    }
    #[test]
    fn add_three_and_two() {
        assert_eq!(5, add_two(3));
    }
    #[test]
    fn one_hundred() {
        assert_eq!(102, add_two(100));
    }
 }

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

&lt;/div&gt;



&lt;p&gt;Run the test:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ cargo test one_hundred&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filtering to Run Multiple Tests&lt;/strong&gt;&lt;br&gt;
 We can specify part of a test name, and any test whose name matches that value will be run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; $ cargo test add
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running target/debug/deps/adder-06a75b4a1f2515e9
 running 2 tests
 test tests::add_two_and_two ... ok
 test tests::add_three_and_two ... ok
 test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Integration tests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Integration tests are conducted outside of your library. They can only call functions included in your library's public API since they use it in the same manner as any other code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; extern crate adder;
 #[test]
 fn it_adds_two() {
    assert_eq!(4, adder::add_two(2));
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mocking&lt;/strong&gt;&lt;br&gt;
Mocking is a practice in unit testing. In mocking, you create fake objects, called mocks, from real objects for testing purposes. These mocks simulate the behavior of the real object as much as it needs to. is this correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reasons for Mocking&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control over test environment&lt;/li&gt;
&lt;li&gt;Isolation of components for unit testing&lt;/li&gt;
&lt;li&gt;Improved test stability and reliability&lt;/li&gt;
&lt;li&gt;Efficiency and speed&lt;/li&gt;
&lt;li&gt;Enabling testing of unavailable or incomplete components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;mockall&lt;/code&gt; crate is most popular mocking library in the Rust ecosystem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
mockall = "0.11"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use mockall::{automock, predicate::*};

#[automock]
pub trait Adder {
    fn add(&amp;amp;self, a: i32, b: i32) -&amp;gt; i32;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn add_with_logger(adder: &amp;amp;dyn Adder, a: i32, b: i32) -&amp;gt; i32 {
    let result = adder.add(a, b);
    println!("Adding {} + {} = {}", a, b, result);
    result
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





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

    #[test]
    fn test_add_with_logger() {
        let mut mock = MockAdder::new();
        mock.expect_add()
            .with(eq(2), eq(3))
            .returning(|a, b| a + b);

        let result = add_with_logger(&amp;amp;mock, 2, 3);
        assert_eq!(result, 5);
    }
}

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

&lt;/div&gt;



</description>
      <category>rust</category>
      <category>testing</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Understanding Rust Ownership</title>
      <dc:creator>Sureni Dhanasekara</dc:creator>
      <pubDate>Tue, 22 Apr 2025 10:35:25 +0000</pubDate>
      <link>https://dev.to/sureni-dhanasekara/understanding-rust-ownership-30i4</link>
      <guid>https://dev.to/sureni-dhanasekara/understanding-rust-ownership-30i4</guid>
      <description>&lt;p&gt;ownership is a core concept that determines how memory is managed at runtime, guaranteeing memory safety without needing a garbage collector. Each value in Rust has a single owner (a variable), and when the owner goes out of scope, the value is dropped (memory is freed). This system prevents memory leaks and dangling pointers by ensuring that there's always a clear responsibility for cleaning up memory&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ownership Rules&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each value in Rust has a variable that’s called its owner.&lt;/li&gt;
&lt;li&gt;There can be only one owner at a time.&lt;/li&gt;
&lt;li&gt;When the owner goes out of scope, the value will be dropped.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example: Ownership Transfer&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;fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // Ownership moves from s1 to s2

    println!("{}", s1); // ❌ ERROR: s1 is no longer valid
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;reason for S1 is not valid is String is heap-allocated, and Rust moves ownership to avoid double-free errors. But if you want to keep  both s1 and s2 are valid then can use &lt;code&gt;clone&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 s1 = String::from("hello");
let s2 = s1.clone(); // now both s1 and s2 are valid

println!("{}", s1); 
println!("{}", s2); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ownership can be returned&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;fn give_ownership() -&amp;gt; String {
    String::from("Rust")
}

fn main() {
    let s = give_ownership(); // s gets ownership
    println!("{}", s);        // Works fine
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or pass in a value and return it back&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn take_and_return(s: String) -&amp;gt; String {
    s // return ownership
}

fn main() {
    let name = String::from("Rust");
    let name = take_and_return(name); // ownership moves and returns
    println!("{}", name); // Still valid
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Copy Types vs Move Types&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple types like integers are Copy types (stack-based):&lt;/li&gt;
&lt;li&gt;Complex types like String, Vec, etc., are Move types (heap-based).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;simple scalar values can be Copy, and nothing that requires allocation or is some form of resource is Copy. Here are some of the types that are Copy:&lt;/p&gt;

&lt;p&gt;•    All the integer types, such as u32.&lt;br&gt;
 •    The Boolean type, bool, with values true and false.&lt;br&gt;
 •    The character type, char.&lt;br&gt;
 •    All the floating point types, such as f64.&lt;br&gt;
 •    Tuples, but only if they contain types that are also Copy. For example, (i32, i32) is Copy, but (i32, String) is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References and Borrowing&lt;/strong&gt;&lt;br&gt;
In Rust, borrowing is when you let someone use a value without taking ownership.&lt;/p&gt;

&lt;p&gt;Instead of moving ownership (which makes the original variable unusable), you can borrow it using references.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn print_name(name: &amp;amp;String) {
    println!("Name: {}", name);
}

fn main() {
    let name = String::from("martin");
    print_name(&amp;amp;name);       // borrowed using &amp;amp; (immutable reference)
    println!("{}", name);    // still usable here
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Types of Borrowing&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Immutable Borrow (&amp;amp;T)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows read-only access&lt;/li&gt;
&lt;li&gt;Any number of immutable borrows allowed at the same time
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn show(val: &amp;amp;String) {
    println!("Value: {}", val);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Mutable Borrow (&amp;amp;mut T)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows write access&lt;/li&gt;
&lt;li&gt;Only one mutable borrow is allowed at a time
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn change(val: &amp;amp;mut String) {
    val.push_str(" Rocks!");
}

fn main() {
    let mut msg = String::from("Rust");
    change(&amp;amp;mut msg);           // mutable borrow
    println!("{}", msg);        // Rust Rocks!
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Borrowing Rules&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can have either one mutable reference or any number of immutable references, but not both at the same time&lt;/li&gt;
&lt;li&gt;References must always be valid (no dangling pointers!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Borrowing Matters&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rust avoids data races and null/dangling pointers&lt;/li&gt;
&lt;li&gt;You don’t need to manually manage memory&lt;/li&gt;
&lt;li&gt;It prevents bugs at compile time, not at runtime&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>learning</category>
      <category>developer</category>
    </item>
    <item>
      <title>Rust Generics and Traits</title>
      <dc:creator>Sureni Dhanasekara</dc:creator>
      <pubDate>Sun, 20 Apr 2025 12:10:44 +0000</pubDate>
      <link>https://dev.to/sureni-dhanasekara/rust-generics-and-traits-5694</link>
      <guid>https://dev.to/sureni-dhanasekara/rust-generics-and-traits-5694</guid>
      <description>&lt;p&gt;Generics allows you to write versatile and reusable codes which are in multiple types without duplications. Simply Instead of writing separate functions for i32, f64, and String, you write one generic function that works with all of them. They are denoted by angle brackets (&amp;lt;&amp;gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Use Generics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Code reusability&lt;/em&gt;&lt;/strong&gt;: Write once, use for any type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Type safety&lt;/em&gt;&lt;/strong&gt;: Compiler checks for correct types at compile time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Performance&lt;/em&gt;&lt;/strong&gt;: No runtime overhead &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Problem Example: Finding the Largest Item in a List&lt;/em&gt;&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;Without generics, your code looks like this:

fn largest_i32(list: &amp;amp;[i32]) -&amp;gt; &amp;amp;i32 {
    let mut largest = &amp;amp;list[0];

    for item in list {
        if item &amp;gt; largest {
            largest = item;
        }
    }

    largest
}

fn largest_char(list: &amp;amp;[char]) -&amp;gt; &amp;amp;char {
    let mut largest = &amp;amp;list[0];

    for item in list {
        if item &amp;gt; largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest_i32(&amp;amp;number_list);
    println!("The largest number is {result}");

    let char_list = vec!['y', 'm', 'a', 'q'];

    let result = largest_char(&amp;amp;char_list);
    println!("The largest char is {result}");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here we can see it duplicated code for largest_i32 and largest_char. We can use generics in this code like as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Rewriting with Generics&lt;/em&gt;&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;fn largest&amp;lt;T&amp;gt;(list: &amp;amp;[T]) -&amp;gt; &amp;amp;T {
    let mut largest = &amp;amp;list[0];

    for item in list {
        if item &amp;gt; largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest(&amp;amp;number_list);
    println!("The largest number is {result}");

    let char_list = vec!['y', 'm', 'a', 'q'];

    let result = largest(&amp;amp;char_list);
    println!("The largest char is {result}");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;T: PartialOrd is a trait bound that ensures the type supports comparison using &amp;gt;.&lt;/p&gt;

&lt;p&gt;This function now works for i32, char, and any type implementing PartialOrd.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Where Are Generic Types Used?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn identity&amp;lt;T&amp;gt;(x: T) -&amp;gt; T {
    x
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Structs
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;Enums
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum Option&amp;lt;T&amp;gt; {
    Some(T),
    None,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Traits &amp;amp; Implementations
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl&amp;lt;T: std::fmt::Debug&amp;gt; Point&amp;lt;T&amp;gt; {
    fn show(&amp;amp;self) {
        println!("{:?}, {:?}", self.x, self.y);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Methods With Multiple Generics
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Pair&amp;lt;T, U&amp;gt; {
    first: T,
    second: U,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Monomorphization&lt;/strong&gt;&lt;br&gt;
Rust uses a process called monomorphization during compilation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For each concrete type used with a generic, it generates a version of the function or struct for that type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This means no runtime overhead, unlike Java or C++ templates.&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;Generic Function:
fn identity&amp;lt;T&amp;gt;(x: T) -&amp;gt; T

Used with:
- identity(10)
- identity("hello")

→ Compiler generates:
- fn identity_i32(x: i32) -&amp;gt; i32
- fn identity_str(x: &amp;amp;str) -&amp;gt; &amp;amp;str
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;What Are Traits?&lt;/strong&gt;&lt;br&gt;
In Rust, traits are like interfaces in other languages. They define behavior that types can implement. Traits help constrain generics to ensure type safety and functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Defining and Implementing Traits&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;trait Greet {
    fn greet(&amp;amp;self) -&amp;gt; String;
}

struct Person;

impl Greet for Person {
    fn greet(&amp;amp;self) -&amp;gt; String {
        "Hello!".to_string()
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Default Implementations&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;trait Farewell {
    fn goodbye(&amp;amp;self) -&amp;gt; String {
        "Goodbye!".to_string()
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Using where Clauses for Readability&lt;/strong&gt;&lt;br&gt;
Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn process&amp;lt;T: Greet, U: Farewell&amp;gt;(t: T, u: U)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn process&amp;lt;T, U&amp;gt;(t: T, u: U)
where
    T: Greet,
    U: Farewell,
{
    println!("{} {}", t.greet(), u.goodbye());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Common Mistakes with Generics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Forgetting Trait Bounds&lt;br&gt;
If you try to compare or print generic types without proper trait bounds like PartialOrd, Debug, or Display, you'll get compiler errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Overcomplicating Generics&lt;br&gt;
Not everything needs to be generic. Use when there's clear duplication or type flexibility needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type Inference Limits&lt;br&gt;
Sometimes the compiler can't infer the type, especially in complex chains. You might need to explicitly annotate types.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>rust</category>
      <category>generic</category>
    </item>
    <item>
      <title>Understanding Crates in Rust</title>
      <dc:creator>Sureni Dhanasekara</dc:creator>
      <pubDate>Sat, 19 Apr 2025 11:36:14 +0000</pubDate>
      <link>https://dev.to/sureni-dhanasekara/understanding-crates-in-rust-1amj</link>
      <guid>https://dev.to/sureni-dhanasekara/understanding-crates-in-rust-1amj</guid>
      <description>&lt;p&gt;Crate is a compilation unit which serve as packages of rust code. This can be reused, share and publish.  Whether you're consuming powerful third-party libraries or crafting your own, understanding crates is essential to becoming an effective Rustacean. With a vibrant ecosystem and a robust toolchain, Rust crates allow developers to build fast, reliable, and modern software one crate at a time. Crates are not just an organizational tool they define how your code is compiled and reused.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Reusable&lt;/em&gt;&lt;/strong&gt;  : Once you write a crate (especially a library 
crate), it can be used in multiple projects.
  &lt;em&gt;Example&lt;/em&gt; - You write a math_utils crate with useful math 
       functions. You can then use that same crate in other projects 
       or even publish it for others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Shareable&lt;/em&gt;&lt;/strong&gt; : Using tools like crates.io, you can share your crate with the entire Rust ecosystem. Others can add your crate as a dependency and start using it instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Modular&lt;/em&gt;&lt;/strong&gt; : A crate helps break your project into smaller logical components.Instead of one giant file, you can create organized modules and expose only what’s necessary to users of your crate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Scalable&lt;/em&gt;&lt;/strong&gt; : Large applications in Rust are often made up of multiple crates, sometimes managed using a workspace.This allows teams to build and test parts of the project independently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two primary types of crates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Binary crate&lt;/em&gt;&lt;/strong&gt; - This Produce an executable program. They have an entry point (fn main()). This is the default crate. When we use &lt;code&gt;rustc main.rs&lt;/code&gt; then it treated as binary crate. When create project by using cargo (Rust’s build system and dependency manager) it default create binary crate.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo new my_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Library crate&lt;/em&gt;&lt;/strong&gt; - Provide functionality to be used by other crates. They don’t have a main() function. We can use &lt;code&gt;--crate-type lib&lt;/code&gt; to convert binary crate to library crate. If you want to create project with library crate  use following code.
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;p&gt;Crates can be reused across projects, and the Rust community shares tens of thousands of crates via &lt;a href="https://dev.tourl"&gt;crates.io&lt;/a&gt;(The official registry for Rust crates), the official package registry.One such crate is &lt;a href="https://crates.io/crates/holiday_checker" rel="noopener noreferrer"&gt;holiday-checker&lt;/a&gt;, which I published to help developers easily check for holidays in their applications. You can find the source code on &lt;a href="https://github.com/surenidh/rust/tree/holiday-crate/holiday_checker" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To use an external crate, add it to your Cargo.toml under [dependencies]:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
rand = "0.8"    # Use the rand crate for randomness
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then add it to your code:&lt;br&gt;
&lt;/p&gt;

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

fn main() {
    let mut rng = rand::thread_rng();
    let n: u8 = rng.gen_range(1..=10);
    println!("Random number: {}", n);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust crates support unit and integration testing natively. Inside any crate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/lib.rs
pub fn add(a: i32, b: i32) -&amp;gt; i32 {
    a + b
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run tests with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can share your crate with the world by publishing it to crates.io:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create an account on crates.io&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add metadata to Cargo.toml:&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;[package]
name = "my_crate"
version = "0.1.0"
authors = ["Your Name &amp;lt;you@example.com&amp;gt;"]
edition = "2021"
license = "MIT OR Apache-2.0"
description = "A useful utility library"
repository = "https://github.com/your/repo"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Authenticate:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo login &amp;lt;your-api-token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Publish:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;holiday-checker crate : &lt;a href="https://crates.io/crates/holiday_checker" rel="noopener noreferrer"&gt;https://crates.io/crates/holiday_checker&lt;/a&gt;&lt;br&gt;
GitHub Repo : &lt;a href="https://github.com/surenidh/rust/tree/holiday-crate/holiday_checker" rel="noopener noreferrer"&gt;https://github.com/surenidh/rust/tree/holiday-crate/holiday_checker&lt;/a&gt;&lt;/p&gt;

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