[package]
name = "ping"
version = "0.1.0"
edition = "2021"
[dependencies]
#delf = { path = "../delf" } #Used to specify a library in another directory
[profile.release]
strip = true # Automatically strip symbols from the binary.
#opt-level = "z" # Optimize for size.
opt-level = "s" # Optimize for size.
lto = true # Used to remove deadcode and unused functions
panic = "abort" # Remove backtrace when crashes
macro_rules!create_function{// This macro takes an argument of designator `ident` and
// creates a function named `$func_name`.
// The `ident` designator is used for variable/function names.
($func_name:ident)=>{fn$func_name(){// The `stringify!` macro converts an `ident` into a string.
println!("You called {:?}()",stringify!($func_name));}};
}// Create functions named `foo` and `bar` with the above macro.
create_function!(foo);create_function!(bar);fnmain(){foo();bar();}
Macro for many arguments:
// `find_min!` will calculate the minimum of any number of arguments.
macro_rules!find_min{// Base case:
($x:expr)=>($x);
// `$x` followed by at least one `$y,`
($x:expr, $($y:expr),+)=>(// Call `find_min!` on the tail `$y`
std::cmp::min($x,find_min!($($y),+)))}fnmain(){println!("{}",find_min!(1));println!("{}",find_min!(1+2,2));println!("{}",find_min!(5,2*3,4));}
fnmain(){letmut s =String::from("hello world goodbye universe");// You can make as many imputable borrow that you want
let r1 =&s[0..5];let r2 =&s[6..11];let r3 =&s[12..19];let r4 =&s[20..28];println!("{}, {}, and {}{}", r1, r2, r3, r4);//Only after r1, r2, and r3 are not used anymore in the scope can you use a mutable reference
let r5 =&mut s;// no problem
println!("{}", r5);}fnchange(some_string:&mut String){
some_string.push_str(", world");}fncalculate_length(s:&String)->usize{
s.len()}
Mutable Borrowing:
fnmain(){letmut s =String::from("hello");//Make a mutable string
// If this is in a scope then it will be removed at the end of the
let r1 =&mut s;// Since you have a mutable borrow then you cant have a immutable borrow. The following will fail
// let r2 = &mut s;
change(r1);// Since there is a mutable variables based on s you cant use s only r1 until it is removed
println!("{}", r1);}fnchange(some_string:&mut String){
some_string.push_str(", world");}fncalculate_length(s:&String)->usize{
s.len()}
No Dangling Return:
fnmain(){let reference_to_nothing =no_dangle();println!("{}", reference_to_nothing);}fnno_dangle()-> String{let s =String::from("hello");//You cant return a reference to a string that was created in this function scope
//&s
s
}
String Slice Borrowing:
let s =String::from("hello world");let hello =&s[0..5];let world =&s[6..11];println!("{}", reference_to_nothing);
In the main.rs file you need include mod filename;. This links the file to main function. Then in the actual file you can import the module with use crate::filename;
#![allow(unreachable_code)]fnmain(){'outer:loop{println!("Entered the outer loop");'inner:loop{println!("Entered the inner loop");// This would break only the inner loop
//break;
// This breaks the outer loop
break'outer;}println!("This point will never be reached");}println!("Exited the outer loop");}
Loop over Mutable:
fnmain(){letmut names =vec!["Bob","Frank","Ferris"];for name in names.iter_mut(){*name =match name {&mut"Ferris"=>"There is a rustacean among us!",_=>"Hello",}}println!("names: {:?}", names);}
fnmain(){// first, let's declare both structs: with Rust repr
structIOI_Rust{ttl:u8,
tos:u8,
flags:u8,
options_size:u8,
options_data:u32,
}// and C repr
#[repr(C)]structIOI_C{ttl:u8,
tos:u8,
flags:u8,
options_size:u8,
options_data:u32,
}usememoffset::span_of;usestd::mem::size_of;// let's make a quick macro, this will make this a lot easier
macro_rules!print_offset{// the macro takes one identifier (the struct's name), then a tuple
// of identifiers (the field names)
($type: ident, ($($field: ident),*)) =>{// `$type` is an identifier, but we're going to
// print it out, so we need it as a string instead.
let t =stringify!($type);// this will repeat for each $field$(let f =stringify!($field);let span =span_of!($type,$field);println!("{:10} {:15} {:?}", t, f, span);)*// finally, print the total field size
let ts =size_of::<$type>();println!("{:10} {:15} {}", t,"(total)", ts);println!();};
}print_offset!(IOI_Rust,(ttl, tos, flags, options_size, options_data));print_offset!(IOI_C,(ttl, tos, flags, options_size, options_data));}/*
IOI_Rust ttl 4..5
IOI_Rust tos 5..6
IOI_Rust flags 6..7
IOI_Rust options_size 7..8
IOI_Rust options_data 0..4
IOI_Rust (total) 8
IOI_C ttl 0..1
IOI_C tos 1..2
IOI_C flags 2..3
IOI_C options_size 3..4
IOI_C options_data 4..8
IOI_C (total) 8
*/
#[derive(Debug)]structPoint(i32, i32);//Used to keep the lifetime of the function to the parent function
fnleft_most<'a>(p1:&'a Point, p2:&'a Point)->&'a Point{if p1.0< p2.0{
p1
}else{
p2
}}fnmain(){let p1: Point = Point(10,10);let p2: Point = Point(20,20);let p3 =left_most(&p1,&p2);// What is the lifetime of p3?
println!("p3: {p3:?}");}