use scoped_error::{Many, expect_error_fn};
use std::{error::Error, thread};
fn fetch_all(urls: Vec<String>) -> Result<Vec<String>, Many> {
let handles: Vec<_> = urls
.into_iter()
.map(|url| thread::spawn(move || fetch(&url)))
.collect();
let results: Vec<_> = handles.into_iter().map(|h| h.join().unwrap()).collect();
Many::from_results("failed to fetch URLs", results)
}
fn fetch(url: &str) -> Result<String, scoped_error::Error> {
let err = || scoped_error::Error::new(format!("failed to fetch {}", url));
expect_error_fn(err, || {
connect(url)?;
Ok("connected".into())
})
}
fn connect(url: &str) -> Result<String, scoped_error::Error> {
let err = || scoped_error::Error::new(format!("failed to connect to {}", url));
expect_error_fn(err, || Err("no network connection")?)
}
fn main() -> Result<(), Box<dyn Error>> {
fetch_all(vec![
"https://example.com".to_string(),
"https://example.org".to_string(),
])?;
Ok(())
}