mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-22 19:43:06 +00:00
Use quick_main in examples
This commit is contained in:
parent
9467df216a
commit
87da3d5766
4 changed files with 232 additions and 117 deletions
51
src/app.md
51
src/app.md
|
@ -132,7 +132,8 @@ Your favorite number must be 256.
|
|||
extern crate log;
|
||||
extern crate env_logger;
|
||||
|
||||
use log::SetLoggerError;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
mod foo {
|
||||
mod bar {
|
||||
|
@ -151,7 +152,13 @@ mod foo {
|
|||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<(), SetLoggerError> {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
SetLogger(log::SetLoggerError);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
env_logger::init()?;
|
||||
warn!("[root] warn");
|
||||
info!("[root] info");
|
||||
|
@ -161,9 +168,7 @@ fn run() -> Result<(), SetLoggerError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run().unwrap();
|
||||
}
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[`env_logger`][env_logger] output is controlled by [`RUST_LOG`] environmental
|
||||
|
@ -200,7 +205,10 @@ via [`log::set_logger`]. Messages are logged to stdout.
|
|||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
use log::{LogRecord, LogLevel, LogMetadata, LogLevelFilter, SetLoggerError};
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use log::{LogRecord, LogLevel, LogMetadata, LogLevelFilter};
|
||||
|
||||
struct ConsoleLogger;
|
||||
|
||||
|
@ -216,7 +224,13 @@ impl log::Log for ConsoleLogger {
|
|||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<(), SetLoggerError> {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
SetLogger(log::SetLoggerError);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
log::set_logger(|max_log_level| {
|
||||
max_log_level.set(LogLevelFilter::Info);
|
||||
Box::new(ConsoleLogger)
|
||||
|
@ -228,9 +242,7 @@ fn run() -> Result<(), SetLoggerError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run().unwrap();
|
||||
}
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-log-syslog]: #ex-log-syslog
|
||||
|
@ -246,23 +258,30 @@ with [`syslog::init`].
|
|||
and `Option<&str>` holds optional application name.
|
||||
|
||||
```rust,no_run
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate syslog;
|
||||
|
||||
use log::{LogLevelFilter, SetLoggerError};
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use log::LogLevelFilter;
|
||||
use syslog::Facility;
|
||||
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
SetLogger(log::SetLoggerError);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<(), SetLoggerError> {
|
||||
fn run() -> Result<()> {
|
||||
syslog::init(Facility::LOG_USER, LogLevelFilter::Debug, Some("My app name"))?;
|
||||
debug!("this is a debug {}", "message");
|
||||
error!("this is an error!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run().unwrap();
|
||||
}
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-log-custom]: #ex-log-custom
|
||||
|
|
|
@ -24,10 +24,19 @@ 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};
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
fn run() -> io::Result<()> {
|
||||
use std::fs::File;
|
||||
use std::io::{Write, BufReader, BufRead};
|
||||
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(std::io::Error);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let path = "lines.txt";
|
||||
|
||||
let mut output = File::create(path)?;
|
||||
|
@ -43,9 +52,7 @@ fn run() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run().unwrap();
|
||||
}
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-byteorder-le]: #ex-byteorder-le
|
||||
|
@ -57,7 +64,8 @@ fn main() {
|
|||
```rust
|
||||
extern crate byteorder;
|
||||
|
||||
use std::io;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
|
@ -67,7 +75,13 @@ struct Payload {
|
|||
value: u16,
|
||||
}
|
||||
|
||||
fn run() -> io::Result<()> {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(std::io::Error);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let original_payload = Payload::default();
|
||||
let encoded_bytes = encode(&original_payload)?;
|
||||
let decoded_payload = decode(&encoded_bytes)?;
|
||||
|
@ -75,14 +89,14 @@ fn run() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn encode(payload: &Payload) -> io::Result<Vec<u8>> {
|
||||
fn encode(payload: &Payload) -> Result<Vec<u8>> {
|
||||
let mut bytes = vec![];
|
||||
bytes.write_u8(payload.kind)?;
|
||||
bytes.write_u16::<LittleEndian>(payload.value)?;
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
fn decode(mut bytes: &[u8]) -> io::Result<Payload> {
|
||||
fn decode(mut bytes: &[u8]) -> Result<Payload> {
|
||||
let payload = Payload {
|
||||
kind: bytes.read_u8()?,
|
||||
value: bytes.read_u16::<LittleEndian>()?,
|
||||
|
@ -90,9 +104,7 @@ fn decode(mut bytes: &[u8]) -> io::Result<Payload> {
|
|||
Ok(payload)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run().unwrap();
|
||||
}
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-rand-float]: #ex-rand-float
|
||||
|
|
|
@ -32,9 +32,18 @@ we expect the parsed value to be. The expected value is declared using the
|
|||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
fn main() {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Json(serde_json::Error);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let j = r#"{
|
||||
"userid": 103609,
|
||||
"verified": true,
|
||||
|
@ -44,7 +53,7 @@ fn main() {
|
|||
]
|
||||
}"#;
|
||||
|
||||
let parsed: Value = serde_json::from_str(j).unwrap();
|
||||
let parsed: Value = serde_json::from_str(j)?;
|
||||
|
||||
let expected = json!({
|
||||
"userid": 103609,
|
||||
|
@ -56,7 +65,11 @@ fn main() {
|
|||
});
|
||||
|
||||
assert_eq!(parsed, expected);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-toml-config]: #ex-toml-config
|
||||
|
@ -71,9 +84,18 @@ valid TOML data.
|
|||
```rust
|
||||
extern crate toml;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use toml::Value;
|
||||
|
||||
fn main() {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Toml(toml::de::Error);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let toml_content = r#"
|
||||
[package]
|
||||
name = "your_package"
|
||||
|
@ -84,11 +106,15 @@ fn main() {
|
|||
serde = "1.0"
|
||||
"#;
|
||||
|
||||
let package_info: Value = toml::from_str(toml_content).unwrap();
|
||||
let package_info: Value = toml::from_str(toml_content)?;
|
||||
|
||||
assert_eq!(package_info["dependencies"]["serde"].as_str(), Some("1.0"));
|
||||
assert_eq!(package_info["package"]["name"].as_str(), Some("your_package"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
Parse TOML into your own structs using Serde:
|
||||
|
@ -102,6 +128,9 @@ extern crate serde_derive;
|
|||
extern crate serde;
|
||||
extern crate toml;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -117,7 +146,13 @@ struct Package {
|
|||
authors: Vec<String>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Toml(toml::de::Error);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let toml_content = r#"
|
||||
[package]
|
||||
name = "your_package"
|
||||
|
@ -128,13 +163,17 @@ fn main() {
|
|||
serde = "1.0"
|
||||
"#;
|
||||
|
||||
let package_info: Config = toml::from_str(toml_content).unwrap();
|
||||
let package_info: Config = toml::from_str(toml_content)?;
|
||||
|
||||
assert_eq!(package_info.package.name, "your_package");
|
||||
assert_eq!(package_info.package.version, "0.1.0");
|
||||
assert_eq!(package_info.package.authors, vec!["You! <you@example.org>"]);
|
||||
assert_eq!(package_info.dependencies["serde"], "1.0");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
<!-- Categories -->
|
||||
|
|
209
src/net.md
209
src/net.md
|
@ -31,21 +31,27 @@ URL will print a message containing an explanation of what went wrong.
|
|||
```rust
|
||||
extern crate url;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use url::Url;
|
||||
|
||||
fn main() {
|
||||
let s = "https://github.com/rust-lang/rust/issues?labels=E-easy&state=open";
|
||||
|
||||
match Url::parse(s) {
|
||||
Ok(url) => {
|
||||
println!("Successfully parsed the URL.");
|
||||
println!("The path part of the URL is: {}", url.path());
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Failed to parse the URL: {}", err);
|
||||
}
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
UrlParse(url::ParseError);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let s = "https://github.com/rust-lang/rust/issues?labels=E-easy&state=open";
|
||||
|
||||
let parsed = Url::parse(s)?;
|
||||
println!("The path part of the URL is: {}", parsed.path());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-url-base]: #ex-url-base
|
||||
|
@ -57,39 +63,35 @@ fn main() {
|
|||
```rust
|
||||
extern crate url;
|
||||
|
||||
use url::{Url, ParseError};
|
||||
use url::Url;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
UrlParse(url::ParseError);
|
||||
}
|
||||
errors {
|
||||
CannotBeABase
|
||||
}
|
||||
foreign_links {
|
||||
Parse(ParseError);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = "https://github.com/rust-lang/cargo?asdf";
|
||||
fn run() -> Result<()> {
|
||||
let full = "https://github.com/rust-lang/cargo?asdf";
|
||||
|
||||
match base_url(s) {
|
||||
Ok(base) => {
|
||||
assert_eq!(base.as_str(), "https://github.com/");
|
||||
println!("The base of the URL is: {}", base);
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Failed to extract base URL: {}", err);
|
||||
}
|
||||
}
|
||||
let url = Url::parse(full)?;
|
||||
let base = base_url(url)?;
|
||||
|
||||
assert_eq!(base.as_str(), "https://github.com/");
|
||||
println!("The base of the URL is: {}", base);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the base of the given URL - the part not including any path segments
|
||||
/// and query parameters.
|
||||
fn base_url(full: &str) -> Result<Url> {
|
||||
let mut url = Url::parse(full)?;
|
||||
|
||||
fn base_url(mut url: Url) -> Result<Url> {
|
||||
// Clear path segments.
|
||||
match url.path_segments_mut() {
|
||||
Ok(mut path) => {
|
||||
|
@ -106,6 +108,8 @@ fn base_url(full: &str) -> Result<Url> {
|
|||
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-url-new-from-base]: #ex-url-new-from-base
|
||||
|
@ -119,29 +123,39 @@ The [`join`] method creates a new URL from a base and relative path.
|
|||
```rust
|
||||
extern crate url;
|
||||
|
||||
use url::{Url, ParseError};
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
fn main() {
|
||||
let path = "/rust-lang/cargo";
|
||||
use url::Url;
|
||||
|
||||
match build_github_url(path) {
|
||||
Ok(url) => {
|
||||
assert_eq!(url.as_str(), "https://github.com/rust-lang/cargo");
|
||||
println!("The joined URL is: {}", url);
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Failed to build GitHub URL: {}", err);
|
||||
}
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
UrlParse(url::ParseError);
|
||||
}
|
||||
}
|
||||
|
||||
fn build_github_url(path: &str) -> Result<Url, ParseError> {
|
||||
fn run() -> Result<()> {
|
||||
let path = "/rust-lang/cargo";
|
||||
|
||||
let gh = build_github_url(path)?;
|
||||
|
||||
assert_eq!(gh.as_str(), "https://github.com/rust-lang/cargo");
|
||||
println!("The joined URL is: {}", gh);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_github_url(path: &str) -> Result<Url> {
|
||||
// Hardcoded in our program. Caller's path will be joined to this.
|
||||
const GITHUB: &'static str = "https://github.com";
|
||||
|
||||
let base = Url::parse(GITHUB).expect("hardcoded URL is known to be valid");
|
||||
base.join(path)
|
||||
let joined = base.join(path)?;
|
||||
|
||||
Ok(joined)
|
||||
}
|
||||
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-url-origin]: #ex-url-origin
|
||||
|
@ -156,23 +170,31 @@ it represents.
|
|||
```rust
|
||||
extern crate url;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use url::{Url, Host};
|
||||
|
||||
fn main() {
|
||||
let s = "ftp://rust-lang.org/examples";
|
||||
|
||||
match Url::parse(s) {
|
||||
Ok(url) => {
|
||||
assert_eq!(url.scheme(), "ftp");
|
||||
assert_eq!(url.host(), Some(Host::Domain("rust-lang.org")));
|
||||
assert_eq!(url.port_or_known_default(), Some(21));
|
||||
println!("The origin is as expected!");
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Failed to parse the URL: {}", err);
|
||||
}
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
UrlParse(url::ParseError);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let s = "ftp://rust-lang.org/examples";
|
||||
|
||||
let url = Url::parse(s)?;
|
||||
|
||||
assert_eq!(url.scheme(), "ftp");
|
||||
assert_eq!(url.host(), Some(Host::Domain("rust-lang.org")));
|
||||
assert_eq!(url.port_or_known_default(), Some(21));
|
||||
println!("The origin is as expected!");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
The same result can be obtained using the [`origin`] method as well.
|
||||
|
@ -180,27 +202,35 @@ The same result can be obtained using the [`origin`] method as well.
|
|||
```rust
|
||||
extern crate url;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use url::{Url, Origin, Host};
|
||||
|
||||
fn main() {
|
||||
let s = "ftp://rust-lang.org/examples";
|
||||
|
||||
match Url::parse(s) {
|
||||
Ok(url) => {
|
||||
let expected_scheme = "ftp".to_owned();
|
||||
let expected_host = Host::Domain("rust-lang.org".to_owned());
|
||||
let expected_port = 21;
|
||||
let expected = Origin::Tuple(expected_scheme, expected_host, expected_port);
|
||||
|
||||
let origin = url.origin();
|
||||
assert_eq!(origin, expected);
|
||||
println!("The origin is as expected!");
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Failed to parse the URL: {}", err);
|
||||
}
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
UrlParse(url::ParseError);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let s = "ftp://rust-lang.org/examples";
|
||||
|
||||
let url = Url::parse(s)?;
|
||||
|
||||
let expected_scheme = "ftp".to_owned();
|
||||
let expected_host = Host::Domain("rust-lang.org".to_owned());
|
||||
let expected_port = 21;
|
||||
let expected = Origin::Tuple(expected_scheme, expected_host, expected_port);
|
||||
|
||||
let origin = url.origin();
|
||||
assert_eq!(origin, expected);
|
||||
println!("The origin is as expected!");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-url-rm-frag]: #ex-url-rm-frag
|
||||
|
@ -214,18 +244,25 @@ Once [`Url`] is parsed it can be sliced with [`url::Position`] to strip unneeded
|
|||
```rust
|
||||
extern crate url;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use url::{Url, Position};
|
||||
|
||||
fn run() -> Result<(), url::ParseError> {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
UrlParse(url::ParseError);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let parsed = Url::parse("https://github.com/rust-lang/rust/issues?labels=E-easy&state=open")?;
|
||||
let cleaned: &str = &parsed[..Position::AfterPath];
|
||||
println!("cleaned: {}", cleaned);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run().unwrap();
|
||||
}
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-url-basic]: #ex-url-basic
|
||||
|
@ -338,6 +375,9 @@ GitHub [stargazers API v3](https://developer.github.com/v3/activity/starring/#li
|
|||
extern crate serde_derive;
|
||||
extern crate reqwest;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct User {
|
||||
login: String,
|
||||
|
@ -345,7 +385,13 @@ struct User {
|
|||
// remaining fields not deserialized for brevity
|
||||
}
|
||||
|
||||
fn run() -> reqwest::Result<()> {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Reqwest(reqwest::Error);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let request_url = format!("https://api.github.com/repos/{owner}/{repo}/stargazers",
|
||||
owner = "brson",
|
||||
repo = "rust-cookbook");
|
||||
|
@ -357,9 +403,7 @@ fn run() -> reqwest::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run().unwrap();
|
||||
}
|
||||
quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-rest-post]: #ex-rest-post
|
||||
|
@ -376,14 +420,15 @@ Request is prepared with [`Client::post`], authenticated with [`RequestBuilder::
|
|||
Gist is subsequently deleted with HTTP DELETE request prepared with [`Client::delete`] and executed as before.
|
||||
|
||||
```rust,no_run
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate reqwest;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use std::env;
|
||||
|
||||
error_chain! {
|
||||
|
|
Loading…
Reference in a new issue