Some findings and notes about using rust on some real-world stuff

Handling JSON

A small example how to dump your struct to a file and read it again.

extern crate serde_derive;
extern crate serde;
extern crate serde_json;
use std::io::BufWriter;
use std::io::BufReader;
use std::fs::File;

#[derive(Serialize, Deserialize, Debug)]
enum CarClass {

#[derive(Serialize, Deserialize, Debug)]
struct Car {
    maxspeed: f64,
    weight: f64,
    class: CarClass

fn main() {
    let new_car = Car {
        maxspeed: 120.0,
        weight: 4000.0,
        class: CarClass::Offroad
    // write out the file
    let writer = BufWriter::new(File::create("car.json").unwrap());
    serde_json::to_writer_pretty(writer, &new_car).unwrap();

    // read it back again
    let reader = BufReader::new(File::open("car.json").unwrap());
    let loaded_car: Car = serde_json::from_reader(reader).unwrap();
    println!("{:?}", loaded_car);


serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"

Iterate folder:

use std::io;
use std::fs::{self, DirEntry};
use std::path::Path;

fn iterate_path(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> {
    if dir.is_dir() {
        for entry in fs::read_dir(dir)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_dir() {
                visit_dirs(&path, cb)?;
            } else {

or walkdir:

walkdir = "2"
extern crate walkdir
use walkdir::WalkDir;

for entry in WalkDir::new("foo") {
    println!("{}", entry?.path().display());

Argument parsing with clap

clap = "2"
extern crate clap;
use clap::{Arg, App, SubCommand};

fn main() {
    let matches = App::new("myapp")
                               .help("Sets a starting directory")
    let dir  = matches.value_of("dir").unwrap();
    println!("Value for root: {}", dir);

cargo run -- somedir


use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use treexml::Document;

match File::open("yo.xml") {
    Ok(f) => {
        let mut buf_reader = BufReader::new(f);
        let doc = Document::parse(buf_reader).unwrap();
    Err(_e) => ()

Run system command

use std::process::Command;

let output = 
        .args(&["-l", "-R"])
        .expect("failed to execute process");
let res = output.stdout;
println!("{:?}", res);

Parse string to type

let i = String::from("42").parse::<i32>().unwrap();
// or let the compiler figure that out from annotating the variable
let i: i32 = String::from("42").parse().unwrap();

Building gotchas and Cargo

OSX @rpath

you can use install_name_tool to add a relative library search path to your executable like that:
install_name_tool -add_rpath @executable_path/. your_binary
in case you are using a gui library like libui you can then bundle the libui.A.dylib with your app bundle.
cargo bundle is recommended for packaging the actual app.

create multiple binaries

Let's say you want a GUI app and one for the command line that has minimal size and dependencies. All you need to do is the following in your Cargo.toml:

name = "cli"
path = "src/"

name = "cli"
path = "src/"

cargo build will then build both. Run the binary of your choice with cargo run --bin cli.

Windows programs without a console window

#![windows_subsystem = "windows"]

If you use this in your crate root, no console window will be shown if you run the resulting executable.