0% found this document useful (0 votes)
42 views43 pages

DailyCode 20

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views43 pages

DailyCode 20

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 43

09/06/2024, 16:00 DailyCode

Preface
Phrase #1

Phrase #2

Phrase #3

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 1/43
09/06/2024, 16:00 DailyCode

Syllabus

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 2/43
09/06/2024, 16:00 DailyCode

Why rust? Isn’t Node.js enough?


Type safety
Javascript

Rust

💡 Typescript was introduced to get rid of some of these problems in JS


Systems language
It is intended to be used (but not restricted to) to do lower level things
1. Building a Compiler
2. Building a browser
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 3/43
09/06/2024, 16:00 DailyCode

3. Working closer to the OS/kernel

Generally faster
Rust has a separate compilation step (similar to C++) that spits out an optimised binary and
does a lot of static analysis at compile time.
JS does JIT compilation.

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 4/43
Concurrency
09/06/2024, 16:00 DailyCode

Rust has built-in support for concurrent programming allowing multiple threads to perform
tasks simultaneously without risking data races
Javascript is single threaded generally (there are some projects that tried making it multi
threaded but rarely used)

Memory safe
Rust has a concept of owners, borrowing and lifetimes that make it extremely memory safe

💡 Rust doesn't hide complexity from developers it offers them the right tools to manage
all the complexity.

Initializing rust locally


Rust projects can be used to do a lot of things
1. Create Backend for a Full stack app
2. Create CLIs (command line interfaces)
3. Create browsers
4. Great Code Editors

For this bootcamp, we’ll be getting comfortable with the syntax of Rust.
For most of the video, a repl.it playground should be good enough https://replit.com/~

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 5/43
09/06/2024, 16:00 DailyCode

But it’s generally a good idea to start projects locally


Best place to find how to install it - https://www.rust-lang.org/tools/install
By the end of it, you should be able to run cargo in your terminal.
If not, it means you have an installation issue

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 6/43
09/06/2024, 16:00 DailyCode

Initializing a rust project


Run the following command to bootstrap a simple Rust project
Copy
mkdir rust-project
cd rust-project
cargo init

lib vs application
Application

💡 Cargo is similar to npm . It’s a package manager for rust

By default, a rust application gets initialised


It means an end user app that actually executes independently. Spits out a binary when
compiled
Lib
Copy
cargo init --lib

This would initialize a library that you can deploy for other people to use

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 7/43
09/06/2024, 16:00 DailyCode

VSCode setup + Hello world


1. Open the project in VSCode
2. Install the rust-analyser Extension

Optional extensions - CodeLLDB, toml


Hello world program
Rust code

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 8/43
09/06/2024, 16:00 DailyCode

Equivalent Javascript code


Copy
function main() {
console.log("Hello world")
}

main();

Simple Variables in rust


Before we write any more code, let’s quickly discuss variables so we can understand some
rust concepts before we get into the meat of the code
You can define variables using the let keyword (very similar to JS)
You can assign the type of the variable, or it can be inferred as well.
1. Numbers
Copy
fn main() {
let x: i32 = 1;
println!("{}", x);
}

💡 Ignore how the printing is happening right now, we’ll come to it later
Equivalent typescript code
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 9/43
09/06/2024, 16:00 DailyCode

Copy
function main() {
let x: number = 1;
console.log(x);
}

main()

What happens if we overflow?


Copy
fn main() {
let mut num: i8 = 124;
for i in 0..100 {
num += 127;
}
print!("Number: {}", num)
}

2. Booleans
Bools can have two states, true or false
Copy
fn main() {
let is_male = false;
let is_above_18 = true;

if is_male {
println!("You are a male");

} else {
println!("You are not a male");
}

if is_male && is_above_18 {


print!("You are a legal male");
}
}

Equivalent typescript code


Copy
function main() {
let is_male = false;
let is_above_18 = true;

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 10/43
09/06/2024, 16:00 DailyCode

if (is_male) {
console.log("You are a male");
} else {
console.log("You are not a male");
}

if (is_male && is_above_18) {


console.log("You are a legal male");
}
}

main();

3. Strings
There are two ways of doing strings in rust. We’ll be focussing on the easier one
Copy
fn main() {
let greeting = String::from("hello world");
println!("{}", greeting);

// print!("{}", greeting.chars().nth(1000))
}

Equivalent typescript code


Copy
function main() {
let greeting = "hello world";
console.log(greeting);

// console.log(greeting[1000]);
}

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 11/43
Conditionals, loops…
09/06/2024, 16:00 DailyCode

Conditionals
Copy
pub fn main() {
let x = 99;
let is_even = is_even(x);
if is_even {
print!("{} is even", x);
} else {
print!("{} is odd", x);
}
}

pub fn is_even(x: i32) -> bool {


return x % 2 == 0;
}

Loops

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 12/43
09/06/2024, 16:00 DailyCode

Copy
pub fn main() {
let str = String::from("harkirat singh");
println!("First name {}", get_first_name(str))

pub fn get_first_name(str: String) -> String {


let mut first_name = String::from("");
for c in str.chars() {
if c == ' ' {
break
}
first_name.push(c);
}
return first_name;
}

Functions
Copy
fn do_sum(a: i32, b: i32) -> i32 {
return a + b;
}

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 13/43
09/06/2024, 16:00 DailyCode

Memory Management in Rust

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 14/43
09/06/2024, 16:00 DailyCode

Whenever you run a program (C++, Rust, JS), it allocates and deallocates memory on the
RAM.
For example, for the following JS code
Copy
function main() {
runLoop();
}

function runLoop() {
let x = [];
for (let i = 0; i < 100000; i++) {
x.push(1);
}
console.log(x);
}

main();

as the runLoop function runs, a new array is pushed to RAM, and eventually garbage
collected

There are 3 popular ways of doing memory management

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 15/43
09/06/2024, 16:00 DailyCode

Jargon #0 - Mutability
Memory management is a crucial aspect of programming in Rust, designed to ensure safety
and efficiency without the need for a garbage collector.
Not having a garbage collector is one of the key reasons rust is so fast
It achieves this using the
Mutability
1. Mutabilityvariables represent variables whose value cant be changed once assigned
Immutable
2. Heap and memory Copy
3. Ownership
fn main() {
model
let x: i32 = 1;
4. Borrowing
x = 2;and//references
Error because x is immutable
println!("{}", x);
5. Lifetimes
}

By default, all variables in Rust are immutable because


1. Immutable data is inherently thread-safe because if no thread can alter the data, then no
synchronization is needed when data is accessed concurrently.
2. Knowing that certain data will not change allows the compiler to optimize code better.
You can make variables mutable by using the mut keyword
Copy
fn main() {
let mut x: i32 = 1;
x = 2; // No error
println!("{}", x);
}

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 16/43
09/06/2024, 16:00 DailyCode

💡 const in Javascript is not the same as immutable variables in rust. In JS, you can still
update the contents of const and arrays objects

💡 JShttps://www.npmjs.com/package/immutable
also has a concept of immutability that a lot of libraries were built on in the past -

Jargon #1 - Stack vs heap


Stack vs. Heap Allocation
Rust has clear rules about stack and heap data management:
Stack: Fast allocation and deallocation. Rust uses the stack for most primitive data types
and for data where the size is known at compile time (eg: numbers).
Heap: Used for data that can grow at runtime, such as vectors or strings.

What’s stored on the stack?


Numbers - i32, i64, f64 …
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 17/43
09/06/2024, 16:00 DailyCode

Booleans - true, false


Fixed sized arrays (we’ll come to this later)
What’s stored on heap?
Strings
Vectors (we’ll come to this later)

Examples
Hello world with numbers

Hello world with functions

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 18/43
09/06/2024, 16:00 DailyCode

Hello world with strings

Memory in action
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 19/43
09/06/2024, 16:00 DailyCode

Copy
fn main() {
stack_fn(); // Call the function that uses stack memory
heap_fn(); // Call the function that uses heap memory
update_string(); // Call the function that changes size of variable
}

fn stack_fn() {
// Declare a few integers on the stack
let a = 10;
let b = 20;
let c = a + b;
println!("Stack function: The sum of {} and {} is {}", a, b, c);
}

fn heap_fn() {
// Create a string, which is allocated on the heap
let s1 = String::from("Hello");
let s2 = String::from("World");
let combined = format!("{} {}", s1, s2);
println!("Heap function: Combined string is '{}'", combined);
}

fn update_string() {
// Start with a base string on the heap
let mut s = String::from("Initial string");
println!("Before update: {}", s);

// Append some text to the string


s.push_str(" and some additional text");
println!("After update: {}", s);
}

Jargon #2 - Ownership
Ref - https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 20/43
09/06/2024, 16:00 DailyCode

Meet Rihana
She always wants to keep a boyfriend (or owner) and can never remain single. She says if I
ever become single (have no owners), I will die. She also can only have a single boyfriend at a
time.

Stack variables
Example #1 - Passing stack Variables inside functions
Copy
fn main() {
let x = 1; // crated on stack
let y = 3; // created on stack
println!("{}", sum(x, y));
println!("Hello, world!");
}

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 21/43
09/06/2024, 16:00 DailyCode

fn sum(a: i32, b: i32) -> i32 {


let c = a + b;
return c;
}

This might sound trivial since if the function is popped of the stack, all variables go away with
it, but check the next example
Example #2 - Scoping variables in the same fn
Copy
fn main() {
let x = 1; // crated on stack
{
let y = 3; // created on stack
}

println!("{}", y); // throws error


}

Heap variables
Heap variables are like Rihana. They always want to have a single owner, and if their owner
goes out of scope, they get deallocated.
Any time the owner of a heap variable goes out of scope, the value is de-allocated from the
heap.
Example #1 - Passing strings (heap variables) to functions as args
Copy
fn main() {
let s1 = String::from("hello");
let s2 = s1;
println!("{}", s1); // This line would cause a compile error because
}

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 22/43
09/06/2024, 16:00 DailyCode

s1
name value
ptr
len 5
capacity 5 index value
0 h
s2 1 e
name value 2 l
ptr 3 l
len 5 4 o
capacity 5

Another example of the same thing -


Copy
fn main() {
let my_string = String::from("hello");
takes_ownership(my_string);
println!("{}", my_string); // This line would cause a compile error
}

fn takes_ownership(some_string: String) {
println!("{}", some_string); // `some_string` now owns the data.
}

At any time, each value can have a single owner. This is to avoid memory issues like
1. Double free error.
2. Dangling pointers.
Fix?
Clone the string
Copy
fn main() {
let s1 = String::from("hello");

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 23/43
09/06/2024, 16:00 DailyCode

let s2 = s1.clone();
println!("{}", s1); // Compiles now
}

But what if you want to pass the same string over to the function? You don’t want to clone it,
and you want to return back ownership to the original function?
You can either do the following -
Copy
fn main() {
let s1 = String::from("hello");
let s2 = takes_ownership(s1);
println!("{}", s2);
}

fn takes_ownership(some_string: String) -> String {


println!("{}", some_string);
return some_string; // return the string ownership back to the origi
}

You can also do this


Copy
fn main() {
let mut s1 = String::from("hello");
s1 = takes_ownership(s1);
println!("{}", s2);
}

fn takes_ownership(some_string: String) -> String {


println!("{}", some_string);

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 24/43
09/06/2024, 16:00 DailyCode

return some_string; // return the string ownership back to the ori


}

Jargon #3 - Borrowing and


Is there a better way to pass strings (or generally heap related data structures) to a function
references
without passing over the ownership?
Yes - References

Rihana upgrades
Rihana now says I’d like to be borrowed from time to time. I will still have a single owner , but
I can still be borrowed by other variables temporarily. What rules do you think should apply to
her?
1. She can be borrowed by multiple people that she’s friends with but does no hanky panky
2. If she does want to do hanky panky, she can only have 1 borrower that she does it with.
She cant simultaneously be with other borrowers (even with no hanky panky)

References
References mean giving the address of a string rather than the ownership of the string over to
a function
For example

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 25/43
09/06/2024, 16:00 DailyCode

Copy
fn main() {
let s1 = String::from("Hello");
let s2 = &s1;

println!("{}", s2);
println!("{}", s1); // This is valid, The first pointer wasn't in
}

Borrowing
You can transferring ownership of variables to fns. By passing a reference to the string to the
function take_ownership , the ownership of the string remains with the original variable, in the
main function. This allows you to use my_string again after the function call.

Copy
fn main() {
let my_string = String::from("Hello, Rust!");
takes_ownership(&my_string); // Pass a reference to my_string
println!("{}", my_string); // This is valid because ownership was
}

fn takes_ownership(some_string: &String) {
println!("{}", some_string); // some_string is borrowed and not mov
}

Mutable references
What if you want a function to update the value of a variable?

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 26/43
09/06/2024, 16:00 DailyCode

Copy

fn main() {
let mut s1 = String::from("Hello");
update_word(&mut s1);
println!("{}", s1);
}

fn update_word(word: &mut String) {


word.push_str(" World");
}

Try having more than one mutable reference at the same time -
Copy
fn main() {
let mut s1 = String::from("Hello");
let s2 = &mut s1;
update_word(&mut s1);
println!("{}", s1);
println!("{}", s2);
}

fn update_word(word: &mut String) {


word.push_str(" World");
}

Rules of borrowing
There can me many immutable references at the same time
Copy

fn main() {
let s1 = String::from("Hello");
let s2 = &s1;
let s3 = &s1;

println!("{}", s1);
println!("{}", s2);
println!("{}", s3);
}
// No errors

There can be only one mutable reference at a time


https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 27/43
09/06/2024, 16:00 DailyCode

Copy
fn main() {
let mut s1 = String::from("Hello");
let s2 = &mut s1;
let s3 = update_word(&mut s1);

println!("{}", s1);
println!("{}", s2);
}

fn update_word(word: &mut String) {


word.push_str(" World");
}
// Error

If there is a mutable reference , you can’t have another immutable reference either.
Copy
fn main() {
let mut s1 = String::from("Hello");
let s2 = &mut s1;
let s3 = &s1;

println!("{}", s1);
println!("{}", s2);
}

fn update_word(word: &mut String) {


word.push_str(" World");
}

This to avoid any data races/inconsistent behaviour


If someone makes an immutable reference , they don’t expect the value to change suddenly
If more than one mutable references happen, there is a possibility of a data race and
synchronization issues

💡 Two
now
good things to discuss at this point should be but we’re going to ignore it for
1. Lifetimes
2. String slices (&str)

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 28/43
09/06/2024, 16:00 DailyCode

Ref - https://doc.rust-lang.org/book/ch04-03-slices.html

Structs
Structs in rust let you structure data together. Similar to objects in javascript
Copy
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}

fn main() {
let user1 = User {
active: true,
username: String::from("someusername123"),
email: String::from("[email protected]"),
sign_in_count: 1,
};
print!("User 1 username: {:?}", user1.username);
}

Can you guess if they are stored in stack or heap ?

Side quest - Learning about traits


Try running experiments around
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 29/43
09/06/2024, 16:00 DailyCode

1. mutable and immutable references


2. Ownership transfer
for structs
Code 1 - Only stack types in the struct
Copy
struct User {
active: bool,
sign_in_count: u64,
}

fn main() {
let mut user1 = User {
active: true,
sign_in_count: 1,
};

print_name(user1);
print!("User 1 username: {}", user1.active); // Error - can not use
}

fn print_name(user1: User) {
print!("User 1 username: {}", user1.active);
}

Add the copy trait


Copy
#[derive(Copy, Clone)]
struct User {
active: bool,
sign_in_count: u64,
}

fn main() {
let mut user1 = User {
active: true,
sign_in_count: 1,
};

print_name(user1);
print!("User 1 username: {}", user1.active); // Error goes away beca

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 30/43
09/06/2024, 16:00 DailyCode

fn print_name(user1: User) {
print!("User 1 username: {}", user1.active);
}

Code 2 - Add strings


Copy
struct User {
active: bool,
sign_in_count: u64,
username: String,
}

fn main() {
let mut user1 = User {
active: true,
sign_in_count: 1,
username: "harkirat".to_string()
};

change_name(user1);
print!("User 1 username: {}", user1.active); // Error - can not use
}

fn change_name(user1: User) {
print!("User 1 username: {:?}", user1.active);
}

Try adding the Copy trait (you wont be able to because strings dont implement them, use
clone trait instead)

Copy
#[derive(Clone)]
struct User {
active: bool,
sign_in_count: u64,
username: String,
}

fn main() {

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 31/43
09/06/2024, 16:00 DailyCode

let mut user1 = User {


active: true,
sign_in_count: 1,
username: "harkirat".to_string()
};

change_name(user1.clone());
print!("User 1 username: {}", user1.active); // Error - can not use
}

fn change_name(user1: User) {
print!("User 1 username: {:?}", user1.active);
}

Implementing structs
You can also implement structs , which means you can attach functions to instances of
structs
(Very similar to classes in TS)
Copy
struct Rect {
width: u32,
height: u32,
}

impl Rect {
fn area(&self) -> u32 {
self.width * self.height
}
}

fn main() {
let rect = Rect {
width: 30,
height: 50,
};

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 32/43
09/06/2024, 16:00 DailyCode

print!("The area of the rectangle is {}", rect.area());


}

Enums
Enums in rust are similar to enums in Typescript. They allow you to define a type by
enumerating its possible variants.
Ref - https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 33/43
09/06/2024, 16:00 DailyCode

Copy
enum Direction {
North,
East,
South,
West,
}

fn main() {
let my_direction = Direction::North;
let new_direction = my_direction; // No error, because Direction is
move_around(new_direction);
}

fn move_around(direction: Direction) {
// implements logic to move a character around
}

Why not simply do the following -


Copy
fn main() {
move_around("north".to_string());
}

fn move_around(direction: String) {
if direction == "north" {
println!("Moving North");
}
}

Because we don’t enforce the 4 variants of directions. So this is much looser than strictly
allowing only 4 variants for direction
Enums with values
Copy
// Define an enum called Shape
enum Shape {
Circle(f64), // Variant with associated data (radius)
Square(f64), // Variant with associated data (side length)
Rectangle(f64, f64), // Variant with associated data (width, height
}

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 34/43
09/06/2024, 16:00 DailyCode

// Function to calculate area based on the shape


fn calculate_area(shape: Shape) -> f64 {
// calculates the area of the shape
return 0
}

fn main() {
// Create instances of different shapes
let circle = Shape::Circle(5.0);
let square = Shape::Square(4.0);
let rectangle = Shape::Rectangle(3.0, 6.0);

We will be implementing the calcuate_area function in the pattern matching section

Pattern matching
Let you pattern match across various variants of an enum and run some logic
Copy
// Define an enum called Shape
enum Shape {
Circle(f64), // Variant with associated data (radius)
Square(f64), // Variant with associated data (side length)
Rectangle(f64, f64), // Variant with associated data (width, height
}

// Function to calculate area based on the shape


fn calculate_area(shape: Shape) -> f64 {
match shape {
Shape::Circle(radius) => std::f64::consts::PI * radius * radius,
Shape::Square(side_length) => side_length * side_length,
Shape::Rectangle(width, height) => width * height,
}
}

fn main() {
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 35/43
09/06/2024, 16:00 DailyCode

// Create instances of different shapes


let circle = Shape::Circle(5.0);
let square = Shape::Square(4.0);
let rectangle = Shape::Rectangle(3.0, 6.0);

// Calculate and print the areas


println!("Area of circle: {}", calculate_area(circle));
println!("Area of square: {}", calculate_area(square));
println!("Area of rectangle: {}", calculate_area(rectangle));
}

Error handling
Different languages have different ways to handle errors.
Javascript, for example, has the concept of try catch blocks
Copy
try {
const data = fs.readFileSync('example.txt', 'utf8');
console.log("File content:", data);
} catch (err) {
console.error("Error reading the file:", err);
}

The reason we put the code inside a try catch block is that reading a file is
unpredictable .
The file might not exist, the file might be locked by another process, and hence there is a
possibility of this code throwing an error
The same is true for a rust program trying to access a file. But the way rust does error
handling is slightly different
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 36/43
09/06/2024, 16:00 DailyCode

Result Enum
Copy
enum Result<T, E> {
Ok(T),
Err(E),
}

If you look at the code above, it is an enum (with generic types)


This enum is what a function can return/returns when it has a possibility of throwing an error
For example
Copy
use std::fs::File;

fn main() {
let greeting_file_result = fs::read_to_string("hello.txt");
}

Notice the type of greeting_file_result in VSCode


It returns an enum that looks as follows. It’s an enum with the Ok variant having a string value
and Err variant having an Error value
Copy
enum Result{
Ok(String),
Err(Error),
}

Complete code
Copy
use std::fs;

fn main() {
let greeting_file_result = fs::read_to_string("hello.txt");

match greeting_file_result {
Ok(file_content) => {
println!("File read successfully: {:?}", file_content);
},
Err(error) => {
println!("Failed to read file: {:?}", error);
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 37/43
09/06/2024, 16:00 DailyCode

}
}
}

Incase you write a function yourself, you can also return a Result from it. As the name
suggests, Result holds the result of a function call that might lead to an error.
Unwraps
Incase you are ok with runtime errors (crashing the process while it runs if an error happens),
then you can unwrap a Result
Copy
use std::fs;

fn main() {
let greeting_file_result = fs::read_to_string("hello.txt");
print!("{}", greeting_file_result.unwrap());
}

Returning a custom error


Copy
use core::fmt;
use std::{fmt::{Debug, Formatter}, fs};

pub struct FileReadError {

fn main() {
let contents = read_file("hello.txt".to_string());
match contents {
Ok(file_content) => {
println!("File content: {}", file_content);
},
Err(error) => {
println!("Error reading file: {:?}", error);
}
}
}

fn read_file(file_path: String) -> Result<String, FileReadError> {

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 38/43
09/06/2024, 16:00 DailyCode

let greeting_file_result = fs::read_to_string("hello.txt");


match greeting_file_result {
Ok(file_content) => {
Ok(file_content)
},
Err(error) => {
let err = FileReadError {};
Err(err)
}
}
}

Option enum
Ref - https://viblo.asia/p/billion-dollar-mistake-RQqKLopr57z
The Option enum was introduced in Rust to handle the concept of nullability in a safe and
expressive way. Unlike many programming languages that use a null or similar keyword to
represent the absence of a value, Rust doesn't have null.
Copy
pub enum Option<T> {
None,
Some(T),
}

If you ever have a function that should return null, return an Option instead.
For example
Copy
fn find_first_a(s: String) -> Option<i32> {
for (index, character) in s.chars().enumerate() {
if character == 'a' {
return Some(index as i32);

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 39/43
09/06/2024, 16:00 DailyCode

}
}
return None;
}

fn main() {
let my_string = String::from("raman");
match find_first_a(my_string) {
Some(index) => println!("The letter 'a' is found at index: {}",
None => println!("The letter 'a' is not found in the string."),
}
}

Collections
https://doc.rust-lang.org/book/ch08-00-common-collections.html

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 40/43
09/06/2024, 16:00 DailyCode

Cargo, packages and external deps


Just like the nodejs ecosystem has npm , the rust ecosystem has cargo
Cargo is a package manager for rust, which means we can use it to bring packages (crates in
case of rust) to our projects

Generate a random number


Use crate - https://crates.io/crates/rand
Run cargo add rand
Copy
use rand::{Rng, thread_rng};

fn main() {
let mut rng = thread_rng();
let n: u32 = rng.gen();
println!("Random number: {}", n);
}

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 41/43
09/06/2024, 16:00 DailyCode

Store time in a DB/as a variable


Use crate https://crates.io/crates/chrono
Run cargo add chrono
Copy
use chrono::{Local, Utc};

fn main() {
// Get the current date and time in UTC
let now = Utc::now();
println!("Current date and time in UTC: {}", now);

// Format the date and time


let formatted = now.format("%Y-%m-%d %H:%M:%S");
println!("Formatted date and time: {}", formatted);

// Get local time


let local = Local::now();
println!("Current date and time in local: {}", local);
}

What all libraries does rust have?


A lot of them
1. https://actix.rs/ - Extremely fast http server
2. https://serde.rs/ - Serializing and deserialising data in rust
3. https://tokio.rs/ - Asynchronous runtime in rust
4. https://docs.rs/reqwest/latest/reqwest/ - Send HTTP requests
5. https://docs.rs/sqlx/latest/sqlx/ - Connect to sql database

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 42/43
Leftovers - Traits, Generics and
09/06/2024, 16:00 DailyCode

Lifetimes, Multithreading, macros,


async ops (Futures)
https://doc.rust-lang.org/book/ch10-00-generics.html
https://doc.rust-lang.org/book/ch19-00-advanced-features.html
https://doc.rust-lang.org/book/ch20-00-final-project-a-web-server.html
https://doc.rust-lang.org/std/future/trait.Future.html

https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 43/43

You might also like