embrace errors

pull/6/head
dvkt 5 years ago
parent cfc5803991
commit 6690372441

@ -1,6 +1,6 @@
use gopher;
use std::io;
use std::io::{Read, Write};
use std::io::{Read, Result, Write};
use std::net::TcpStream;
use std::net::ToSocketAddrs;
use std::os::unix::fs::OpenOptionsExt;
@ -75,18 +75,18 @@ pub fn type_for_char(c: char) -> Option<Type> {
}
// produces an io::Error more easily
pub fn io_error(msg: String) -> io::Error {
pub fn error(msg: String) -> io::Error {
io::Error::new(io::ErrorKind::Other, msg)
}
// Fetches a gopher URL and returns a raw Gopher response.
pub fn fetch_url(url: &str) -> io::Result<String> {
pub fn fetch_url(url: &str) -> Result<String> {
let (_, host, port, sel) = parse_url(url);
fetch(host, port, sel)
}
// Fetches a gopher URL by its component parts and returns a raw Gopher response.
pub fn fetch(host: &str, port: &str, selector: &str) -> io::Result<String> {
pub fn fetch(host: &str, port: &str, selector: &str) -> Result<String> {
let mut body = String::new();
let selector = selector.replace('?', "\t"); // search queries
@ -95,7 +95,7 @@ pub fn fetch(host: &str, port: &str, selector: &str) -> io::Result<String> {
.and_then(|mut socks| {
socks
.next()
.ok_or_else(|| io_error("Can't create socket".to_string()))
.ok_or_else(|| error("Can't create socket".to_string()))
})
.and_then(|sock| TcpStream::connect_timeout(&sock, TCP_TIMEOUT_DURATION))
.and_then(|mut stream| {
@ -110,7 +110,7 @@ pub fn fetch(host: &str, port: &str, selector: &str) -> io::Result<String> {
}
// Downloads a binary to disk and returns the path it was saved to.
pub fn download_url(url: &str) -> io::Result<String> {
pub fn download_url(url: &str) -> Result<String> {
let (_, host, port, sel) = parse_url(url);
let sel = sel.replace('?', "\t"); // search queries
let filename = sel
@ -126,7 +126,7 @@ pub fn download_url(url: &str) -> io::Result<String> {
.and_then(|mut socks| {
socks
.next()
.ok_or_else(|| io_error("Can't create socket".to_string()))
.ok_or_else(|| error("Can't create socket".to_string()))
})
.and_then(|sock| TcpStream::connect_timeout(&sock, TCP_TIMEOUT_DURATION))
.and_then(|mut stream| {

@ -3,8 +3,7 @@ mod view;
pub use self::action::Action;
pub use self::view::View;
use std::io;
use std::io::{stdin, stdout, Write};
use std::io::{stdin, stdout, Result, Write};
use std::process;
use std::process::Stdio;
use std::sync::mpsc;
@ -16,7 +15,7 @@ use termion::raw::IntoRawMode;
use termion::terminal_size;
use gopher;
use gopher::io_error;
use gopher::error;
use gopher::Type;
use help;
use menu::Menu;
@ -92,6 +91,7 @@ impl UI {
self.render_status().unwrap_or_else(|| "".into()),
);
self.status.clear();
self.dirty = false;
}
}
@ -106,7 +106,7 @@ impl UI {
}
}
pub fn open(&mut self, url: &str) -> io::Result<()> {
pub fn open(&mut self, url: &str) -> Result<()> {
self.status.clear();
// no open loops
@ -133,7 +133,7 @@ impl UI {
})
}
fn download(&mut self, url: &str) -> io::Result<()> {
fn download(&mut self, url: &str) -> Result<()> {
let url = url.to_string();
self.spinner("", move || gopher::download_url(&url))
.and_then(|res| res)
@ -143,7 +143,7 @@ impl UI {
})
}
fn fetch(&mut self, url: &str) -> io::Result<Page> {
fn fetch(&mut self, url: &str) -> Result<Page> {
// on-line help
if url.starts_with("gopher://help/") {
return self.fetch_help(url);
@ -156,19 +156,19 @@ impl UI {
match typ {
Type::Menu | Type::Search => Ok(Box::new(Menu::from(url.to_string(), res))),
Type::Text | Type::HTML => Ok(Box::new(Text::from(url.to_string(), res))),
_ => Err(io_error(format!("Unsupported Gopher Response: {:?}", typ))),
_ => Err(error(format!("Unsupported Gopher Response: {:?}", typ))),
}
}
// get Menu for on-line help url, ex: gopher://help/1/types
fn fetch_help(&mut self, url: &str) -> io::Result<Page> {
fn fetch_help(&mut self, url: &str) -> Result<Page> {
if let Some(source) = help::lookup(
&url.trim_start_matches("gopher://help/")
.trim_start_matches("1/"),
) {
Ok(Box::new(Menu::from(url.to_string(), source.to_string())))
} else {
Err(gopher::io_error(format!("Help file not found: {}", url)))
Err(gopher::error(format!("Help file not found: {}", url)))
}
}
@ -178,7 +178,7 @@ impl UI {
&mut self,
label: &str,
work: F,
) -> io::Result<T> {
) -> Result<T> {
let req = thread::spawn(work);
let (tx, rx) = mpsc::channel();
@ -205,7 +205,7 @@ impl UI {
let result = req.join();
tx.send(true); // stop spinner
self.dirty = true;
result.map_err(|e| io_error(format!("Spinner error: {:?}", e)))
result.map_err(|e| error(format!("Spinner error: {:?}", e)))
}
pub fn render(&mut self) -> String {
@ -322,7 +322,7 @@ impl UI {
Action::None
}
fn process_action(&mut self, action: Action) -> io::Result<()> {
fn process_action(&mut self, action: Action) -> Result<()> {
match action {
Action::Keypress(Key::Esc) => self.status.clear(),
Action::Keypress(Key::Ctrl('c')) => {
@ -334,7 +334,7 @@ impl UI {
}
}
Action::Keypress(Key::Ctrl('q')) => self.running = false,
Action::Error(e) => return Err(io_error(e)),
Action::Error(e) => return Err(error(e)),
Action::Redraw => self.dirty = true,
Action::Open(url) => self.open(&url)?,
Action::Keypress(Key::Left) | Action::Keypress(Key::Backspace) => {
@ -391,16 +391,16 @@ impl Drop for UI {
}
}
fn copy_to_clipboard(data: &str) -> io::Result<()> {
fn copy_to_clipboard(data: &str) -> Result<()> {
spawn_os_clipboard()
.and_then(|mut child| {
let child_stdin = child.stdin.as_mut().unwrap();
child_stdin.write_all(data.as_bytes())
})
.map_err(|e| io_error(format!("Clipboard error: {}", e)))
.map_err(|e| error(format!("Clipboard error: {}", e)))
}
fn spawn_os_clipboard() -> io::Result<process::Child> {
fn spawn_os_clipboard() -> Result<process::Child> {
if cfg!(target_os = "macos") {
process::Command::new("pbcopy")
.stdin(Stdio::piped())
@ -414,7 +414,7 @@ fn spawn_os_clipboard() -> io::Result<process::Child> {
}
// runs the `open` shell command
fn open_external(url: &str) -> io::Result<()> {
fn open_external(url: &str) -> Result<()> {
process::Command::new("open")
.arg(url)
.output()

Loading…
Cancel
Save