Hello World
Some basic example:
fn main() { println!("Hello World!"); eprintln!("Message in stderr :-("); }
Some more complex example:
fn main() { let hello = "Hello, world"; println!("{}", hello); }
On last more, a little more hard-core:
fn main() { println!("{}", "Hello, world" .chars() .collect::<Vec<char>>() .into_iter() .collect::<String>() ); }
Numbers
Starting to format numbers.
fn main() { let n_immutable = 1; let mut n = 42; println!("{}", n); println!("{:.2}", 0.123456789); println!("{:04}", 42); println!("{val}", val=42); println!("{:?}", (1, 2, 3, 4)); println!("{:#?}", (1, 2, 3, 4)); println!("{n}", n=[1, 2, 3, 4, 5].iter().sum::<u32>() ); println!("{n}", n=(1..=10).sum::<u32>() ); println!("{n:04.4}", n="42".parse::<f64>().unwrap() ); }
Wow, and what about a fibo?
fn fibo(n : u32) -> u32 { if n == 0 { 0 } else { fibo(n - 1) + n } } fn main() { println!("{val}", val = (1..=10).map(|x| fibo(x)).sum::<u32>() ); }
And limits?
fn main() { println!("{} -> {}", u32::MIN, u32::MAX ); }
Colors in text
Today I'm testing text_colorizer
In cargo.toml:
[dependencies]
text-colorizer="*"
and the source code:
extern crate text_colorizer; use text_colorizer::*; fn main() { let blue_world = "Hello, world!".blue().bold().italic(); println!("{}", blue_world); println!("{:#?}", blue_world); }
gets us:
Hello, world! <- This part is blue, shiny and italic.
ColoredString {
input: "Hello, world!",
fgcolor: Some(
Blue,
),
bgcolor: None,
style: Style(
9,
),
}
Another one: ansi_term: ansi_term
In cargo.toml:
[dependencies]
ansi_term="*"
use ansi_term::Colour::*; fn main() { let red_world = Red.bold().italic().paint("Hello world!"); println!("{}", red_world); println!("{:#?}", red_world); }
Sorting /etc/passwd
use std::fs; use anyhow::Result; #[derive(Debug)] struct Entry { username: String, uid: u16, gid: u16 } fn main() -> Result<()> { let password_file = "/etc/passwd"; let content = fs::read_to_string(password_file)?; let mut entries = content .split('\n') .filter(|entry| entry.split(':').count() >= 4) .map(|entry| { let values = entry.split(':').collect::<Vec<&str>>(); Entry { username: values[0].to_string(), uid: values[2].parse::<u16>().unwrap(), gid: values[3].parse::<u16>().unwrap(), } }) .collect::<Vec<Entry>>(); entries.sort_by(|a, b| a.uid.cmp(&b.uid)); for entry in entries { println!("{username} ({uid},{gid})", username=entry.username, uid=entry.uid, gid=entry.gid, ) } Ok(()) }
File & Pipe
use std::fs; use std::process; use std::io::{self, Read}; use base64::{decode,encode}; fn write() { let src = "/etc/passwd"; let content = match fs::read_to_string(&src) { Ok(content) => content, Err(x) => { eprintln!("{}", x); process::exit(1); } }; let mut lines = content .split('\n') .filter(|x| !x.is_empty()) .collect::<Vec<&str>>(); lines.sort_unstable(); println!("{encoded}", encoded=encode(lines.join("\n"))); } fn read() { let dst = "/tmp/passwd"; let mut buffer = String::new(); io::stdin().read_to_string(&mut buffer).expect("We want some input."); let buffer = buffer.trim(); let decoded : String = match decode(&buffer) { Ok(res) => { String::from_utf8(res).expect("Valid utf8 string") }, Err(err) => { eprintln!("Invalid buffer: {:?}", err); process::exit(1); } }; match fs::write(&dst, decoded) { Ok(_res) => { println!("Wrote file {dst}.", dst=dst); }, Err(x) => { eprintln!("{}", x); } } } fn main() { if atty::is(atty::Stream::Stdin) { write(); } else { read(); } }
Run by doing:
$ cargo r|cargo r && wc -l /tmp/passwd
Wrote file /tmp/passwd.
53 /tmp/passwd
Regex
use std::env; use std::fs; use std::process; use anyhow::Result; use regex::Regex; fn main() -> Result<()> { let args : Vec<String> = env::args().collect(); let filename = match args.get(1) { None => { eprintln!("Invalid argument"); process::exit(1); }, Some(n) => { n } }; let pattern = args[2].clone(); let repl = args[3].clone(); let in_contents = fs::read_to_string(filename)?; let re = Regex::new(&pattern)?; let out_contents = re.replace_all(&in_contents, &repl).to_string(); println!("{}", out_contents); let pattern = "^([^:]*):"; let re = Regex::new(pattern)?; for line in out_contents.split('\n') { let res = match re.captures(line) { None => continue, Some(v) => v, }; println!("{}", &res[1]); } Ok(()) }
To test:
cargo r --bin test000 /etc/passwd mycroft testaroo
HashMap
use std::collections::HashMap; fn main() { let mut h : HashMap<u32, u32> = HashMap::new(); println!("is empty: {}", h.is_empty()); h.insert(42, 42); println!("is empty: {}, h: {:?}", h.is_empty(), h); println!("has 42: {:?}", h.contains_key(&42)); println!("has 1442: {:?}", h.contains_key(&1442)); let v = match h.get(&42) { None => { eprintln!("Don't have value"); 0 }, Some(x) => { eprintln!("Have value: {}", x); *x } }; println!("Value: {:?}", v); let v = match h.get(&1442) { None => { eprintln!("Don't have value"); 0 }, Some(x) => { eprintln!("Have value: {}", x); *x } }; println!("Value: {:?}", v); h.remove(&42); println!("is empty: {}", h.is_empty()); for i in 1..=7 { h.insert(i, i); } println!("Len: {}", h.len()); for (k, v) in &h { println!("{} = {}", k, v); } // With entry API let z = h.entry(4242).or_insert(4242); println!("with Entry API: {:?}", z); fn get_value() -> u32 { return 4242; } let z = h.entry(42).or_insert_with(get_value); println!("with Entry API w/ function: {:?}", z); }
Threads
1
use std::thread; use std::time::Duration; fn main() { let v = vec![1, 2, 3]; let th = thread::spawn(move || { for _index in 1..10 { println!("in spawned thread: {v:?}", v=v); thread::sleep(Duration::from_millis(1)); } }); for _index in 1..5 { println!("in main thread"); thread::sleep(Duration::from_millis(1)); } th.join().unwrap(); }
2
use std::thread; use std::time::Duration; use std::sync::mpsc; fn main() { let v = vec![1, 2, 3]; let (tx, rx) = mpsc::channel(); let th = thread::spawn(move || { for received in rx { println!("in spawned thread: {v:?}; {recv}", v=v, recv=received); if received == 9 { break; } thread::sleep(Duration::from_millis(1)); } }); for index in 1..10 { println!("in main thread"); tx.send(index).unwrap(); thread::sleep(Duration::from_millis(1)); } th.join().unwrap(); }
Threads, Arc & RNG
use std::thread; use std::sync::{Arc,Mutex}; use std::time::Duration; use rand::Rng; fn main() { let counter = Arc::new(Mutex::new(0)); let mut threads = vec![]; for i in 1..10 { let cloned_counter = Arc::clone(&counter); let th = thread::spawn(move || { let mut num = cloned_counter.lock().unwrap(); let mut rng = rand::thread_rng(); thread::sleep(Duration::from_millis(rng.gen::<u64>() % 100)); *num += i; println!("=> {}: {}", i, *num); }); threads.push(th); } for th in threads { th.join().unwrap(); } println!("Result: {}", *counter.lock().unwrap()); }