run() -> main() (#548)

* [433] remove old run function

* Completes run() -> main() transitions
This commit is contained in:
Jubilee 2019-09-19 13:05:17 -07:00 committed by Andrew Gauger
parent f4d63dada2
commit 5eba1a6068
38 changed files with 67 additions and 146 deletions

View file

@ -107,9 +107,7 @@ 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. We use the [error-chain] crate to make
`?` work within `run`.
The basic pattern we use is to have a `fn main() -> Result`.
The structure generally looks like:
@ -127,7 +125,7 @@ error_chain! {
}
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let bytes = b"2001:db8::1";
// Bytes to string.
@ -140,14 +138,12 @@ fn run() -> Result<()> {
Ok(())
}
quick_main!(run);
```
This is using the `error_chain!` macro to define a custom `Error` and
`Result` type, along with automatic conversions from two standard
library error types. The automatic conversions make the `?` operator
work. The `quick_main!` macro generates the actual `main` function and
prints out the error if one occurred.
work.
For the sake of readability error handling boilerplate is hidden by
default like below. In order to read full contents click on the
@ -167,14 +163,12 @@ use url::{Url, Position};
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let parsed = Url::parse("https://httpbin.org/cookies/set?k2=v2&k1=v1")?;
let cleaned: &str = &parsed[..Position::AfterPath];
println!("cleaned: {}", cleaned);
Ok(())
}
#
# quick_main!(run);
```
For more background on error handling in Rust, read [this page of the

View file

@ -31,7 +31,7 @@ use rayon::prelude::*;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let options: MatchOptions = Default::default();
let files: Vec<_> = glob_with("*.jpg", &options)?
.filter_map(|x| x.ok())
@ -72,8 +72,6 @@ where
Ok(img.resize(longest_edge, longest_edge, FilterType::Nearest)
.save(file_path)?)
}
#
# quick_main!(run);
```
[`glob::glob_with`]: https://docs.rs/glob/*/glob/fn.glob_with.html

View file

@ -29,7 +29,7 @@ fn insert(fruit: &str) -> Result<()> {
Ok(())
}
fn run() -> Result<()> {
fn main() -> Result<()> {
insert("apple")?;
insert("orange")?;
insert("peach")?;
@ -41,8 +41,6 @@ fn run() -> Result<()> {
insert("grape")?;
Ok(())
}
#
# quick_main!(run);
```
[`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html

View file

@ -88,7 +88,7 @@ use image::{ImageBuffer, Pixel, Rgb};
# ((color * factor).powf(0.8) * 255.) as u8
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let (width, height) = (1920, 1080);
let mut img = ImageBuffer::new(width, height);
let iterations = 300;
@ -114,8 +114,6 @@ fn run() -> Result<()> {
let _ = img.save("output.png")?;
Ok(())
}
#
# quick_main!(run);
```
[`ImageBuffer::new`]: https://docs.rs/image/*/image/struct.ImageBuffer.html#method.new

View file

@ -38,7 +38,7 @@ fn sha256_digest<R: Read>(mut reader: R) -> Result<Digest> {
Ok(context.finish())
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let path = "file.txt";
let mut output = File::create(path)?;
@ -52,8 +52,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`digest::Context`]: https://briansmith.org/rustdoc/ring/digest/struct.Context.html

View file

@ -83,15 +83,13 @@ extern {
fn greet(name: *const c_char);
}
fn run() -> Result<()> {
fn main() -> Result<()> {
unsafe { hello() }
let name = prompt("What's your name? ")?;
let c_name = CString::new(name)?;
unsafe { greet(c_name.as_ptr()) }
Ok(())
}
#
# quick_main!(run);
```
[`cc::Build::define`]: https://docs.rs/cc/*/cc/struct.Build.html#method.define

View file

@ -31,7 +31,7 @@ use log4rs::config::{Appender, Config, Root};
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let logfile = FileAppender::builder()
.encoder(Box::new(PatternEncoder::new("{l} - {m}\n")))
.build("log/output.log")?;
@ -48,8 +48,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`log4rs::append::file::FileAppender`]: https://docs.rs/log4rs/*/log4rs/append/file/struct.FileAppender.html

View file

@ -24,7 +24,7 @@ use semver::{Version, VersionReq};
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let version_constraint = "> 1.12.0";
let version_test = VersionReq::parse(version_constraint)?;
let output = Command::new("git").arg("--version").output()?;
@ -46,8 +46,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html

View file

@ -35,7 +35,7 @@ where
)
}
fn run() -> Result<()> {
fn main() -> Result<()> {
assert_eq!(
find_max_matching_version("<= 1.0.0", vec!["0.9.0", "1.0.0", "1.0.1"])?,
Some(Version::parse("1.0.0")?)
@ -57,8 +57,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`semver::Version`]: https://docs.rs/semver/*/semver/struct.Version.html

View file

@ -61,7 +61,7 @@ struct Package {
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let toml_content = r#"
[package]
name = "your_package"
@ -81,6 +81,4 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```

View file

@ -18,7 +18,7 @@ use std::io;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let query = "CA";
let data = "\
City,State,Population,Latitude,Longitude
@ -42,8 +42,6 @@ West Hollywood,CA,37031,34.0900000,-118.3608333";
wtr.flush()?;
Ok(())
}
#
# quick_main!(run);
```
_Disclaimer: this example has been adapted from [the csv crate tutorial](https://docs.rs/csv/*/csv/tutorial/index.html#filter-by-search)_.

View file

@ -55,7 +55,7 @@ struct Record {
description: String,
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let csv = "year,make,model,description
1948,Porsche,356,Luxury sports car
1967,Ford,Mustang fastback 1967,American car";
@ -75,8 +75,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`csv::ByteRecord`]: https://docs.rs/csv/*/csv/struct.ByteRecord.html

View file

@ -28,7 +28,7 @@ struct Record<'a> {
id: u64,
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let mut wtr = csv::Writer::from_writer(io::stdout());
let rec1 = Record { name: "Mark", place: "Melbourne", id: 56};
@ -43,6 +43,4 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```

View file

@ -22,7 +22,7 @@ use std::io;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let mut wtr = csv::Writer::from_writer(io::stdout());
wtr.write_record(&["Name", "Place", "ID"])?;
@ -34,8 +34,6 @@ fn run() -> Result<()> {
wtr.flush()?;
Ok(())
}
#
# quick_main!(run);
```
[`csv::Writer`]: https://docs.rs/csv/*/csv/struct.Writer.html

View file

@ -70,7 +70,7 @@ impl<'de> Deserialize<'de> for HexColor {
}
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let data = "color_name,color
red,#ff0000
green,#00ff00
@ -94,8 +94,6 @@ magenta,#ff00ff"
println!("{}", written);
Ok(())
}
#
# quick_main!(run);
```
[`csv::Reader::deserialize`]: https://docs.rs/csv/\*/csv/struct.Reader.html#method.deserialize

View file

@ -20,7 +20,7 @@ use base64::{encode, decode};
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let hello = b"hello rustaceans";
let encoded = encode(hello);
let decoded = decode(&encoded)?;
@ -31,8 +31,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`decode`]: https://docs.rs/base64/*/base64/fn.decode.html

View file

@ -21,7 +21,7 @@ use walkdir::WalkDir;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
for entry in WalkDir::new(".")
.follow_links(true)
.into_iter()
@ -36,8 +36,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`follow_links`]: https://docs.rs/walkdir/*/walkdir/struct.WalkDir.html#method.follow_links

View file

@ -20,7 +20,7 @@ use glob::{glob_with, MatchOptions};
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let options = MatchOptions {
case_sensitive: false,
..Default::default()
@ -32,8 +32,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html

View file

@ -23,7 +23,7 @@ use std::{env, fs};
# }
# }
#
fn run() -> Result<()> {
fn main() -> Result<()> {
let current_dir = env::current_dir()?;
println!(
"Entries modified in the last 24 hours in {:?}:",
@ -50,8 +50,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`DirEntry::path`]: https://doc.rust-lang.org/std/fs/struct.DirEntry.html#method.path

View file

@ -22,13 +22,11 @@ use glob::glob;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
for entry in glob("**/*.png")? {
println!("{}", entry?.display());
}
Ok(())
}
#
# quick_main!(run);
```

View file

@ -22,7 +22,7 @@ use std::process::{Command, Stdio};
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let directory = std::env::current_dir()?;
let mut du_output_child = Command::new("du")
.arg("-ah")
@ -60,8 +60,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html

View file

@ -27,7 +27,7 @@ struct Commit {
message: String,
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let output = Command::new("git").arg("log").arg("--oneline").output()?;
if !output.status.success() {
@ -52,8 +52,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html

View file

@ -21,7 +21,7 @@ use std::process::{Command, Stdio};
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let mut child = Command::new("python").stdin(Stdio::piped())
.stderr(Stdio::piped())
.stdout(Stdio::piped())
@ -47,8 +47,6 @@ fn run() -> Result<()> {
bail!("External command failed:\n {}", err)
}
}
#
# quick_main!(run);
```
[`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html

View file

@ -26,7 +26,7 @@ use regex::RegexSetBuilder;
# }
# }
#
fn run() -> Result<()> {
fn main() -> Result<()> {
let log_path = "application.log";
let buffered = BufReader::new(File::open(log_path)?);
@ -45,8 +45,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`regex::RegexSet`]: https://docs.rs/regex/*/regex/struct.RegexSet.html

View file

@ -32,7 +32,7 @@ impl<'a> fmt::Display for PhoneNumber<'a> {
}
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let phone_text = "
+1 505 881 9292 (v) +1 505 778 2212 (c) +1 505 881 9297 (f)
(202) 991 9534
@ -78,8 +78,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`Regex::captures_iter`]: https://docs.rs/regex/*/regex/struct.Regex.html#method.captures_iter

View file

@ -30,43 +30,42 @@ header! { (XRateLimitLimit, "X-RateLimit-Limit") => [usize] }
header! { (XRateLimitRemaining, "X-RateLimit-Remaining") => [usize] }
header! { (XRateLimitReset, "X-RateLimit-Reset") => [u64] }
fn run() -> Result<()> {
let url = "https://api.github.com/users/rust-lang-nursery ";
let client = reqwest::Client::new();
let response = client.get(url).send()?;
fn main() -> Result<()> {
loop {
let url = "https://api.github.com/users/rust-lang-nursery ";
let client = reqwest::Client::new();
let response = client.get(url).send()?;
let rate_limit = response.headers().get::<XRateLimitLimit>().ok_or(
"response doesn't include the expected X-RateLimit-Limit header",
)?;
let rate_limit = response.headers().get::<XRateLimitLimit>().ok_or(
"response doesn't include the expected X-RateLimit-Limit header",
)?;
let rate_remaining = response.headers().get::<XRateLimitRemaining>().ok_or(
"response doesn't include the expected X-RateLimit-Remaining header",
)?;
let rate_remaining = response.headers().get::<XRateLimitRemaining>().ok_or(
"response doesn't include the expected X-RateLimit-Remaining header",
)?;
let rate_reset_at = response.headers().get::<XRateLimitReset>().ok_or(
"response doesn't include the expected X-RateLimit-Reset header",
)?;
let rate_reset_at = response.headers().get::<XRateLimitReset>().ok_or(
"response doesn't include the expected X-RateLimit-Reset header",
)?;
let rate_reset_within = Duration::from_secs(**rate_reset_at) - UNIX_EPOCH.elapsed()?;
let rate_reset_within = Duration::from_secs(**rate_reset_at) - UNIX_EPOCH.elapsed()?;
if response.status() == StatusCode::Forbidden && **rate_remaining == 0 {
println!("Sleeping for {} seconds.", rate_reset_within.as_secs());
thread::sleep(rate_reset_within);
return run();
if response.status() == StatusCode::Forbidden && **rate_remaining == 0 {
println!("Sleeping for {} seconds.", rate_reset_within.as_secs());
thread::sleep(rate_reset_within);
return main();
} else {
println!(
"Rate limit is currently {}/{}, the reset of this limit will be within {} seconds.",
**rate_remaining,
**rate_limit,
rate_reset_within.as_secs(),
);
break;
}
}
else {
println!(
"Rate limit is currently {}/{}, the reset of this limit will be within {} seconds.",
**rate_remaining,
**rate_limit,
rate_reset_within.as_secs(),
);
}
Ok(())
}
#
# quick_main!(run);
```
[`hyper::header!`]: https://doc.servo.org/hyper/header/index.html#defining-custom-headers

View file

@ -36,7 +36,7 @@ struct Gist {
html_url: String,
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let gh_user = env::var("GH_USER")?;
let gh_pass = env::var("GH_PASS")?;
@ -68,8 +68,6 @@ fn run() -> Result<()> {
println!("Gist {} deleted! Status code: {}",gist.id, response.status());
Ok(())
}
#
# quick_main!(run);
```
The example uses [HTTP Basic Auth] in order to authorize access to [GitHub API].

View file

@ -47,8 +47,6 @@ fn run() -> Result<()> {
copy(&mut response, &mut dest)?;
Ok(())
}
#
# quick_main!(run);
```
[`File`]: https://doc.rust-lang.org/std/fs/struct.File.html

View file

@ -65,7 +65,7 @@ use reqwest::StatusCode;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let url = "https://httpbin.org/range/102400?duration=2";
const CHUNK_SIZE: u32 = 10240;
@ -95,8 +95,6 @@ fn run() -> Result<()> {
println!("Finished with success!");
Ok(())
}
#
# quick_main!(run);
```
[`reqwest::Client::get`]: https://docs.rs/reqwest/*/reqwest/struct.Client.html#method.get

View file

@ -26,7 +26,7 @@ use reqwest::Client;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let paste_api = "https://paste.rs";
let file = File::open("message")?;
@ -36,8 +36,6 @@ fn run() -> Result<()> {
println!("Your paste is located at: {}", response_body);
Ok(())
}
#
# quick_main!(run);
```
[`Client::post`]: https://docs.rs/reqwest/*/reqwest/struct.Client.html#method.post

View file

@ -21,7 +21,7 @@ use std::io::Read;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let mut res = reqwest::get("http://httpbin.org/get")?;
let mut body = String::new();
res.read_to_string(&mut body)?;
@ -32,8 +32,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`read_to_string`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_string

View file

@ -43,7 +43,7 @@ pub struct HeadersEcho {
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let url = Url::parse_with_params("http://httpbin.org/headers",
&[("lang", "rust"), ("browser", "servo")])?;
@ -65,8 +65,6 @@ fn run() -> Result<()> {
println!("{:?}", out);
Ok(())
}
#
# quick_main!(run);
```
[`header::Authorization`]: https://doc.servo.org/hyper/header/struct.Authorization.html

View file

@ -30,7 +30,7 @@ use reqwest::header::CONTENT_TYPE;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let response = reqwest::get("https://www.rust-lang.org/logos/rust-logo-32x32.png")?;
let headers = response.headers();
@ -54,8 +54,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`http`]: https://docs.rs/http/*/http/

View file

@ -49,7 +49,7 @@ fn check_link(url: &Url) -> Result<bool> {
Ok(res.status() != StatusCode::NOT_FOUND)
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let url = Url::parse("https://www.rust-lang.org/en-US/")?;
let res = reqwest::get(url.as_ref())?;
@ -72,8 +72,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`attr`]: https://docs.rs/select/*/select/node/struct.Node.html#method.attr

View file

@ -24,7 +24,7 @@ use select::predicate::Name;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let res = reqwest::get("https://www.rust-lang.org/en-US/")?;
Document::from_read(res)?
@ -34,8 +34,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`attr`]: https://docs.rs/select/*/select/node/struct.Node.html#method.attr

View file

@ -51,7 +51,7 @@ fn extract_links(content: &str) -> Result<HashSet<Cow<str>>> {
Ok(links)
}
fn run() -> Result<()> {
fn main() -> Result<()> {
let mut content = String::new();
reqwest::get(
"https://en.wikipedia.org/w/index.php?title=Rust_(programming_language)&action=raw",
@ -62,8 +62,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`Cow`]: https://doc.rust-lang.org/std/borrow/enum.Cow.html

View file

@ -23,7 +23,7 @@ use url::Url;
# }
# }
fn run() -> Result<()> {
fn main() -> Result<()> {
let full = "https://github.com/rust-lang/cargo?asdf";
let url = Url::parse(full)?;
@ -49,8 +49,6 @@ fn base_url(mut url: Url) -> Result<Url> {
Ok(url)
}
#
# quick_main!(run);
```
[`PathSegmentsMut::clear`]: https://docs.rs/url/*/url/struct.PathSegmentsMut.html#method.clear

View file

@ -39,7 +39,7 @@ use url::{Url, Origin, Host};
# }
# }
#
fn run() -> Result<()> {
fn main() -> Result<()> {
let s = "ftp://rust-lang.org/examples";
let url = Url::parse(s)?;
@ -55,8 +55,6 @@ fn run() -> Result<()> {
Ok(())
}
#
# quick_main!(run);
```
[`origin`]: https://docs.rs/url/*/url/struct.Url.html#method.origin