Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/stdxPublic

The missing batteries of Rust

NotificationsYou must be signed in to change notification settings

brson/stdx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This project is unmaintained. For a similar project seerustmax.

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.

FeatureCrate
Bitfieldsbitflags = "0.9.1"📖
Byte order conversionbyteorder = "1.1.0"📖
Date and timechrono = "0.4.0"📖
Command-line argument parsingclap = "2.25.0"📖
Encoding/decodingencoding_rs = "0.6.11"📖
Error handlingerror-chain = "0.10.0"📖
Fast hashingfnv = "1.0.5"📖
Compression - deflate (gzip)flate2 = "0.2.19"📖
Iterator functions, macrositertools = "0.6.0"📖
Global initializationlazy_static = "0.2.8"📖
C interoplibc = "0.2.25"📖
Logginglog = "0.3.8"📖
Memory-mapped file I/Omemmap = "0.5.2"📖
Multidimensional arraysndarray = "0.9.1"📖
Big, rational, complex numbersnum = "0.1.40"📖
Number of CPUsnum_cpus = "1.6.2"📖
Random numbersrand = "0.3.15"📖
Parallel iterationrayon = "0.8.2"📖
Regular expressionsregex = "0.2.2"📖
HTTP clientreqwest = "0.7.1"📖
Software versioningsemver = "0.7.0"📖
Serializationserde = "1.0.10"📖
JSONserde_json = "1.0.2"📖
Tar archivestar = "0.4.23"📖
Temporary directoriestempdir = "0.3.5"📖
Thread poolthreadpool = "1.4.0"📖
Configuration filestoml = "0.4.2"📖
URLsurl = "1.5.1"📖
Directory traversalwalkdir = "1.0.7"📖

   

bitflags = "0.9.1"📖

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

Example:examples/bitflags.rs

#[macro_use]externcrate bitflags;bitflags!{structFlags:u32{constFLAG_A       =0b00000001;constFLAG_B       =0b00000010;constFLAG_C       =0b00000100;constFLAG_ABC     =FLAG_A.bits                           |FLAG_B.bits                           |FLAG_C.bits;}}fnmain(){let e1 =FLAG_A |FLAG_C;let e2 =FLAG_B |FLAG_C;assert_eq!((e1 | e2),FLAG_ABC);// unionassert_eq!((e1& e2),FLAG_C);// intersectionassert_eq!((e1 - e2),FLAG_A);// set differenceassert_eq!(!e2,FLAG_A);// set complement}

   

byteorder = "1.1.0"📖

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

Example:examples/byteorder.rs

externcrate byteorder;use std::io::Cursor;use byteorder::{BigEndian,ReadBytesExt};use byteorder::{LittleEndian,WriteBytesExt};fnmain(){// Read unsigned 16 bit big-endian integers from a Read type:letmut 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:letmut 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

externcrate chrono;use chrono::*;fnmain(){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 touse and is highly configurable.

Example:examples/clap.rs

externcrate clap;use clap::{Arg,App,SubCommand};fnmain(){let app =App::new("My Super Program").version("1.0").author("Kevin K. <kbknapp@gmail.com>").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 argumentslet matches = app.get_matches();let config = matches.value_of("config").unwrap_or("default.conf");let input = matches.value_of("INPUT").unwrap();// Handle subcommandsmatch 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 Sourceimplementation of the Encoding Standard in Rust. Gecko-oriented meansthat converting to and from UTF-16 is supported in addition toconverting to and from UTF-8, that the performance and streamabilitygoals are browser-oriented, and that FFI-friendliness is a goal.

Example:examples/encoding_rs.rs

externcrate encoding_rs;use encoding_rs::*;fnmain(){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 understandserror handling in Rust, it can bedifficult to grasp and implement its best practices.error-chainhelps you define your own error type that works with the? operatorto make error handling in Rust simple and elegant.

Example:examples/error-chain.rs

// `error_chain!` can recurse deeply#![recursion_limit ="1024"]#[macro_use]externcrate 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 typeserror_chain!{}}use errors::*;fnmain(){ifletErr(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 ein 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`.ifletSome(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`.fnrun() ->Result<()>{use std::fs::File;// Use chain_err to attach your own context to errorsFile::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 theDEFLATE algorithm.

Example:examples/flate2.rs

externcrate flate2;externcrate tar;use flate2::read::GzDecoder;use std::env;use std::fs::File;use std::io::{self,BufReader};use tar::Archive;fnrun() ->Result<(), io::Error>{letmut 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)?;letmut archive =Archive::new(archive);    archive.unpack(outdir)?;Ok(())}fnmain(){run().unwrap()}

   

fnv = "1.0.5"📖

The standard library's hash maps are notoriously slow for small keys (likeintegers). That's because they provide strong protection against a class ofdenial-of-service attacks called"hash flooding". And that's a reasonabledefault. But when yourHashMaps are a bottleneck consider reaching for thiscrate. It provides the Fowler-Noll-Vo hash function, and conveniences forcreating FNV hash maps that are considerably faster than those in std.

Example:examples/fnv.rs

externcrate fnv;use fnv::FnvHashMap;fnmain(){letmut 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 standardIterator type provides a powerful abstraction foroperating over sequences of values, and is used pervasively throughoutRust. There are though a number of common operations one might want to performon sequences that are not provided by the standard library, and that's whereitertools comes in. This crate has everythingincluding the kitchen sink (inthe form of thebatching adaptor). Highlights includededup,group_by,mend_slices,merge,sorted,join and more.

Example:examples/itertools.rs

externcrate itertools;use itertools::{join, max, sorted};fnmain(){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 particularthere is no'life before main' in Rust, so it's not possible towrite a programmatic constructor for a global value that will be runat startup. Instead, Rust prefers lazy execution for globalinitialization, and thelazy_static! macro does just that.

Example:examples/lazy_static.rs

#[macro_use]externcrate lazy_static;use std::collections::HashMap;lazy_static!{static refHASHMAP:HashMap<u32,&'staticstr> ={letmut m =HashMap::new();        m.insert(0,"foo");        m.insert(1,"bar");        m.insert(2,"baz");        m};static refCOUNT:usize =HASHMAP.len();static refNUMBER:u32 = times_two(21);}fntimes_two(n:u32) ->u32{ n*2}fnmain(){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 Ctype and function definitions appropriate to each target platform Rustsupports. It defines the standardized C features that are commonacross all platforms as well as non-standard features specific to theplatform C libraries. For more platform-specific FFI definitionsseenix andwinapi.

Example:examples/libc.rs

externcrate libc;fnmain(){unsafe{        libc::exit(0);}}

   

log = "0.3.8"📖

The most common way to perform basic logging in Rust, with theerror!,warn!,info!, anddebug! macros. It is oftencombined with theenv_logger crate to get logging to the console,controlled by theRUST_LOG environment variable. This is thetraditional logging crate used byrustc, and its functionality wasonce built in to the language.

Supplemental crates:env_logger = "0.4.3"

Example:examples/log.rs

#[macro_use]externcrate log;externcrate env_logger;use log::LogLevel;fnmain(){    env_logger::init().unwrap();debug!("this is a debug {}","message");error!("this is printed by default");iflog_enabled!(LogLevel::Info){let x =3*4;// expensive computationinfo!("the answer was: {}", x);}}

Alternatives:slog,log4rs

   

memmap = "0.5.2"📖

Cross-platform access tomemory-mapped I/O, a technique for sharingmemory between processes, and for accessing the content of files as asimple array of bytes. It is implemented by binding themmapsyscall on Unix, and theCreateFileMapping /MapViewOfFilefunctions on Windows. This is a low-level feature used to build otherabstractions. Note that it's not generally possible to create safeabstractions for memory mapping, since memory mapping entails sharedaccess to resources outside of Rust's control. As such, the APIsin this crate are unsafe.

Example:examples/memmap.rs

externcrate memmap;use memmap::{Mmap,Protection};use std::env;use std::io;use std::str;fnrun() ->Result<(), io::Error>{letmut 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();ifletOk(file_str) = str::from_utf8(all_bytes){println!("{}", file_str);}else{println!("not utf8");}}Ok(())}fnmain(){run().unwrap()}

   

ndarray = "0.9.1"📖

The ndarray crate provides an N-dimensional container for generalelements and for numerics. The multidimensional array, otherwise knownas 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)]externcrate ndarray;use ndarray::{Array3, arr3};fnmain(){// Create a three-dimensional f64 array, initialized with zerosletmut 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 arrayassert_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 numerictraits. This crate has a long history, beginning life in the standardlibrary, being moved into the rust-lang organization, and finallybeing adopted by community maintainers. It remains a common way toaccess the kinds of features it provides.

Example:examples/num.rs

externcrate num;use num::FromPrimitive;use num::bigint::BigInt;use num::rational::{Ratio,BigRational};fnapprox_sqrt(number:u64,iterations:usize) ->BigRational{let start:Ratio<BigInt>        =Ratio::from_integer(FromPrimitive::from_u64(number).unwrap());letmut approx = start.clone();for _in0..iterations{        approx =(&approx +(&start /&approx)) /Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());}    approx}fnmain(){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 CPUsto use! This is the simple way to get that information.

Example:examples/num_cpus.rs

externcrate threadpool;externcrate num_cpus;use threadpool::ThreadPool;use std::sync::mpsc::channel;fnmain(){// Get the number of cpus on current machinelet n_workers = num_cpus::get();let n_jobs =8;// Create the thread pool with amount of workers equal to coreslet pool =ThreadPool::new(n_workers);// Create transmitter and receiver channellet(tx, rx) =channel();// For each job grab a free worker from the pool and executefor _in0..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 cryptographicallystrong. This is another crate with a long history, beginning life inthe standard library.

Example:examples/rand.rs

externcrate rand;use rand::Rng;fnmain(){letmut rng = rand::thread_rng();if rng.gen(){// random boolprintln!("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. Rayonprovides parallel iterators that make expressing efficient paralleloperations simple and foolproof.

Example:examples/rayon.rs

externcrate rayon;use rayon::prelude::*;fnmain(){letmut input =(0..1000).collect::<Vec<_>>();// Calculate the sum of squareslet 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 quicksortletmut input =(0..1000).rev().collect::<Vec<_>>();quick_sort(&mut input);}fnquick_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));}fnpartition<T:PartialOrd +Send>(v:&mut[T]) ->usize{let pivot = v.len() -1;letmut i =0;for jin0..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 arefast, like Rust is fast. Part oftheir power comes from a careful design that disallows back-referencesand arbitrary lookahead, creating predictable worst-case performance.

Example:examples/regex.rs

externcrate regex;use regex::Regex;fnmain(){// Find a datelet re =Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();assert!(re.is_match("2014-01-01"));// Iterating over capture groupslet re =Regex::new(r"(\d{4})-(\d{2})-(\d{2})").unwrap();let text ="2012-03-14, 2013-01-01 and 2014-07-05";for capin 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 HTTPimplementation,hyper, which is the HTTP stack developed forServo.

Example:examples/reqwest.rs

externcrate reqwest;use std::collections::HashMap;use std::io::{BufRead,BufReader};fnmain(){// Make a GET requestlet 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 linein lines{println!("{}", line);}// Make a POST requestlet 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 automaticallyletmut 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 usessemantic versioning (also known as "semver") forcrate versioning. This crate provides the canonical semverrepresentation for Rust.

Example:examples/semver.rs

externcrate semver;use semver::Version;fnmain(){// Construct Version objectsassert!(Version::parse("1.2.3") ==Ok(Version{        major:1,        minor:2,        patch:3,        pre: vec!(),        build: vec!(),}));// Compare Versionsassert!(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 Versionletmut 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 fastand easy using theserde serialization framework. Simplytag your data structures with#[derive(Serialize, Deserialize)]and serde will automatically convert them between formats likeJSON, TOML, YAML, and more. To best understand serde, readits documentation atserde.rs.

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

Example:examples/serde.rs

#[macro_use]externcrate serde_derive;externcrate serde_json;use serde_json::Value;#[derive(Serialize,Deserialize,Debug)]structContact{name:String,age:u32,}fnmain(){let contact =Contact{name:"Brian".to_string(),age:21,};// Serialize data structures to strings in JSON formatlet contact:String = serde_json::to_string(&contact).unwrap();println!("{}", contact);// Deserialize data structures from JSON stringslet contact:Contact = serde_json::from_str(&contact).unwrap();println!("{:?}", contact);// Convert to arbitrary JSON `Value` typelet contact:Value = serde_json::to_value(&contact).unwrap();println!("{:?}", contact);}

Alternatives:rustc-serialize

   

serde_json = "1.0.2"📖

Access toJSON, 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 manipulationof arbitrary JSON in addition to its use for automatic serializationwithserde.

Example:examples/json.rs

externcrate serde_json;use serde_json::Value;fnmain(){// 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 oftenfound in the form of.tar.gz files (called "tarballs") that havebeen compressed with theDEFLATE algorithm, which thetar cratecan decompress when paired with theflate2 crate.

Example:examples/tar.rs

externcrate flate2;externcrate tar;use flate2::read::GzDecoder;use std::env;use std::fs::File;use std::io::{self,BufReader};use tar::Archive;fnrun() ->Result<(), io::Error>{letmut 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)?;letmut archive =Archive::new(archive);    archive.unpack(outdir)?;Ok(())}fnmain(){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

externcrate tempdir;use std::fs::File;use std::io::Write;use tempdir::TempDir;fnmain(){// 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");letmut 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

externcrate threadpool;externcrate num_cpus;use threadpool::ThreadPool;use std::sync::mpsc::channel;fnmain(){// Get the number of cpus on current machinelet n_workers = num_cpus::get();let n_jobs =8;// Create the thread pool with amount of workers equal to coreslet pool =ThreadPool::new(n_workers);// Create transmitter and receiver channellet(tx, rx) =channel();// For each job grab a free worker from the pool and executefor _in0..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 forconfiguration files, likeCargo.toml. It's easy on the eyes, simpleto parse, and serializes from Rust types withserde.

Example:examples/toml.rs

externcrate toml;use toml::Value;fnmain(){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 forServo.

Example:examples/url.rs

externcrate url;use url::{Url,Host};fnmain(){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 directoryrecursively. Note thefilter_entry method on the directoryiterator that short-circuits decent into subdirectories.

Example:examples/walkdir.rs

externcrate walkdir;use walkdir::{WalkDir,Error};fnrun() ->Result<(),Error>{let wd =WalkDir::new(".");for entryin wd{let entry = entry?;println!("{}", entry.path().display());}Ok(())}fnmain(){run().unwrap();}

   

Aboutstdx

Rust has a lovely and portable standard library, but it is notfeatureful enough to write software of any greatsophistication. 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 oncrates.io. This affords the Rust community freedom to experiment -discovering the Rustiest solutions to even common problems can takequite some iteration - but it also means that we're in for a slowevolutionary process to converge around the best of those solutions. Inthe meantime, you just have to know which crates to use for what.

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

How to usestdx

stdx is primarily a teaching tool. New and old Rust programmersalike will get the most from it by digestingthe list ofstdx crates, each entry of which links to a description of the cratealong withan example of its basic use.

These examples are full working source and are intended to get youup and running with any of thestdx cratesimmediately. Justcopy the crate name and version exactly as written into thedependenciessection of yourCargo.toml like so:

[dependencies]bitflags ="0.9.1"

Then copy the full example into yourexamples directory, likeso:

Example:examples/bitflags.rs

#[macro_use]externcrate bitflags;bitflags!{structFlags:u32{constFLAG_A       =0b00000001;constFLAG_B       =0b00000010;constFLAG_C       =0b00000100;constFLAG_ABC     =FLAG_A.bits                           |FLAG_B.bits                           |FLAG_C.bits;}}fnmain(){let e1 =FLAG_A |FLAG_C;let e2 =FLAG_B |FLAG_C;assert_eq!((e1 | e2),FLAG_ABC);// unionassert_eq!((e1& e2),FLAG_C);// intersectionassert_eq!((e1 - e2),FLAG_A);// set differenceassert_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 usestdx?

As a learning tool, I hope the benefit will be evident from a straightread-through. Butstdx, and tools like it, may provide importantbenefits to users in the future.

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

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

As of now, the only validationstdx provides is that the exactversions of thestdx crates resolve correctly by Cargo, and thatthey build on Linux and Windows. That is already beneficial byuncovering problematic combinations and incorrect semverspecifications. Here are some other assurances thatstdx willenable:

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

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

Selection criteria

The criteria for inclusion instdx is conservative, and fuzzy. It'smostly crates that are pretty super important, considering criterialike

  • 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 quintessentiallyRust and relied on by many Rust programs. It is intentionallylimited 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

SeeCONTRIBUTING.md.

License

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

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

About

The missing batteries of Rust

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp