show errors in UI

pull/6/head
dvkt 5 years ago
parent d9baf79025
commit ffd4530472

@ -6,6 +6,7 @@ mod gopher;
mod menu;
mod text;
mod ui;
use std::process::exit;
use ui::UI;
fn main() {
@ -23,6 +24,7 @@ fn main() {
print_raw(url);
} else {
eprintln!("--raw needs gopher-url");
exit(1);
}
return;
}
@ -40,14 +42,20 @@ fn main() {
if !url.is_empty() && url.chars().nth(0).unwrap() == '-' {
eprintln!("unknown flag: {}\n", url);
print_usage();
return;
exit(1);
}
let mut ui = UI::new();
ui.open(url);
ui.open(url)
.or_else(|e| Err(fatal(&format!("\r\x1b[91m{}\x1b[0m", e))));
ui.run();
}
fn fatal(s: &str) {
eprintln!("{}", s);
exit(1);
}
fn print_version() {
println!("\x1b[93;1mphetch v0.0.1-dev\x1b[m");
}

@ -1,3 +1,4 @@
use std::io;
use std::io::{stdin, stdout, Write};
use std::process::{Command, Stdio};
use termion::input::TermRead;
@ -29,6 +30,7 @@ pub enum Action {
Redraw, // redraw everything
Quit, // yup
Clipboard(String), // copy to clipboard
Error(String), // error message
Unknown, // handler doesn't know what to do
}
@ -39,6 +41,22 @@ pub trait View {
fn set_size(&mut self, cols: usize, rows: usize);
}
macro_rules! status {
($e:expr) => { status!("{}", $e); };
($e:expr, $($y:expr),*) => {{
print!("\r{}\x1b[0m\x1b[K", format!($e, $($y),*));
stdout().flush();
}}
}
macro_rules! error {
($e:expr) => { error!("{}", $e); };
($e:expr, $($y:expr),*) => {{
eprint!("\r\x1b[0;91m{}\x1b[0m\x1b[K", format!($e, $($y),*));
stdout().flush();
}}
}
impl UI {
pub fn new() -> UI {
UI {
@ -70,8 +88,10 @@ impl UI {
}
pub fn update(&mut self) {
if let Action::Quit = self.process_input() {
self.running = false;
match self.process_input() {
Action::Quit => self.running = false,
Action::Error(e) => error!(e),
_ => {}
}
}
@ -86,27 +106,24 @@ impl UI {
String::from("N/A")
}
pub fn open(&mut self, url: &str) {
print!("\r\x1b[90mLoading...\x1b[0m\x1b[K");
stdout().flush();
self.dirty = true;
pub fn open(&mut self, url: &str) -> io::Result<()> {
status!("\x1b[90mLoading...");
let (typ, host, port, sel) = gopher::parse_url(url);
let response = gopher::fetch(host, port, sel)
.map_err(|e| {
eprintln!("\x1B[91merror loading \x1b[93m{}: \x1B[0m{}[?25h", url, e); // TODO
std::process::exit(1);
gopher::fetch(host, port, sel)
.and_then(|response| match typ {
Type::Menu => Ok(self.add_page(MenuView::from(url.to_string(), response))),
Type::Text => Ok(self.add_page(TextView::from(url.to_string(), response))),
Type::HTML => Ok(self.add_page(TextView::from(url.to_string(), response))),
_ => Err(io::Error::new(
io::ErrorKind::Other,
format!("Unsupported Gopher Type: {:?}", typ),
)),
})
.unwrap();
match typ {
Type::Menu => self.add_page(MenuView::from(url.to_string(), response)),
Type::Text => self.add_page(TextView::from(url.to_string(), response)),
Type::HTML => self.add_page(TextView::from(url.to_string(), response)),
_ => panic!("unknown type: {:?}", typ),
}
.map_err(|e| io::Error::new(e.kind(), format!("Error loading {}: {}", url, e)))
}
fn add_page<T: View + 'static>(&mut self, view: T) {
self.dirty = true;
if !self.pages.is_empty() && self.page < self.pages.len() - 1 {
self.pages.truncate(self.page + 1);
}
@ -125,10 +142,10 @@ impl UI {
self.dirty = true;
Action::None
}
Action::Open(url) => {
self.open(&url);
Action::None
}
Action::Open(url) => match self.open(&url) {
Err(e) => Action::Error(e.to_string()),
Ok(()) => Action::None,
},
Action::Back => {
if self.page > 0 {
self.dirty = true;

Loading…
Cancel
Save