mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-10 06:04:20 +00:00
Various restructuring
This commit is contained in:
parent
085cb40f67
commit
7bd8dd1062
26 changed files with 326 additions and 204 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
|||
target
|
||||
*~
|
||||
book/
|
||||
|
||||
*.swp
|
||||
|
|
|
@ -25,18 +25,47 @@ TODO: Fixing bugs
|
|||
TODO: Pull requests
|
||||
|
||||
## Crates
|
||||
TODO: How to add new crates to project
|
||||
|
||||
All crates used by the cookbook are listed in Cargo.toml. If you are
|
||||
adding a new crate, first add it there.
|
||||
|
||||
## Tests
|
||||
TODO: Write about writing tests
|
||||
|
||||
All examples are tested using [`skeptic`]. Run them with `cargo test`.
|
||||
|
||||
[`skeptic`]: https://github.com/brson/rust-skeptic
|
||||
|
||||
## Style
|
||||
https://aturon.github.io
|
||||
|
||||
### Git Commit Messages
|
||||
https://chris.beams.io/posts/git-commit/
|
||||
TODO: Possibly take relevant parts from this post or write our own
|
||||
|
||||
### Snippet Style
|
||||
TODO: Talk about writing good idiomatic code
|
||||
TODO: Maybe provide a template?
|
||||
|
||||
Snippets are intended to be read by complete beginners, and copied
|
||||
into projects for experimentation. They should follow best practices.
|
||||
|
||||
Snippets should have a simple single-sentence description
|
||||
that describes something a typical Rust user typically wants to do.
|
||||
|
||||
The snippet should have minimal code that doesn't directly support the
|
||||
description of the snippet. Keep extra functions and types to a
|
||||
minimum.
|
||||
|
||||
Follow the template in [src/error_handling_note.md]. Examples always
|
||||
set up error handling correctly and propagate errors with `?` (not
|
||||
`try!`).
|
||||
|
||||
Don't use glob imports, even for preludes.
|
||||
|
||||
Sort imports.
|
||||
|
||||
Describe the code in prose, not in comments. Things that should be
|
||||
described include any traits imported and their methods used. Think
|
||||
about what information here supports the use case and might not be
|
||||
obvious to someone new. Say the minimum possible about aspects that
|
||||
don't directly support the use case. See [basics.md] for examples.
|
||||
|
||||
Hyperlink all references to APIs, and style them as `code`.
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ function main() {
|
|||
elif [ $(program_installed mdbook) == 0 ]; then
|
||||
echo "Please install mdbook: cargo install mdbook."
|
||||
else
|
||||
echo "Copying CONTRIBUTING.md to src/pages/contributing.md"
|
||||
cp CONTRIBUTING.md src/pages/contributing.md
|
||||
echo "Building site to book/"
|
||||
mdbook build
|
||||
echo "Copying assets/* to book/"
|
||||
|
|
2
build.rs
2
build.rs
|
@ -3,7 +3,7 @@ extern crate skeptic;
|
|||
use std::fs;
|
||||
|
||||
fn main() {
|
||||
let paths = fs::read_dir("./src/pages/").unwrap()
|
||||
let paths = fs::read_dir("./src/").unwrap()
|
||||
// convert paths to Strings
|
||||
.map(|p| p.unwrap().path().to_str().unwrap().to_string())
|
||||
// only compile markdown files
|
||||
|
|
|
@ -1,22 +1,8 @@
|
|||
# Summary
|
||||
|
||||
[Table of Contents](pages/table_of_contents.md)
|
||||
[A Note About Error Handling](pages/error_handling_note.md)
|
||||
[Table of Contents](intro.md)
|
||||
[A Note About Error Handling](error_handling_note.md)
|
||||
|
||||
- [Math](pages/math.md)
|
||||
- [rand](pages/rand.md)
|
||||
- [petgraph](pages/petgraph.md)
|
||||
- [crossbeam](pages/crossbeam.md)
|
||||
- [Algorithms](pages/algorithms.md)
|
||||
- [IO](pages/IO.md)
|
||||
- [File IO](pages/file_io.md)
|
||||
- [Command Line Parsing](pages/cli_parsing.md)
|
||||
- [Serialization](pages/serialization.md)
|
||||
- [Byteorder](pages/byteorder.md)
|
||||
- [JSON](pages/json.md)
|
||||
- [TOML](pages/toml.md)
|
||||
- [Networking](pages/networking.md)
|
||||
- [Concurrency](pages/concurrency.md)
|
||||
- [Rayon](pages/rayon.md)
|
||||
|
||||
[Contributing](pages/contributing.md)
|
||||
- [Basics](basics.md)
|
||||
- [Concurrency]
|
||||
- [Application development]
|
||||
|
|
148
src/basics.md
Normal file
148
src/basics.md
Normal file
|
@ -0,0 +1,148 @@
|
|||
# Basics
|
||||
|
||||
| Recipe | Crates | Categories |
|
||||
|--------|--------|------------|
|
||||
| [Read lines of strings from a file][ex-std-read-lines] | [![std-badge]][std] | [![cat-file-io-badge]][cat-file-io] |
|
||||
| [Read and write integers in little-endian byte order][ex-byteorder-le] | [![byteorder-badge]][byteorder] | [![cat-serialization-badge]][cat-serialization] |
|
||||
| [Generate random floating point numbers][ex-rand-float] | [![rand-badge]][rand] | [![cat-math-badge]][cat-math] |
|
||||
| [Generate random values on a custom type][ex-rand-custom] | [![rand-badge]][rand] | [![cat-math-badge]][cat-math] |
|
||||
| [Construct a graph of objects][ex-petgraph-basic] | [![petgraph-badge]][petgraph] | [![cat-math-badge]][cat-math] |
|
||||
|
||||
<a name="ex-std-read-lines"/>
|
||||
## Read lines of strings from a file
|
||||
|
||||
[![std-badge]][std] [![cat-file-io-badge]][cat-file-io]
|
||||
|
||||
Writes a three-line message to a file, then reads it back a line at a
|
||||
time with the [`Lines`] iterator created by
|
||||
[`BufRead::lines`]. [`BufRead`] is a trait, and the most common way to
|
||||
get one is from a [`BufReader`], which is constructed from some type
|
||||
that implements [`Write`], here a [`File`]. The [`File`] is opened
|
||||
for writing with [`File::create`], and reading with [`File::open`].
|
||||
|
||||
```rust
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write, BufReader, BufRead};
|
||||
|
||||
fn run() -> io::Result<()> {
|
||||
|
||||
write!(File::create("lines.txt")?, "Rust\n💖\nFun")?;
|
||||
|
||||
let file = File::open("lines.txt")?;
|
||||
let file = BufReader::new(file);
|
||||
|
||||
for line in file.lines() {
|
||||
println!("{}", line?);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() { run().unwrap() }
|
||||
```
|
||||
|
||||
<a name="ex-byteorder-le"/>
|
||||
## Read and write integers in little-endian byte order
|
||||
|
||||
[![byteorder-badge]][byteorder] [![cat-serialization-badge]][cat-serialization]
|
||||
|
||||
```rust
|
||||
extern crate byteorder;
|
||||
|
||||
use std::io::Cursor;
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
#[derive(Default, Eq, PartialEq, Debug)]
|
||||
struct Payload {
|
||||
kind: u8,
|
||||
value: u16,
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let original_payload = Payload::default();
|
||||
let encoded_buf = encode(&original_payload)?;
|
||||
let decoded_payload = decode(&encoded_buf)?;
|
||||
assert_eq!(original_payload, decoded_payload);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encode(payload: &Payload) -> Result<Vec<u8>> {
|
||||
let mut wtr = vec![];
|
||||
wtr.write_u8(payload.kind)?;
|
||||
wtr.write_u16::<LittleEndian>(payload.value)?;
|
||||
Ok(wtr)
|
||||
}
|
||||
|
||||
fn decode(buf: &[u8]) -> Result<Payload> {
|
||||
let mut rdr = Cursor::new(buf);
|
||||
Ok(Payload {
|
||||
kind: rdr.read_u8()?,
|
||||
value: rdr.read_u16::<LittleEndian>()?,
|
||||
})
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { run().unwrap() }
|
||||
```
|
||||
|
||||
<a name="ex-rand-float"/>
|
||||
## Generate random floating point numbers
|
||||
|
||||
[![rand-badge]][rand] [![cat-math-badge]][cat-math]
|
||||
|
||||
<a name="ex-rand-custom"/>
|
||||
## Generate random values on a custom type
|
||||
|
||||
[![rand-badge]][rand] [![cat-math-badge]][cat-math]
|
||||
|
||||
<a name="ex-petgraph-basic"/>
|
||||
## Construct a graph of objects
|
||||
|
||||
[![petgraph-badge]][petgraph] [![cat-math-badge]][cat-math]
|
||||
|
||||
<!- Categories -->
|
||||
|
||||
[cat-file-io-badge]: https://img.shields.io/badge/-file_io-orange.svg
|
||||
[cat-file-io]: https://crates.io
|
||||
[cat-math-badge]: https://img.shields.io/badge/-rand-orange.svg
|
||||
[cat-math]: https://crates.io
|
||||
[cat-serialization-badge]: https://img.shields.io/badge/-serialization-orange.svg
|
||||
[cat-serialization]: https://crates.io
|
||||
|
||||
<!-- Crates -->
|
||||
|
||||
[byteorder-badge]: https://img.shields.io/badge/byteorder-1.0.0-blue.svg
|
||||
[byteorder]: https://docs.rs/byteorder/1.0.0/byteorder/
|
||||
[petgraph-badge]: https://img.shields.io/badge/petgraph-0.4.3-blue.svg
|
||||
[petgraph]: https://docs.rs/petgraph/0.4.3/petgraph/
|
||||
[std-badge]: https://img.shields.io/badge/std-1.17.0-blue.svg
|
||||
[std]: https://doc.rust-lang.org/std
|
||||
[rand-badge]: https://img.shields.io/badge/rand-0.3.15-blue.svg
|
||||
[rand]: https://docs.rs/rand/0.3.15/rand/
|
||||
|
||||
<!-- Examples -->
|
||||
|
||||
[ex-byteorder-le]: basics.html#ex-byteorder-le
|
||||
[ex-petgraph-basic]: basics.html#ex-petgraph-basic
|
||||
[ex-rand-custom]: basics.html#ex-rand-custom
|
||||
[ex-rand-float]: basics.html#ex-rand-float
|
||||
[ex-std-read-lines]: basics.html#ex-std-read-lines
|
||||
|
||||
<!-- API links -->
|
||||
|
||||
[`BufRead::lines`]: https://doc.rust-lang.org/std/io/trait.BufRead.html#method.lines
|
||||
[`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
|
||||
[`BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html
|
||||
[`File`]: https://doc.rust-lang.org/std/fs/struct.File.html
|
||||
[`File::create`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.create
|
||||
[`File::open`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.open
|
||||
[`Lines`]: https://doc.rust-lang.org/std/io/struct.Lines.html
|
||||
[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
|
|
@ -1,6 +1,8 @@
|
|||
# Parallel Prime Calculations
|
||||
[![crossbeam-badge]][crossbeam]
|
||||
|
||||
FIXME: This doesn't look like it's running in parallel
|
||||
|
||||
## Calculate primes upto a number
|
||||
|
||||
```rust
|
92
src/error_handling_note.md
Normal file
92
src/error_handling_note.md
Normal file
|
@ -0,0 +1,92 @@
|
|||
# A note about error handling
|
||||
|
||||
Error handling in Rust is robust when done correctly, but in today's
|
||||
Rust it requires a fair bit of boilerplate. Because of this one often
|
||||
sees Rust examples filled with `unwrap` calls instead of proper error
|
||||
handling.
|
||||
|
||||
Since these recipes are intended to be reused as-is and encourage best
|
||||
practices, they set up error handling correctly when there are
|
||||
`Result` types involved.
|
||||
|
||||
The basic pattern we use is to have a `fn run() -> Result` that acts
|
||||
like the "real" main function.
|
||||
|
||||
The code for this setup generally looks like:
|
||||
|
||||
```rust
|
||||
use std::io::{self, Write};
|
||||
|
||||
fn run() -> io::Result<()> {
|
||||
let ref mut stdout = io::stdout();
|
||||
writeln!(stdout, "hello, world")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() { run().unwrap() }
|
||||
```
|
||||
|
||||
and when necessary to reduce boilerplate,
|
||||
they use the [error-chain] crate.
|
||||
|
||||
```rust
|
||||
extern crate byteorder;
|
||||
|
||||
use std::io::Cursor;
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
#[derive(Default, Eq, PartialEq, Debug)]
|
||||
struct Payload {
|
||||
kind: u8,
|
||||
value: u16,
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let original_payload = Payload::default();
|
||||
let encoded_buf = encode(&original_payload)?;
|
||||
let decoded_payload = decode(&encoded_buf)?;
|
||||
assert_eq!(original_payload, decoded_payload);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encode(payload: &Payload) -> Result<Vec<u8>> {
|
||||
let mut wtr = vec![];
|
||||
wtr.write_u8(payload.kind)?;
|
||||
wtr.write_u16::<LittleEndian>(payload.value)?;
|
||||
Ok(wtr)
|
||||
}
|
||||
|
||||
fn decode(buf: &[u8]) -> Result<Payload> {
|
||||
let mut rdr = Cursor::new(buf);
|
||||
Ok(Payload {
|
||||
kind: rdr.read_u8()?,
|
||||
value: rdr.read_u16::<LittleEndian>()?,
|
||||
})
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { run().unwrap() }
|
||||
```
|
||||
|
||||
This is using the `error_chain!` macro to define a custom `Error`
|
||||
and `Result` type, along with an automatic conversion from
|
||||
the common `::std::io::Error` type. The automatic conversion
|
||||
makes the `?` operator work .
|
||||
|
||||
For more background on error handling in Rust, read [this page of the
|
||||
Rust book][error-docs] and [this blog post][error-blog].
|
||||
|
||||
<!-- Links-->
|
||||
|
||||
[error-docs]: https://doc.rust-lang.org/book/error-handling.html
|
||||
[error-blog]: https://brson.github.io/2016/11/30/starting-with-error-chain
|
||||
|
|
@ -26,6 +26,7 @@ fn operate_on_file(myfile: &str, mystring: &str, count: i32) -> io::Result<()> {
|
|||
|
||||
// Read lines from file
|
||||
for line in io::BufReader::new(&f).lines() {
|
||||
// FIXME: bad unwrap
|
||||
println!("{}", line.unwrap());
|
||||
}
|
||||
Ok(())
|
|
@ -2,16 +2,24 @@
|
|||
|
||||
A practical guide to the Rust crate ecosystem.
|
||||
|
||||
|
||||
|
||||
## Recipes
|
||||
|
||||
### Foundations
|
||||
### Basics
|
||||
|
||||
| Recipe | Crates | Categories |
|
||||
|--------|--------|------------|
|
||||
| [Read lines of strings from a file][ex-std-read-lines] | [![std-badge]][std] | [![cat-file-io-badge]][cat-file-io] |
|
||||
| [Read and write integers in little-endian byte order][ex-byteorder-le] | [![byteorder-badge]][byteorder] | [![cat-serialization-badge]][cat-serialization] |
|
||||
| [Generate random floating point numbers][ex-rand-float] | [![rand-badge]][rand] | [![cat-math-badge]][cat-math] |
|
||||
| [Generate random values on a custom type][ex-rand-custom] | [![rand-badge]][rand] | [![cat-math-badge]][cat-math] |
|
||||
| [Construct a graph of objects][ex-petgraph-basic] | [![petgraph-badge]][petgraph] | [![cat-math-badge]][cat-math] |
|
||||
|
||||
### Serialization
|
||||
|
||||
| Recipe | Crates | Categories |
|
||||
|--------|--------|------------|
|
||||
| [Serialize and deserialize unstructured JSON][ex-json-basic] | [![json-badge]][json] | [![cat-serialization-badge]][cat-serialization] |
|
||||
| [Deserialize an unstructured TOML configuration file][ex-toml-basic] | [![toml-badge]][toml] | [![cat-serialization-badge]][cat-serialization] |
|
||||
|
||||
|
@ -21,16 +29,12 @@ A practical guide to the Rust crate ecosystem.
|
|||
|--------|--------|------------|
|
||||
| [Mutate the elements of an array in parallel][ex-rayon-iter-mut] | [![rayon-badge]][rayon] | [![cat-concurrency-badge]][cat-concurrency] |
|
||||
|
||||
### I/O
|
||||
|
||||
### Application development
|
||||
|
||||
| Recipe | Crates | Categories |
|
||||
|--------|--------|------------|
|
||||
| [Parse command line arguments][ex-clap-basic] | [![clap-badge]][clap] | [![cat-app-badge]][cat-app] |
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
If you'd like to make changes to the project, please see [this guide](pages/contributing.html).
|
||||
|
@ -39,41 +43,60 @@ If you'd like to make changes to the project, please see [this guide](pages/cont
|
|||
|
||||
MIT/Apache-2.0
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
Links, in a few categories. Follow the existing structure.
|
||||
|
||||
Individual pages contain a subset of these exact links, depending on
|
||||
the crates and categories of their examples.
|
||||
|
||||
Keep lines sorted.
|
||||
|
||||
-->
|
||||
|
||||
<!- Categories -->
|
||||
|
||||
[cat-serialization-badge]: https://img.shields.io/badge/-serialization-orange.svg
|
||||
[cat-serialization]: https://crates.io
|
||||
[cat-math-badge]: https://img.shields.io/badge/-rand-orange.svg
|
||||
[cat-math]: https://crates.io
|
||||
[cat-app-badge]: https://img.shields.io/badge/-app-orange.svg
|
||||
[cat-app]: https://crates.io
|
||||
[cat-concurrency-badge]: https://img.shields.io/badge/-concurrency-orange.svg
|
||||
[cat-concurrency]: https://crates.io
|
||||
[cat-file-io-badge]: https://img.shields.io/badge/-file_io-orange.svg
|
||||
[cat-file-io]: https://crates.io
|
||||
[cat-math-badge]: https://img.shields.io/badge/-rand-orange.svg
|
||||
[cat-math]: https://crates.io
|
||||
[cat-serialization-badge]: https://img.shields.io/badge/-serialization-orange.svg
|
||||
[cat-serialization]: https://crates.io
|
||||
|
||||
<!-- Crates -->
|
||||
|
||||
[byteorder-badge]: https://img.shields.io/badge/byteorder-1.0.0-blue.svg
|
||||
[byteorder]: https://docs.rs/byteorder/1.0.0/byteorder/
|
||||
[clap-badge]: https://img.shields.io/badge/clap-2.22.2-blue.svg
|
||||
[clap]: https://docs.rs/clap/2.22.0/rand/
|
||||
[json-badge]: https://img.shields.io/badge/json-0.11.5-blue.svg
|
||||
[json]: https://docs.rs/json/0.11.5/json/
|
||||
[petgraph-badge]: https://img.shields.io/badge/petgraph-0.4.3-blue.svg
|
||||
[petgraph]: https://docs.rs/petgraph/0.4.3/petgraph/
|
||||
[rand-badge]: https://img.shields.io/badge/rand-0.3.15-blue.svg
|
||||
[rand]: https://docs.rs/rand/0.3.15/rand/
|
||||
[clap-badge]: https://img.shields.io/badge/clap-2.22.2-blue.svg
|
||||
[clap]: https://docs.rs/clap/2.22.0/rand/
|
||||
[rayon-badge]: https://img.shields.io/badge/rayon-0.6.0-blue.svg
|
||||
[rayon]: https://docs.rs/rayon/0.6.0/rayon/
|
||||
[json-badge]: https://img.shields.io/badge/json-0.11.5-blue.svg
|
||||
[json]: https://docs.rs/json/0.11.5/json/
|
||||
[std-badge]: https://img.shields.io/badge/std-1.17.0-blue.svg
|
||||
[std]: https://doc.rust-lang.org/std
|
||||
[toml-badge]: https://img.shields.io/badge/toml-0.3.0-blue.svg
|
||||
[toml]: https://docs.rs/toml/0.3.0/toml/
|
||||
|
||||
<!-- Examples -->
|
||||
|
||||
[ex-byteorder-le]: todo
|
||||
[ex-rand-float]: todo
|
||||
[ex-rand-custom]: todo
|
||||
[ex-petgraph-basic]: todo
|
||||
[ex-byteorder-le]: basics.html#ex-byteorder-le
|
||||
[ex-clap-basic]: todo
|
||||
[ex-json-basic]: todo
|
||||
[ex-toml-basic]: todo
|
||||
[ex-petgraph-basic]: basics.html#ex-petgraph-basic
|
||||
[ex-rand-custom]: basics.html#ex-rand-custom
|
||||
[ex-rand-float]: basics.html#ex-rand-float
|
||||
[ex-rayon-iter-mut]: todo
|
||||
[ex-std-read-lines]: basics.html#ex-std-read-lines
|
||||
[ex-toml-basic]: todo
|
|
@ -1,3 +1,4 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
println!("This program does nothing.");
|
||||
println!("See documentation at https://github.com/brson/rust-cookbook");
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# Algorithms
|
|
@ -1,57 +0,0 @@
|
|||
# Byteorder
|
||||
[![byteorder-badge]][byteorder]
|
||||
|
||||
## Read and write integers in little-endian byte order
|
||||
|
||||
```rust
|
||||
extern crate byteorder;
|
||||
|
||||
use std::io::Cursor;
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
#[derive(Default, Eq, PartialEq, Debug)]
|
||||
struct Payload {
|
||||
kind: u8,
|
||||
value: u16,
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let original_payload = Payload::default();
|
||||
let encoded_buf = encode(&original_payload)?;
|
||||
let decoded_payload = decode(&encoded_buf)?;
|
||||
assert_eq!(original_payload, decoded_payload);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encode(payload: &Payload) -> Result<Vec<u8>> {
|
||||
let mut wtr = vec![];
|
||||
wtr.write_u8(payload.kind)?;
|
||||
wtr.write_u16::<LittleEndian>(payload.value)?;
|
||||
Ok(wtr)
|
||||
}
|
||||
|
||||
fn decode(buf: &[u8]) -> Result<Payload> {
|
||||
let mut rdr = Cursor::new(buf);
|
||||
Ok(Payload {
|
||||
kind: rdr.read_u8()?,
|
||||
value: rdr.read_u16::<LittleEndian>()?,
|
||||
})
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
mod errors {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
use errors::*;
|
||||
fn main() { run().unwrap() }
|
||||
```
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[byteorder-badge]: https://img.shields.io/crates/v/rustc-serialize.svg?label=byteorder
|
||||
[byteorder]: https://docs.rs/byteorder
|
|
@ -1 +0,0 @@
|
|||
# Concurrency
|
|
@ -1,46 +0,0 @@
|
|||
# Contributing to the Rust Cookbook
|
||||
|
||||
Have something useful to add to the Rust Cookbook? We'd love to have it!
|
||||
|
||||
This document contains information and guidelines that you should read before
|
||||
contributing to the project. If you think something in this document should change,
|
||||
feel free propose a change in a pull request.
|
||||
|
||||
## Table of Contents
|
||||
* [Getting Started](#getting-started)
|
||||
* [How to Contribute](#how-to-contribute)
|
||||
* [Crates](#crates)
|
||||
* [Tests](#tests)
|
||||
* [Style](#style)
|
||||
* [Git Commit Messages](#git-commit-messages)
|
||||
* [Snippet Style](#snippet-style)
|
||||
|
||||
## Getting Started
|
||||
TODO: Mention Trello and how to join (if we keep using it)
|
||||
|
||||
## How to Contribute
|
||||
TODO: Reporting bugs
|
||||
TODO: Project page suggestions
|
||||
TODO: Fixing bugs
|
||||
TODO: Pull requests
|
||||
|
||||
## Crates
|
||||
|
||||
All crates used by the cookbook are listed in Cargo.toml. If you are
|
||||
adding a new crate, first add it there.
|
||||
|
||||
## Tests
|
||||
|
||||
All examples are tested using [`skeptic`]. Run them with `cargo test`.
|
||||
|
||||
[`skeptic`]: https://github.com/brson/rust-skeptic
|
||||
|
||||
## Style
|
||||
|
||||
### Git Commit Messages
|
||||
https://chris.beams.io/posts/git-commit/
|
||||
TODO: Possibly take relevant parts from this post or write our own
|
||||
|
||||
### Snippet Style
|
||||
TODO: Talk about writing good idiomatic code
|
||||
TODO: Maybe provide a template?
|
|
@ -1,50 +0,0 @@
|
|||
# A note about error handling
|
||||
|
||||
Error handling in Rust is robust when done correctly, but in today's
|
||||
Rust it requires a fair bit of boilerplate. Because of this one often
|
||||
sees Rust examples filled with `unwrap` calls instead of proper error
|
||||
handling.
|
||||
|
||||
Since these recipes are intended to be reused as-is and encourage best
|
||||
practices, they set up error handling correctly, and when necessary to
|
||||
reduce boilerplate, they use the [error-chain] crate.
|
||||
|
||||
The code for this setup generally looks like:
|
||||
|
||||
```rust
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
mod errors {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use errors::*;
|
||||
|
||||
fn main() { run().unwrap() }
|
||||
|
||||
fn run() -> Result<()> {
|
||||
use std::io::Write;
|
||||
let ref mut stdout = ::std::io::stdout();
|
||||
writeln!(stdout, "hello, world")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
This is using the `error_chain!` macro to define a custom `Error`
|
||||
and `Result` type, along with an automatic conversion from
|
||||
the common `::std::io::Error` type. The automatic conversion
|
||||
makes the `?` operator work
|
||||
|
||||
For more background on error handling in Rust, read [this page of the Rust book][error-docs] and [this blog post][error-blog].
|
||||
|
||||
<!-- Links-->
|
||||
|
||||
[error-docs]: https://doc.rust-lang.org/book/error-handling.html
|
||||
[error-blog]: https://brson.github.io/2016/11/30/starting-with-error-chain
|
||||
|
|
@ -1 +0,0 @@
|
|||
# Math
|
|
@ -1 +0,0 @@
|
|||
# Networking
|
Loading…
Reference in a new issue