diff --git a/Makefile b/Makefile index deea73a..bca53f1 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ run: phetch ./phetch -phetch: +phetch: src/*.rs cargo build cp target/debug/phetch . diff --git a/src/fetch.rs b/src/fetch.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/main.rs b/src/main.rs index fac3d8f..9b05f11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,14 @@ #![allow(unused_must_use)] -#![allow(unused_imports)] extern crate termion; - use std::collections::HashMap; use std::io::{stdin, stdout, Read, Write}; -use std::net::TcpStream; use termion::event::Key; use termion::input::TermRead; use termion::raw::IntoRawMode; +mod fetch; mod page; mod types; mod ui; @@ -19,21 +17,25 @@ use ui::*; fn main() { let args: Vec = std::env::args().collect(); if args.len() < 2 { - usage(); + print_usage(); return; } let host = args.get(1).unwrap(); - let port = String::from("70"); - let selector = String::from("/"); + let port = "70".to_string(); let port = args.get(2).unwrap_or(&port); + let selector = "/".to_string(); let selector = args.get(3).unwrap_or(&selector); if host == "--help" || host == "-h" || host == "-help" { - usage(); + print_usage(); return; } + + let mut ui = UI::new(); + ui.load(host, port, selector); + ui.run(); } -fn usage() { +fn print_usage() { println!("\x1B[93;1musage:\x1B[0m "); println!("\t$ phetch host [port [selector]]"); } diff --git a/src/page.rs b/src/page.rs index 6910df8..f85bd77 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,3 +1,6 @@ +use std::io; +use std::io::{Read, Write}; +use std::net::TcpStream; use types::Type; #[derive(Debug)] @@ -20,3 +23,47 @@ pub struct Page { input: String, // user's inputted value offset: usize, // scrolling position } + +impl Page { + fn new() -> Page { + Page { + raw: String::new(), + url: String::new(), + links: vec![], + link: 0, + typ: Type::Menu, + input: String::new(), + offset: 0, + } + } + + pub fn load(host: &str, port: &str, selector: &str) -> Option { + let mut page = Self::new(); + if let Some(res) = Self::fetch(host, port, selector) { + page.raw = res; + Some(page) + } else { + None + } + } + + // Fetches a URL and returns a raw Gopher response. + fn fetch(host: &str, port: &str, selector: &str) -> Option { + let mut body = String::new(); + let stream = TcpStream::connect(format!("{}:{}", host, port)) + .and_then(|mut stream| { + stream.write(format!("{}\r\n", selector).as_ref()); + Ok(stream) + }) + .and_then(|mut stream| { + stream.read_to_string(&mut body); + Ok(()) + }); + + if let Ok(()) = stream { + Some(body) + } else { + None + } + } +} diff --git a/src/types.rs b/src/types.rs index 0f7b8f6..b43a2e3 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,8 @@ +#![allow(dead_code)] + #[derive(Copy, Clone, PartialEq, Debug)] pub enum Type { - TextFile, // 0 + Text, // 0 Menu, // 1 CSOEntity, // 2 Error, // 3 diff --git a/src/ui.rs b/src/ui.rs index ebe9e13..4c8e0b3 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -14,6 +14,15 @@ impl UI { } } + pub fn load(&mut self, host: &str, port: &str, selector: &str) { + if let Some(page) = Page::load(host, port, selector) { + self.pages.push(page); + } else { + eprintln!("error loading {}:{}{}", host, port, selector); + std::process::exit(1); + } + } + pub fn print(&self) { print!("{}", self.render()); } @@ -21,4 +30,13 @@ impl UI { pub fn render(&self) -> String { String::new() } + + pub fn run(&self) { + loop { + self.print(); + self.respond_to_user(); + } + } + + fn respond_to_user(&self) {} }