Simple Operations and How-Tos

How do I...

use a range as a match subpattern?


#![allow(unused)]
fn main() {
let age = 27;
match age {
    0             => println!("I'm not born yet I guess"),
    n @ 1  ... 12 => println!("I'm a child of age {:?}", n),
    n @ 13 ... 19 => println!("I'm a teen of age {:?}", n),
    n             => println!("I'm an old person of age {:?}", n),
}
}

convert a number to a string?

The std::string::ToString is automatically implemented for any type which implements the Display trait. This includes all machine (including number) types.


#![allow(unused)]
fn main() {
let i = 5;
let five = i.to_string();
assert_eq!(five, "5");
}

convert a string to a number?


#![allow(unused)]
fn main() {
let num = "10".parse::<i32>().unwrap();
assert_eq!(10, num);
}

combine two strings?


#![allow(unused)]
fn main() {
fn greet(name: &str) {
    function_with_str_arg(&format!("Hello, {}!", name));
}
}

create a buffered reader from a File or other unbuffered type that implements Read?

To create a buffered reader for a File, do this:


#![allow(unused)]
fn main() {
BufReader::new(reader)
}

If you need to also set the size of the buffer, use this instead:


#![allow(unused)]
fn main() {
BufReader::with_capacity(size, reader)
}

create a buffered writer from a File or other unbuffered type that implements Write?

To create a buffered writer for a File, do this:


#![allow(unused)]
fn main() {
BufWriter::new(file)
}

If you need to also set the size of the buffer, use this instead:


#![allow(unused)]
fn main() {
BufWriter::with_capacity(size, writer)
}

convert an iterator over Result<T> into an iterator over T?

Assume we're reading lines from a reader and want to collect the lines into a vector of strings. We can do so like this, which will create a value of type Vec<T>:


#![allow(unused)]
fn main() {
let lines = reader.lines().collect::<io::Result<Vec<String>>>()?;
}

define a generic function whose argument is any filename type?

All three string types implement a common trait, AsRef<Path>, which makes it easy to declare a generic function that accepts "any filename type":


#![allow(unused)]
fn main() {
use std::path::Path;
use std::io;

fn open_file<P>(path_arg: P)
    -> io::Result<()>
    where P: AsRef<Path>
{
    let path = path_arg.as_ref();
    // ...
}
}

list the contents of a directory?


#![allow(unused)]
fn main() {
for entry_result in path.read_dir()? {
    let entry = entry_result?;
    println!("{}", entry.file_name().to_string_lossy());
}
}

Using type parameter... as runtime code?

pub trait DeviceCommunicationManagerCreator: Send {
  fn new(sender: Sender<DeviceCommunicationEvent>) -> Self;
}

fn add_comm_manager<T>(&self) -> Result<(), ButtplugServerStartupError>
  where
    T: 'static + DeviceCommunicationManager + DeviceCommunicationManagerCreator,
  {
    let mgr = T::new(self.sender.clone());
    ...
  }