The missing batteries of Rust

Related tags

stdx
Overview

stdx - The missing batteries of Rust

New to Rust and don't yet know what crates to use? stdx has the best crates.

Current revision: stdx 0.119.0-rc, for Rust 1.19, July 20, 2017.

Feature Crate
Bitfields bitflags = "0.9.1" ๐Ÿ“–
Byte order conversion byteorder = "1.1.0" ๐Ÿ“–
Date and time chrono = "0.4.0" ๐Ÿ“–
Command-line argument parsing clap = "2.25.0" ๐Ÿ“–
Encoding/decoding encoding_rs = "0.6.11" ๐Ÿ“–
Error handling error-chain = "0.10.0" ๐Ÿ“–
Fast hashing fnv = "1.0.5" ๐Ÿ“–
Compression - deflate (gzip) flate2 = "0.2.19" ๐Ÿ“–
Iterator functions, macros itertools = "0.6.0" ๐Ÿ“–
Global initialization lazy_static = "0.2.8" ๐Ÿ“–
C interop libc = "0.2.25" ๐Ÿ“–
Logging log = "0.3.8" ๐Ÿ“–
Memory-mapped file I/O memmap = "0.5.2" ๐Ÿ“–
Multidimensional arrays ndarray = "0.9.1" ๐Ÿ“–
Big, rational, complex numbers num = "0.1.40" ๐Ÿ“–
Number of CPUs num_cpus = "1.6.2" ๐Ÿ“–
Random numbers rand = "0.3.15" ๐Ÿ“–
Parallel iteration rayon = "0.8.2" ๐Ÿ“–
Regular expressions regex = "0.2.2" ๐Ÿ“–
HTTP client reqwest = "0.7.1" ๐Ÿ“–
Software versioning semver = "0.7.0" ๐Ÿ“–
Serialization serde = "1.0.10" ๐Ÿ“–
JSON serde_json = "1.0.2" ๐Ÿ“–
Tar archives tar = "0.4.23" ๐Ÿ“–
Temporary directories tempdir = "0.3.5" ๐Ÿ“–
Thread pool threadpool = "1.4.0" ๐Ÿ“–
Configuration files toml = "0.4.2" ๐Ÿ“–
URLs url = "1.5.1" ๐Ÿ“–
Directory traversal walkdir = "1.0.7" ๐Ÿ“–

     

bitflags = "0.9.1" โ€ƒ ๐Ÿ“–

The only thing this crate does is export the bitflags! macro, but it's a heckuva-useful macro. bitflags! produces typesafe bitmasks, types with named values that are efficiently packed together as bits to express sets of options.

Example: examples/bitflags.rs

#[macro_use]
extern crate bitflags;

bitflags! {
    struct Flags: u32 {
        const FLAG_A       = 0b00000001;
        const FLAG_B       = 0b00000010;
        const FLAG_C       = 0b00000100;
        const FLAG_ABC     = FLAG_A.bits
                           | FLAG_B.bits
                           | FLAG_C.bits;
    }
}

fn main() {
    let e1 = FLAG_A | FLAG_C;
    let e2 = FLAG_B | FLAG_C;
    assert_eq!((e1 | e2), FLAG_ABC);   // union
    assert_eq!((e1 & e2), FLAG_C);     // intersection
    assert_eq!((e1 - e2), FLAG_A);     // set difference
    assert_eq!(!e2, FLAG_A);           // set complement
}

     

byteorder = "1.1.0" โ€ƒ ๐Ÿ“–

When serializing integers it's important to consider that not all computers store in memory the individual bytes of the number in the same order. The choice of byte order is called "endianness", and this simple crate provides the crucial functions for converting between numbers and bytes, in little-endian, or big-endian orders.

Example: examples/byteorder.rs

extern crate byteorder;

use std::io::Cursor;
use byteorder::{BigEndian, ReadBytesExt};
use byteorder::{LittleEndian, WriteBytesExt};

fn main() {
    // Read unsigned 16 bit big-endian integers from a Read type:
    let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
    // Note that we use type parameters to indicate which kind of byte
    // order we want!
    assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
    assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());

    // Write unsigned 16 bit little-endian integers to a Write type:
    let mut wtr = vec![];
    wtr.write_u16::<LittleEndian>(517).unwrap();
    wtr.write_u16::<LittleEndian>(768).unwrap();
    assert_eq!(wtr, vec![5, 2, 0, 3]);
}

     

chrono = "0.4.0" โ€ƒ ๐Ÿ“–

Date and time types.

Example: examples/chrono.rs

extern crate chrono;
use chrono::*;

fn main() {
    let local: DateTime<Local> = Local::now();
    let utc: DateTime<Utc> = Utc::now();

    let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9);

    assert_eq!((dt.year(), dt.month(), dt.day()), (2014, 11, 28));
    assert_eq!((dt.hour(), dt.minute(), dt.second()), (12, 0, 9));

    assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
    assert_eq!(dt.format("%a %b %e %T %Y").to_string(), "Fri Nov 28 12:00:09 2014");

    assert_eq!(format!("{}", dt), "2014-11-28 12:00:09 UTC");
}

     

clap = "2.25.0" โ€ƒ ๐Ÿ“–

Clap is a command line argument parser that is easy to use and is highly configurable.

Example: examples/clap.rs

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

fn main() {
    let app = App::new("My Super Program")
        .version("1.0")
        .author("Kevin K. <[email protected]>")
        .about("Does awesome things")
        .arg(Arg::with_name("config")
             .short("c")
             .long("config")
             .value_name("FILE")
             .help("Sets a custom config file")
             .takes_value(true))
        .arg(Arg::with_name("INPUT")
             .help("Sets the input file to use")
             .required(true)
             .index(1))
        .subcommand(SubCommand::with_name("test")
                    .about("controls testing features")
                    .arg(Arg::with_name("debug")
                         .short("d")
                         .help("print debug information verbosely")));

    // Parse the command line arguments
    let matches = app.get_matches();

    let config = matches.value_of("config").unwrap_or("default.conf");
    let input = matches.value_of("INPUT").unwrap();

    // Handle subcommands
    match matches.subcommand() {
        ("clone",  Some(sub_matches)) => {
            if matches.is_present("d") {
                // ...
            }
        },
        ("push",   Some(sub_matches)) => {},
        ("commit", Some(sub_matches)) => {},
        _ => {},
    }
}

Alternatives: docopt

     

encoding_rs = "0.6.11" โ€ƒ ๐Ÿ“–

encoding_rs is a Gecko-oriented Free Software / Open Source implementation of the Encoding Standard in Rust. Gecko-oriented means that converting to and from UTF-16 is supported in addition to converting to and from UTF-8, that the performance and streamability goals are browser-oriented, and that FFI-friendliness is a goal.

Example: examples/encoding_rs.rs

extern crate encoding_rs;
use encoding_rs::*;

fn main() {
    let expected = "\u{30CF}\u{30ED}\u{30FC}\u{30FB}\u{30EF}\u{30FC}\u{30EB}\u{30C9}";
    let encoded = b"\x83n\x83\x8D\x81[\x81E\x83\x8F\x81[\x83\x8B\x83h";

    let (decoded, encoding_used, had_errors) = SHIFT_JIS.decode(encoded);

    assert_eq!(&decoded[..], expected);
    assert_eq!(encoding_used, SHIFT_JIS);
    assert!(!had_errors);

    println!("Decoded result: {}", decoded);
}

     

error-chain = "0.10.0" โ€ƒ ๐Ÿ“–

Rust programs that handle errors consistently are reliable programs. Even after one understands error handling in Rust, it can be difficult to grasp and implement its best practices. error-chain helps you define your own error type that works with the ? operator to make error handling in Rust simple and elegant.

Example: examples/error-chain.rs

// `error_chain!` can recurse deeply
#![recursion_limit = "1024"]

#[macro_use]
extern crate error_chain;

// We'll put our errors in an `errors` module, and other modules in
// this crate will `use errors::*;` to get access to everything
// `error_chain!` creates.
mod errors {
    // Create the Error, ErrorKind, ResultExt, and Result types
    error_chain! { }
}

use errors::*;

fn main() {
    if let Err(ref e) = run() {
        use ::std::io::Write;
        let stderr = &mut ::std::io::stderr();
        let errmsg = "Error writing to stderr";

        writeln!(stderr, "error: {}", e).expect(errmsg);

        for e in e.iter().skip(1) {
            writeln!(stderr, "caused by: {}", e).expect(errmsg);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
        }

        ::std::process::exit(1);
    }
}

// Most functions will return the `Result` type, imported from the
// `errors` module. It is a typedef of the standard `Result` type
// for which the error type is always our own `Error`.
fn run() -> Result<()> {
    use std::fs::File;

    // Use chain_err to attach your own context to errors
    File::open("my secret file")
        .chain_err(|| "unable to open my secret file")?;

    // Use the `bail!` macro to return an error Result, ala `println!`
    bail!("giving up");
}

Alternatives: quick-error

     

flate2 = "0.2.19" โ€ƒ ๐Ÿ“–

Compression and decompression using the DEFLATE algorithm.

Example: examples/flate2.rs

extern crate flate2;
extern crate tar;

use flate2::read::GzDecoder;
use std::env;
use std::fs::File;
use std::io::{self, BufReader};
use tar::Archive;

fn run() -> Result<(), io::Error> {
    let mut args = env::args().skip(1);
    let tarball = args.next().expect("incorrect argument");
    let outdir = args.next().expect("incorrect argument");

    let archive = File::open(tarball)?;
    let archive = BufReader::new(archive);
    let archive = GzDecoder::new(archive)?;
    let mut archive = Archive::new(archive);

    archive.unpack(outdir)?;

    Ok(())
}

fn main() { run().unwrap() }

     

fnv = "1.0.5" โ€ƒ ๐Ÿ“–

The standard library's hash maps are notoriously slow for small keys (like integers). That's because they provide strong protection against a class of denial-of-service attacks called "hash flooding". And that's a reasonable default. But when your HashMaps are a bottleneck consider reaching for this crate. It provides the Fowler-Noll-Vo hash function, and conveniences for creating FNV hash maps that are considerably faster than those in std.

Example: examples/fnv.rs

extern crate fnv;

use fnv::FnvHashMap;

fn main() {
    let mut map = FnvHashMap::default();
    map.insert(1, "one");
    map.insert(2, "two");
    map.insert(3, "three");

    for (number, word) in map.iter() {
        println!("Number {}: {}", number, word);
    }

    map.remove(&(2));
    println!("The length of HashMap is {}.", map.len());
    println!("The first element is {}.", map.get(&(1)).unwrap());
}

     

itertools = "0.6.0" โ€ƒ ๐Ÿ“–

The Rust standard Iterator type provides a powerful abstraction for operating over sequences of values, and is used pervasively throughout Rust. There are though a number of common operations one might want to perform on sequences that are not provided by the standard library, and that's where itertools comes in. This crate has everything including the kitchen sink (in the form of the batching adaptor). Highlights include dedup, group_by, mend_slices, merge, sorted, join and more.

Example: examples/itertools.rs

extern crate itertools;

use itertools::{join, max, sorted};

fn main(){
    let a = [3, 2, 5, 8, 7];

    // Combine all iterator elements into one String,
    // seperated by *.
    println!("{:?}", join(&a, "*"));
    // Return the maximum value of the iterable.
    println!("{:?}", max(a.iter()).unwrap());
    // Collect all the iterable's elements into a
    // sorted vector in ascending order.
    println!("{:?}", sorted(a.iter()));
}

     

lazy_static = "0.2.8" โ€ƒ ๐Ÿ“–

Rust has strict rules about accessing global state. In particular there is no 'life before main' in Rust, so it's not possible to write a programmatic constructor for a global value that will be run at startup. Instead, Rust prefers lazy execution for global initialization, and the lazy_static! macro does just that.

Example: examples/lazy_static.rs

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
    static ref COUNT: usize = HASHMAP.len();
    static ref NUMBER: u32 = times_two(21);
}

fn times_two(n: u32) -> u32 { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}

     

libc = "0.2.25" โ€ƒ ๐Ÿ“–

If you need to talk to foreign code, you need this crate. It exports C type and function definitions appropriate to each target platform Rust supports. It defines the standardized C features that are common across all platforms as well as non-standard features specific to the platform C libraries. For more platform-specific FFI definitions see nix and winapi.

Example: examples/libc.rs

extern crate libc;

fn main() {
    unsafe {
        libc::exit(0);
    }
}

     

log = "0.3.8" โ€ƒ ๐Ÿ“–

The most common way to perform basic logging in Rust, with the error!, warn!, info!, and debug! macros. It is often combined with the env_logger crate to get logging to the console, controlled by the RUST_LOG environment variable. This is the traditional logging crate used by rustc, and its functionality was once built in to the language.

Supplemental crates: env_logger = "0.4.3"

Example: examples/log.rs

#[macro_use]
extern crate log;
extern crate env_logger;

use log::LogLevel;

fn main() {
    env_logger::init().unwrap();

    debug!("this is a debug {}", "message");
    error!("this is printed by default");

    if log_enabled!(LogLevel::Info) {
        let x = 3 * 4; // expensive computation
        info!("the answer was: {}", x);
    }
}

Alternatives: slog, log4rs

     

memmap = "0.5.2" โ€ƒ ๐Ÿ“–

Cross-platform access to memory-mapped I/O, a technique for sharing memory between processes, and for accessing the content of files as a simple array of bytes. It is implemented by binding the mmap syscall on Unix, and the CreateFileMapping / MapViewOfFile functions on Windows. This is a low-level feature used to build other abstractions. Note that it's not generally possible to create safe abstractions for memory mapping, since memory mapping entails shared access to resources outside of Rust's control. As such, the APIs in this crate are unsafe.

Example: examples/memmap.rs

extern crate memmap;

use memmap::{Mmap, Protection};
use std::env;
use std::io;
use std::str;

fn run() -> Result<(), io::Error> {
    let mut args = env::args().skip(1);
    let input = args.next().expect("incorrect argument");

    let map = Mmap::open_path(input, Protection::Read)?;
    unsafe {
        let all_bytes = map.as_slice();
        if let Ok(file_str) = str::from_utf8(all_bytes) {
            println!("{}", file_str);
        } else {
            println!("not utf8");
        }
    }
    Ok(())
}

fn main() { run().unwrap() }

     

ndarray = "0.9.1" โ€ƒ ๐Ÿ“–

The ndarray crate provides an N-dimensional container for general elements and for numerics. The multidimensional array, otherwise known as a "matrix", is a core data structure for numerical applications, and Rust does not have one in the language or standard library.

Example: examples/ndarray.rs

#[macro_use(s)]
extern crate ndarray;

use ndarray::{Array3, arr3};

fn main() {
    // Create a three-dimensional f64 array, initialized with zeros
    let mut temperature = Array3::<f64>::zeros((3, 4, 5));

    // Increase the temperature in this location, notice the
    // double-brackets indexing `temperature`
    temperature[[2, 2, 2]] += 0.5;

    // Create a 3-dimensional matrix,
    // 2 submatrices of 2 rows with 3 elements per row, means a shape
    // of `[2, 2, 3]`.
    let a = arr3(&[[[ 1,  2,  3],     // -- 2 rows  \_
                    [ 4,  5,  6]],    // --         /
                   [[ 7,  8,  9],     //            \_ 2 submatrices
                    [10, 11, 12]]]);  //            /
    //  3 columns ..../.../.../

    // This is a 2 x 2 x 3 array
    assert_eq!(a.shape(), &[2, 2, 3]);

    // Letโ€™s create a slice of `a` with
    //
    // - Both of the submatrices of the greatest dimension: `..`
    // - Only the first row in each submatrix: `0..1`
    // - Every element in each row: `..`
    let b = a.slice(s![.., 0..1, ..]);

    // This is the result of the above slice into `a`
    let c = arr3(&[[[ 1,  2,  3]],
                   [[ 7,  8,  9]]]);
    assert_eq!(b, c);
    assert_eq!(b.shape(), &[2, 1, 3]);
}

     

num = "0.1.40" โ€ƒ ๐Ÿ“–

Big integers, rational numbers, complex numbers, and numeric traits. This crate has a long history, beginning life in the standard library, being moved into the rust-lang organization, and finally being adopted by community maintainers. It remains a common way to access the kinds of features it provides.

Example: examples/num.rs

extern crate num;

use num::FromPrimitive;
use num::bigint::BigInt;
use num::rational::{Ratio, BigRational};

fn approx_sqrt(number: u64, iterations: usize) -> BigRational {
    let start: Ratio<BigInt>
        = Ratio::from_integer(FromPrimitive::from_u64(number).unwrap());

    let mut approx = start.clone();

    for _ in 0..iterations {
        approx = (&approx + (&start / &approx)) /
            Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
    }

    approx
}

fn main() {
    println!("{}", approx_sqrt(10, 4)); // prints 4057691201/1283082416
}

     

num_cpus = "1.6.2" โ€ƒ ๐Ÿ“–

When you need to make things parallel, you need to know how many CPUs to use! This is the simple way to get that information.

Example: examples/num_cpus.rs

extern crate threadpool;
extern crate num_cpus;

use threadpool::ThreadPool;
use std::sync::mpsc::channel;

fn main() {
    // Get the number of cpus on current machine
    let n_workers = num_cpus::get();
    let n_jobs = 8;

    // Create the thread pool with amount of workers equal to cores
    let pool = ThreadPool::new(n_workers);

    // Create transmitter and receiver channel
    let (tx, rx) = channel();

    // For each job grab a free worker from the pool and execute
    for _ in 0..n_jobs {
        let tx = tx.clone();
        pool.execute(move || {
            tx.send(1).unwrap();
        });
    }

    assert_eq!(rx.iter().take(n_jobs).fold(0, |a, b| a + b), 8);
}

     

rand = "0.3.15" โ€ƒ ๐Ÿ“–

Random number generators. The defaults are cryptographically strong. This is another crate with a long history, beginning life in the standard library.

Example: examples/rand.rs

extern crate rand;

use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    if rng.gen() { // random bool
        println!("i32: {}, u32: {}", rng.gen::<i32>(), rng.gen::<u32>())
    }

    let tuple = rand::random::<(f64, char)>();
    println!("{:?}", tuple)
}

     

rayon = "0.8.2" โ€ƒ ๐Ÿ“–

When people say that Rust makes parallelism easy, this is why. Rayon provides parallel iterators that make expressing efficient parallel operations simple and foolproof.

Example: examples/rayon.rs

extern crate rayon;

use rayon::prelude::*;

fn main() {
    let mut input = (0..1000).collect::<Vec<_>>();

    // Calculate the sum of squares
    let sq_sum: i32 = input.par_iter()
                      .map(|&i| i * i)
                      .sum();

    // Increment each element in parallel
    input.par_iter_mut()
        .for_each(|p| *p += 1);

    // Parallel quicksort
    let mut input = (0..1000).rev().collect::<Vec<_>>();
    quick_sort(&mut input);
}

fn quick_sort<T: PartialOrd + Send>(v: &mut [T]) {
    if v.len() <= 1 {
        return;
    }

    let mid = partition(v);
    let (lo, hi) = v.split_at_mut(mid);
    rayon::join(|| quick_sort(lo), || quick_sort(hi));
}

fn partition<T: PartialOrd + Send>(v: &mut [T]) -> usize {
    let pivot = v.len() - 1;
    let mut i = 0;
    for j in 0..pivot {
        if v[j] <= v[pivot] {
            v.swap(i, j);
            i += 1;
        }
    }
    v.swap(i, pivot);
    i
}

     

regex = "0.2.2" โ€ƒ ๐Ÿ“–

Rust's regular expressions are fast, like Rust is fast. Part of their power comes from a careful design that disallows back-references and arbitrary lookahead, creating predictable worst-case performance.

Example: examples/regex.rs

extern crate regex;

use regex::Regex;

fn main() {
    // Find a date
    let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
    assert!(re.is_match("2014-01-01"));

    // Iterating over capture groups
    let re = Regex::new(r"(\d{4})-(\d{2})-(\d{2})").unwrap();
    let text = "2012-03-14, 2013-01-01 and 2014-07-05";
    for cap in re.captures_iter(text) {
        println!("Month: {} Day: {} Year: {}", &cap[2], &cap[3], &cap[1]);
    }
}

     

reqwest = "0.7.1" โ€ƒ ๐Ÿ“–

A simple HTTP and HTTPS client. It is built on the popular Rust HTTP implementation, hyper, which is the HTTP stack developed for Servo.

Example: examples/reqwest.rs

extern crate reqwest;

use std::collections::HashMap;
use std::io::{BufRead, BufReader};

fn main() {
    // Make a GET request
    let resp = reqwest::get("https://www.rust-lang.org").unwrap();
    assert!(resp.status().is_success());

    let lines = BufReader::new(resp)
                          .lines()
                          .filter_map(|l| l.ok())
                          .take(10);
    for line in lines {
        println!("{}", line);
    }

    // Make a POST request
    let client = reqwest::Client::new().unwrap();
    let res = client.post("http://httpbin.org/post").unwrap()
        .body("the exact body that is sent")
        .send();

    // Convert to/from JSON automatically
    let mut map = HashMap::new();
    map.insert("lang", "rust");
    map.insert("body", "json");

    // This will POST a body of `{"lang":"rust","body":"json"}`
    let client = reqwest::Client::new().unwrap();
    let res = client.post("http://httpbin.org/post").unwrap()
        .json(&map).unwrap()
        .send();
}

     

semver = "0.7.0" โ€ƒ ๐Ÿ“–

Rust uses semantic versioning (also known as "semver") for crate versioning. This crate provides the canonical semver representation for Rust.

Example: examples/semver.rs

extern crate semver;

use semver::Version;

fn main() {
    // Construct Version objects
    assert!(Version::parse("1.2.3") == Ok(Version {
        major: 1,
        minor: 2,
        patch: 3,
        pre: vec!(),
        build: vec!(),
    }));

    // Compare Versions
    assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta"));
    assert!(Version::parse("1.2.3-alpha2") >  Version::parse("1.2.0"));

    // Increment patch number of mutable Version
    let mut bugfix_release = Version::parse("1.0.0").unwrap();
    bugfix_release.increment_patch();

    assert_eq!(Ok(bugfix_release), Version::parse("1.0.1"));
}

     

serde = "1.0.10" โ€ƒ ๐Ÿ“–

Serialization and deserialization of Rust datastructures is fast and easy using the serde serialization framework. Simply tag your data structures with #[derive(Serialize, Deserialize)] and serde will automatically convert them between formats like JSON, TOML, YAML, and more. To best understand serde, read its documentation at serde.rs.

Supplemental crates: serde_derive = "1.0.10", serde_json = "1.0.2", toml = "0.4.2"

Example: examples/serde.rs

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use serde_json::Value;

#[derive(Serialize, Deserialize, Debug)]
struct Contact {
    name: String,
    age: u32,
}

fn main() {
    let contact = Contact {
        name: "Brian".to_string(),
        age: 21,
    };

    // Serialize data structures to strings in JSON format
    let contact: String = serde_json::to_string(&contact).unwrap();
    println!("{}", contact);

    // Deserialize data structures from JSON strings
    let contact: Contact = serde_json::from_str(&contact).unwrap();
    println!("{:?}", contact);

    // Convert to arbitrary JSON `Value` type
    let contact: Value = serde_json::to_value(&contact).unwrap();
    println!("{:?}", contact);
}

Alternatives: rustc-serialize

     

serde_json = "1.0.2" โ€ƒ ๐Ÿ“–

Access to JSON, the "JavaScript Object Notation" format, widely used for transmission and storage of data on the Internet. This crate can be used for reading, writing, and manipulation of arbitrary JSON in addition to its use for automatic serialization with serde.

Example: examples/json.rs

extern crate serde_json;

use serde_json::Value;

fn main() {
    // Some JSON input data as a &str. Maybe this comes from the user.
    let data = r#"{
                    "name": "John Doe",
                    "age": 43,
                    "phones": [
                      "+44 1234567",
                      "+44 2345678"
                    ]
                  }"#;

    // Parse the string of data into serde_json::Value.
    let v: Value = serde_json::from_str(data).unwrap();

    // Access parts of the data by indexing with square brackets.
    println!("Please call {} at the number {}", v["name"], v["phones"][0]);
}

Alternatives: json

     

tar = "0.4.23" โ€ƒ ๐Ÿ“–

The "tar" archive format is in common use on the web. It is most often found in the form of .tar.gz files (called "tarballs") that have been compressed with the DEFLATE algorithm, which the tar crate can decompress when paired with the flate2 crate.

Example: examples/tar.rs

extern crate flate2;
extern crate tar;

use flate2::read::GzDecoder;
use std::env;
use std::fs::File;
use std::io::{self, BufReader};
use tar::Archive;

fn run() -> Result<(), io::Error> {
    let mut args = env::args().skip(1);
    let tarball = args.next().expect("incorrect argument");
    let outdir = args.next().expect("incorrect argument");

    let archive = File::open(tarball)?;
    let archive = BufReader::new(archive);
    let archive = GzDecoder::new(archive)?;
    let mut archive = Archive::new(archive);

    archive.unpack(outdir)?;

    Ok(())
}

fn main() { run().unwrap() }

     

tempdir = "0.3.5" โ€ƒ ๐Ÿ“–

The most common way to create temporary directories in Rust, this crate was once part of the standard library.

Example: examples/tempdir.rs

extern crate tempdir;

use std::fs::File;
use std::io::Write;
use tempdir::TempDir;

fn main() {
    // Create a directory inside of `std::env::temp_dir()`, named with
    // the prefix "example".
    let tmp_dir = TempDir::new("example").expect("create temp dir");
    let file_path = tmp_dir.path().join("my-temporary-note.txt");
    let mut tmp_file = File::create(file_path).expect("create temp file");
    writeln!(tmp_file, "Brian was here. Briefly.").expect("write temp file");

    // By closing the `TempDir` explicitly, we can check that it has
    // been deleted successfully. If we don't close it explicitly,
    // the directory will still be deleted when `tmp_dir` goes out
    // of scope, but we won't know whether deleting the directory
    // succeeded.
    drop(tmp_file);
    tmp_dir.close().expect("delete temp dir");
}

     

threadpool = "1.4.0" โ€ƒ ๐Ÿ“–

A thread pool for running a number of jobs on a fixed set of worker threads.

Example: examples/threadpool.rs

extern crate threadpool;
extern crate num_cpus;

use threadpool::ThreadPool;
use std::sync::mpsc::channel;

fn main() {
    // Get the number of cpus on current machine
    let n_workers = num_cpus::get();
    let n_jobs = 8;

    // Create the thread pool with amount of workers equal to cores
    let pool = ThreadPool::new(n_workers);

    // Create transmitter and receiver channel
    let (tx, rx) = channel();

    // For each job grab a free worker from the pool and execute
    for _ in 0..n_jobs {
        let tx = tx.clone();
        pool.execute(move || {
            tx.send(1).unwrap();
        });
    }

    assert_eq!(rx.iter().take(n_jobs).fold(0, |a, b| a + b), 8);
}

Alternatives: scoped_threadpool

     

toml = "0.4.2" โ€ƒ ๐Ÿ“–

TOML is a common format for configuration files, like Cargo.toml. It's easy on the eyes, simple to parse, and serializes from Rust types with serde.

Example: examples/toml.rs

extern crate toml;

use toml::Value;

fn main() {
    let toml = r#"
    [test]
    foo = "bar"
"#;

    let value = toml.parse::<Value>().unwrap();
    println!("{:?}", value);
}

     

url = "1.5.1" โ€ƒ ๐Ÿ“–

The URL parser and type, originally created for Servo.

Example: examples/url.rs

extern crate url;

use url::{Url, Host};

fn main() {
    let issue_list_url = Url::parse(
        "https://github.com/rust-lang/rust/issues?labels=E-easy&state=open"
    ).unwrap();

    assert!(issue_list_url.scheme() == "https");
    assert!(issue_list_url.username() == "");
    assert!(issue_list_url.password() == None);
    assert!(issue_list_url.host_str() == Some("github.com"));
    assert!(issue_list_url.host() == Some(Host::Domain("github.com")));
    assert!(issue_list_url.port() == None);
    assert!(issue_list_url.path() == "/rust-lang/rust/issues");
    assert!(issue_list_url.path_segments().map(|c| c.collect::<Vec<_>>()) ==
            Some(vec!["rust-lang", "rust", "issues"]));
    assert!(issue_list_url.query() == Some("labels=E-easy&state=open"));
    assert!(issue_list_url.fragment() == None);
    assert!(!issue_list_url.cannot_be_a_base());
}

     

walkdir = "1.0.7" โ€ƒ ๐Ÿ“–

A cross platform Rust library for efficiently walking a directory recursively. Note the filter_entry method on the directory iterator that short-circuits decent into subdirectories.

Example: examples/walkdir.rs

extern crate walkdir;

use walkdir::{WalkDir, Error};

fn run() -> Result<(), Error> {
    let wd = WalkDir::new(".");

    for entry in wd {
        let entry = entry?;
        println!("{}", entry.path().display());
    }

    Ok(())
}

fn main() { run().unwrap(); }

     

About stdx

Rust has a lovely and portable standard library, but it is not featureful enough to write software of any great sophistication. Compared to common platforms including Java, Python, and Go, Rust's standard library is small.

In Rust, the libraries we use for even simple tasks live and evolve on crates.io. This affords the Rust community freedom to experiment - discovering the Rustiest solutions to even common problems can take quite some iteration - but it also means that we're in for a slow evolutionary process to converge around the best of those solutions. In the meantime, you just have to know which crates to use for what.

stdx contains some of the most important crates in Rust. I mean it. If Rust had a more expansive standard library, many of the stdx crates would be in it, or at least the features they provide. Many of the crates of stdx are maintained by the same authors as the Rust standard library, and they are designed to be idiomatic and interoperable. These are core elements of the crate ecosystem that all Rusticians should be aware of.

How to use stdx

stdx is primarily a teaching tool. New and old Rust programmers alike will get the most from it by digesting the list of stdx crates, each entry of which links to a description of the crate along with an example of its basic use.

These examples are full working source and are intended to get you up and running with any of the stdx crates immediately. Just copy the crate name and version exactly as written into the dependencies section of your Cargo.toml like so:

[dependencies]
bitflags = "0.9.1"

Then copy the full example into your examples directory, like so:

Example: examples/bitflags.rs

#[macro_use]
extern crate bitflags;

bitflags! {
    struct Flags: u32 {
        const FLAG_A       = 0b00000001;
        const FLAG_B       = 0b00000010;
        const FLAG_C       = 0b00000100;
        const FLAG_ABC     = FLAG_A.bits
                           | FLAG_B.bits
                           | FLAG_C.bits;
    }
}

fn main() {
    let e1 = FLAG_A | FLAG_C;
    let e2 = FLAG_B | FLAG_C;
    assert_eq!((e1 | e2), FLAG_ABC);   // union
    assert_eq!((e1 & e2), FLAG_C);     // intersection
    assert_eq!((e1 - e2), FLAG_A);     // set difference
    assert_eq!(!e2, FLAG_A);           // set complement
}

Then execute the following:

cargo run --example bitflags

And suddenly you are a slightly-experienced user of that crate. Now click on the ๐Ÿ“– icon to get the rest of the story.

Convinced? Go check out that list.

Why use stdx?

As a learning tool, I hope the benefit will be evident from a straight read-through. But stdx, and tools like it, may provide important benefits to users in the future.

To be clear, stdx is experimental. A lot of the below is speculative.

stdx provides assurances that the versions of crates it specifes work together correctly in a wide variety of configurations. Today those assurances are few, but they will grow. And these types of assurances will become increasingly valuable to Rust.

As of now, the only validation stdx provides is that the exact versions of the stdx crates resolve correctly by Cargo, and that they build on Linux and Windows. That is already beneficial by uncovering problematic combinations and incorrect semver specifications. Here are some other assurances that stdx will enable:

  • Additional integration test cases between the stdx crates
  • Testing of all stdx crates' own test suites using the stdx version lock
  • Testing on all tier 1 platforms
  • Testing on tier 2 platforms
  • Enforcement and coverage of serde features and interop
  • Enforcement of other compile-time feature standards
  • stdx as version lock - you don't even have to call into it. Just link to it and it locks down a chunk of your crate graph to known-good combinaitons.
  • Ecosystem wide testing using stdx version lock - eventually we will be able to say which crates are known to work correctly with stdx.
  • The more people use the stdx version lock the more assurance they get. This plays into future Rust's LTS directions.

By applying high quality standards to a small selection of critical crates we can create a high degree of confidence in a larger core of the Rust ecosystem.

Selection criteria

The criteria for inclusion in stdx is conservative, and fuzzy. It's mostly crates that are pretty super important, considering criteria like

  • portability
  • quality
  • conformance to conventions
  • documentation
  • interoperability with other crates
  • reliability of maintainers
  • de-facto adoption
  • historical context and precedent

stdx is focused on core features, crates that are quintessentially Rust and relied on by many Rust programs. It is intentionally limited for the sake of simplicity and ease of comprehension.

All crates must work on Rust's tier-1 platforms, currently x86 Linux, OS X, and Windows.

Contributing

See CONTRIBUTING.md.

License

stdx and the crates it links to are licensed under various permissive, BSD-like licenses. In lay-terms these licenses allow their code to be used and distributed freely, and are compatible with Rust's own license (MIT/Apache 2).

stdx itself is dual MIT/Apache 2 licensed, like Rust, and the copyright is owned by its contributors.

Issues
  • Add itertools to stdx

    Add itertools to stdx

    Seems like a core part of what people commonly use for functionality with rusts iterators and I believe it meets all the criteria listed

    help wanted easy 
    opened by LLBlumire 8
  • add stdlibx::prefix

    add stdlibx::prefix

    one of the things I really miss about langauges like python is that you don't have to clutter your import space in order to use most functionality.

    That is not true with rust.

    In rust, I frequently find myself writing dev_prefix files to import structs and traits that are necessary in practically every application.

    Here is an example of a possible one for stdlibx:

    //! `import stdlibx::prefix::*` so you can be ready to code!
    
    // traits
    pub use std::ascii::AsciiExt; // to_ascii_uppercase(), etc
    pub use std::clone::Clone;
    pub use std::convert::AsRef;
    pub use std::default::Default;
    pub use std::fmt::{Debug, Write as FmtWrite};
    pub use std::io::{Read, Seek, SeekFrom, Write};
    pub use std::iter::{FromIterator, Iterator};
    pub use std::str::FromStr;
    pub use std::ops::{Deref, DerefMut};
    
    // structs
    pub use std::collections::{HashMap, HashSet, VecDeque};
    pub use std::ffi::OsString;
    pub use std::path::{Path, PathBuf};
    pub use std::rc::Rc;
    pub use std::sync::Arc;
    

    This list was basically put together because of the number of times I write a line of code and then hit compile and see that it doesn't work because of a forgotten import. It is quite annoying to not have access (by default) to std functions like from_iterator or write_str because you forgot to import a trait! It is almost as frustrating to be using a HashMap and realize it isn't defined. This is especially frustrating for newbies, so I see this lib as a possible (and effective) workaround.

    opened by vitiral 7
  • Check for duplicated dependencies in Travis

    Check for duplicated dependencies in Travis

    This currently fails though. :crying_cat_face:

    bitflags v0.8.2
    โ”œโ”€โ”€ clap v2.24.2
    โ”‚   โ””โ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx)
    โ””โ”€โ”€ openssl v0.9.12
        โ””โ”€โ”€ native-tls v0.1.2
            โ””โ”€โ”€ hyper-native-tls v0.2.2
                โ””โ”€โ”€ reqwest v0.6.2
                    โ””โ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx) (*)
    
    bitflags v0.9.0
    โ””โ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx)
    
    serde v0.9.15
    โ””โ”€โ”€ ndarray v0.9.1
        โ””โ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx)
    
    serde v1.0.7
    โ”œโ”€โ”€ chrono v0.3.1
    โ”‚   โ””โ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx)
    โ”œโ”€โ”€ reqwest v0.6.2
    โ”‚   โ””โ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx) (*)
    โ”œโ”€โ”€ serde_json v1.0.2
    โ”‚   โ”œโ”€โ”€ reqwest v0.6.2 (*)
    โ”‚   โ””โ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx) (*)
    โ”œโ”€โ”€ serde_urlencoded v0.5.1
    โ”‚   โ””โ”€โ”€ reqwest v0.6.2 (*)
    โ”œโ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx) (*)
    โ””โ”€โ”€ toml v0.4.1
        โ””โ”€โ”€ stdx v0.117.0-rc (file:///home/travis/build/brson/stdx) (*)
    
    opened by dtolnay 4
  • bump toml version to 0.4.5 allow use of pretty strings

    bump toml version to 0.4.5 allow use of pretty strings

    toml 0.4.5 stabilized pretty strings which is a pretty useful feature.

    vitiral/artifact#164 needs this to consume stdx

    opened by vitiral 4
  • Add itertools to stdx

    Add itertools to stdx

    Added example for itertools crate

    Fix to issue #15

    opened by alisha17 4
  • Add walkdir to stdx

    Add walkdir to stdx

    Example for walkdir added

    Fix to issue #32

    opened by alisha17 3
  • Add fnv to stdx

    Add fnv to stdx

    fnv crate example using FNV HashMap

    Fix to issue #34

    opened by alisha17 3
  • Clarify reasons for using `json` crate

    Clarify reasons for using `json` crate

    Here is your json example from the readme rewritten using serde_json. The differences are one type ascription ("let parsed: Value") and a slightly friendlier JSON literal syntax.

    I think the readme should show an example that better plays to json's strengths, or else omit this crate since serde and serde_json are already included.

    #[macro_use]
    extern crate serde_json;
    
    use serde_json::Value;
    
    fn main() {
        let parsed: Value = serde_json::from_str(r#"
    {
        "code": 200,
        "success": true,
        "payload": {
            "features": [
                "awesome",
                "easyAPI",
                "lowLearningCurve"
            ]
        }
    }
    
    "#).unwrap();
    
        let instantiated = json!({
            "code": 200,
            "success": true,
            "payload": {
                "features": [
                    "awesome",
                    "easyAPI",
                    "lowLearningCurve"
                ]
            }
        });
    
        assert_eq!(parsed, instantiated);
    }
    
    opened by dtolnay 3
  • Add fnv to stdx

    Add fnv to stdx

    See https://github.com/brson/stdx/blob/master/CONTRIBUTING.md for details on how to add a crate.

    help wanted easy 
    opened by brson 2
  • Fix typo

    Fix typo

    opened by Hendrikto 0
  • crossbeam inclusion

    crossbeam inclusion

    I feel like crossbeam might be a valuable part of this library. A lot of its functionality is intended to be better alternatives to the threading support in the Rust std library

    opened by Zaechus 0
  • thoghts on stdcli crate built on top of this?

    thoghts on stdcli crate built on top of this?

    I left a comment on reddit but wanted your feedback.

    I've been thinking about ways we can make cli development even easier and I think having a stdcli crate that does use stdx::* but also includes more libraries for writing cli's would be AMAZING. This would be built on top of stdx but have libraries specific for developing scripts and cli's.

    Some other libraries that would be useful that stdx doesn't (and shouldn't) have:

    • cargo-script: this wouldnt be in stdcli, but is an important one to know! Quickly write and run cli scripts with crate caching.
    • structopt_derive: simpler and more intuititive than clap, uses clap underneath.
    • tabwriter easy formatting of data into a table using \t character for alignment
    • self_update: auto update/upgrade the compiled binary
    • ansi_term: colors in the terminal
    • fern: easier logging for clis
    • fs_extra: to remove some of your tiny functions
    • ctrlc: easy handling of unix AND windows signals
    opened by vitiral 0
  • Include uuid

    Include uuid

    I was a bit surprised to not find uuid in here yet.

    It's pretty widely used and managed by alexcrichton, so I'd recommend including it.

    https://github.com/rust-lang-nursery/uuid/

    Regarding features to enable by default, I'd vote for features = ["v1", "v4", "serde"].

    v4 is by far the most widely used, and only depends on rand, which does not add a new dependency. v1 also only needs rand, so just enabling it seems reasonable.

    If it's fine with you, @brson , I'll whip up a PR with examples.

    opened by theduke 0
  • Do not duplicate example code in README

    Do not duplicate example code in README

    It feels clumsy having to maintain copies of the same code (examples/ and README). Also, that README is rather large with all those examples. How about just linking to the examples?

    opened by tshepang 3
  • Relicense to CC0?

    Relicense to CC0?

    Like cookbook stdx is largely a collection of examples meant to be used freely, and cookbook looks like it will be relicensed CC0.

    opened by brson 0
  • Add either crate

    Add either crate

    This is a relatively simple crate that could be a good addition.

    opened by clarfonthey 3
  • `memmap` example in `README.md` contains undefined behavior

    `memmap` example in `README.md` contains undefined behavior

    I think that the example in the README.md of memmap contains a race condition which can lead to undefined behavior:

    extern crate memmap;
    
    use memmap::{Mmap, Protection};
    use std::env;
    use std::io;
    use std::str;
    
    fn run() -> Result<(), io::Error> {
        let mut args = env::args().skip(1);
        let input = args.next().expect("incorrect argument");
    
        let map = Mmap::open_path(input, Protection::Read)?;
        unsafe {
            let all_bytes = map.as_slice();
            if let Ok(file_str) = str::from_utf8(all_bytes) {
                println!("{}", file_str);
            } else {
                println!("not utf8");
            }
        }
        Ok(())
    }
    

    If the file changes after the UTF-8 check, the program prints a &str that contains non-UTF-8 bytes.

    opened by tbu- 3
  • Set up testing of every stdx crate

    Set up testing of every stdx crate

    As part of stdx's validation mission, it should be testing that the exact crate revisions it is promoting really do work on all tier-1 platforms.

    Probably the way to do this is to set up another crate inside the repo called stdx-validate (or something) that has a build script that generates a custom test suite. This test suite will parse the stdx Cargo.toml to retrieve the exact version of every crate in stdx, download those crates, frob them to make them work correctly, and run their test suites.

    This test suite should probably also verify that, if the crate has a dependency on another crate in stdx, it is tested with the version specified by stdx, not some arbitrary version.

    Then set up CI for tier 1 platforms.

    enhancement help wanted 
    opened by brson 2
  • Create stdx-check tool

    Create stdx-check tool

    One of the main roles I have in mind for stdx is as tool to measure the compatibility of the larger ecosystem. The stdx-check tool determine whether any given crate was 'compatible' with stdx, serving two purposes:

    • By running stdx-check across every crate on crates.io (using cargobomb probably), we could say what percent is compatible, which would inform the development of stdx, and also give users confidence that stdx is actually leading them down the right path.
    • Users could run stdx-check on their own crates, to validate their stdx compatibility

    At the most basic level I imagine it doing the following:

    • Rewriting ./Cargo.toml to add the a stdx dependency (from git for now perhaps), outputting to Cargo-stdx.toml
    • Running cargo test on the new manifest to see if it passes
    • Inspecting the generated lockfile to see if any of the stdx crates have dupes.

    Other nice follow on work:

    • Support multiple stdx revisions, probably by include_string their tomls
    • Verify a crate directly off of crates.io, which would require frobbing their Cargo.tomls.
    • Write a tool that runs stdx-check across a list of crates.io crates and generates a report with the results, indicating stdx ecosystem compatibility.
    help wanted 
    opened by brson 9
Owner
Brian Anderson
Brian Anderson
Leetcode Solutions in Rust, Advent of Code Solutions in Rust and more

RUST GYM Rust Solutions Leetcode Solutions in Rust AdventOfCode Solutions in Rust This project demostrates how to create Data Structures and to implem

Larry Fantasy 197 Sep 11, 2021
A bunch of links to blog posts, articles, videos, etc for learning Rust

rust-learning A bunch of links to blog posts, articles, videos, etc for learning Rust. Feel free to submit a pull request if you have some links/resou

Camille TJHOA 7.1k Sep 15, 2021
Write Cloudflare Workers in 100% Rust via WebAssembly

Work-in-progress ergonomic Rust bindings to Cloudflare Workers environment. Write your entire worker in Rust! Read the Notes and FAQ Example Usage use

Cloudflare 393 Sep 14, 2021
A catalogue of Rust design patterns, anti-patterns and idioms

Rust Design Patterns An open source book about design patterns and idioms in the Rust programming language that you can read here. Contributing You ar

null 5.3k Sep 15, 2021
Experimental Quantum Computer Simulator + Quantum Chess Implementation

Quantum Chess A somewhat hacky implementation of this paper (made in a week over a holiday). It's not heavily tested and probably has some bugs still

null 18 Feb 10, 2021
List of Rust books

Rust Books Books Starter Books Advanced Books Resources Books Starter Books The Rust Programming Language Free Welcome! This book will teach you about

Spiros Gerokostas 1.4k Sep 10, 2021
A peer-reviewed collection of articles/talks/repos which teach concise, idiomatic Rust.

This repository collects resources for writing clean, idiomatic Rust code. Please bring your own. ?? Idiomatic coding means following the conventions

Matthias 2.8k Sep 10, 2021
:crab: Small exercises to get you used to reading and writing Rust code!

rustlings ?? โค๏ธ Greetings and welcome to rustlings. This project contains small exercises to get you used to reading and writing Rust code. This inclu

The Rust Programming Language 18.9k Sep 16, 2021
a cheat-sheet for mathematical notation in Rust ๐Ÿฆ€ code form

math-as-rust ?? Based on math-as-code This is a reference to ease developers into mathematical notation by showing comparisons with Rust code.

Eduardo Pereira 9 Sep 12, 2021
Rust ๆ ธๅฟƒๅบ“ๅ’Œๆ ‡ๅ‡†ๅบ“็š„ๆบ็ ็บงไธญๆ–‡็ฟป่ฏ‘๏ผŒๅฏไฝœไธบ IDE ๅทฅๅ…ท็š„ๆ™บ่ƒฝๆ็คบ (Rust core library and standard library translation. can be used as IntelliSense for IDE tools)

Rust ๆ ‡ๅ‡†ๅบ“ไธญๆ–‡็‰ˆ ่ฟ™ๆ˜ฏ็ฟป่ฏ‘ Rust ๅบ“ ็š„ๅœฐๆ–น๏ผŒ ็›ธๅ…ณๆบไปฃ็ ๆฅ่‡ชไบŽ https://github.com/rust-lang/rustใ€‚ ๅฆ‚ๆžœๆ‚จไธไผš่ฏด่‹ฑ่ฏญ๏ผŒ้‚ฃไนˆๆ‹ฅๆœ‰ไฝฟ็”จไธญๆ–‡็š„ๆ–‡ๆกฃ่‡ณๅ…ณ้‡่ฆ๏ผŒๅณไฝฟๆ‚จไผš่ฏด่‹ฑ่ฏญ๏ผŒไฝฟ็”จๆฏ่ฏญไนŸไป็„ถ่ƒฝ่ฎฉๆ‚จๆ„Ÿๅˆฐๆ„‰ๅฟซใ€‚Rust ๆ ‡ๅ‡†ๅบ“ๆ˜ฏ้ซ˜่ดจ้‡็š„๏ผŒไธ็ฎกๆ˜ฏๆ–ฐๆ‰‹่ฟ˜ๆ˜ฏ่€ๆ‰‹๏ผŒ้ƒฝๅฏไปฅไปŽไธญ

wtklbm 216 Sep 13, 2021
A Collection of Rust Tips and Tricks

Table of Contents Using Nested Paths in Rust Struct Update Syntax in Rust Field Init Shorthand in Rust Shadowing in Rust Using Nested Paths in Rust So

Vandad Nahavandipoor 14 Sep 3, 2021
Yet another trojan-gfw in Rust

Trojan-rust Yet another trojan-gfw implementation in Rust. Features Server mode only (for now). Supports Redis auth & flow stat. Uses OpenSSL as crypt

็ฒ’็ฒ’ๆฉ™ 25 Aug 11, 2021
The source code that accompanies Hands-on Rust: Effective Learning through 2D Game Development and Play by Herbert Wolverson

Hands-on Rust Source Code This repository contains the source code for the examples found in Hands-on Rust. These are also available from my publisher

Herbert 76 Sep 11, 2021
Raytracer tutorial for PPCA 2021, written in Rust.

Pseudo Photograph Company of ACM ๅทฅ็ง‘ๅ’ŒACM็š„ๆœ‹ๅ‹ไปฌ้ƒฝๅทฒ็ป“่ฏพ๏ผ็œ‹็œ‹่ฟ™ไบ›ไบ†ไธ่ตท็š„่‰บๆœฏๅ“๏ผš ๅทฅ็ง‘ ACM ACMไผชๆ‘„ๅฝฑๅ…ฌๅธ๏ผŒ็ฎ€็งฐPPCA๏ผŒไบŽ2021ๅนดๆˆ็ซ‹ ?? ่ฟ™ไธช้กน็›ฎ็š„ไธป่ฆๅทฅไฝœๆ˜ฏไฝฟ็”จRust่ฏญ่จ€ๅฎž็Žฐไธ€ไธชๅ…‰็บฟ่ฟฝ่ธชๆธฒๆŸ“ๅ™จใ€‚ไปฅ่ฟ™ไธชๅฝขๅผ๏ผŒไฝ ่ƒฝ้€š่ฟ‡ๅญฆไน ไธ€้—จๆ–ฐ็š„๏ผˆ่€Œไธ”ๆผ‚ไบฎ็š„๏ผ‰่ฏญ

null 98 Sep 2, 2021
Trying embedded Rust on the Pinecil GD32VF103 RISC-V device.

Pinecil GD32VF103 RISC-V Rust Demos My personal collection of Rust demos running on the PINE64 Pinecil portable soldering iron, featuring a GD32VF103T

alvinhochun 18 Jul 7, 2021
Rust programs written entirely in Rust

mustang Programs written entirely in Rust Mustang is a system for building programs built entirely in Rust, meaning they do not depend on any part of

Dan Gohman 290 Sep 14, 2021
The best Intermediate Rust course out there!

Ultimate Rust 2: Intermediate Concepts This is the companion repository for the Ultimate Rust 2: Intermediate Concepts (the followup to the popular Ul

Nathan Stocks 19 Aug 19, 2021
A community curated list of Rust Language streamers

Awesome Rust Streaming This is a community curated list of livestreams about the programming language Rust. Don't see a stream that you like? Feel fre

James Munns 470 Sep 12, 2021
ใ€ŒRustใงใ‚‚ใ‚ใ‹ใ‚‹ใ‚ทใ‚นใƒ†ใƒ ใƒ—ใƒญใ‚ฐใƒฉใƒŸใƒณใ‚ฐใ€

learning-systems-programming-in-rust ใ€ŽGo ใชใ‚‰ใ‚ใ‹ใ‚‹ใ‚ทใ‚นใƒ†ใƒ ใƒ—ใƒญใ‚ฐใƒฉใƒŸใƒณใ‚ฐใ€ใ‚’ Rust ใงๆ›ธใ็›ดใ™ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใ€ใใฎๅใ‚‚ใ€ŒRust ใชใ‚‰ใ‚ใ‹ใ‚‹ใ‚ทใ‚นใƒ†ใƒ ใƒ—ใƒญใ‚ฐใƒฉใƒŸใƒณใ‚ฐใ€ใ€‚ ใ“ใ‚Œใฏไฝ• ใ€ŽGo ใชใ‚‰ใ‚ใ‹ใ‚‹ใ‚ทใ‚นใƒ†ใƒ ใƒ—ใƒญใ‚ฐใƒฉใƒŸใƒณใ‚ฐใ€๏ผˆๆธ‹ๅทใ‚ˆใ—ใ่‘—๏ผ‰ๅ†…ใซๆ›ธใ‹ใ‚Œใฆใ„ใ‚‹ G

Yuki Toyoda 349 Sep 15, 2021