From 05f1e6734bf4d116ab491d07b28fa8d26ca79bbb Mon Sep 17 00:00:00 2001 From: dvkt Date: Mon, 16 Dec 2019 17:01:23 -0800 Subject: [PATCH] parse urls --- src/gopher.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/menu.rs | 7 ++++++ src/ui.rs | 8 ++++++- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/gopher.rs b/src/gopher.rs index fa2bf21..edae6cf 100644 --- a/src/gopher.rs +++ b/src/gopher.rs @@ -43,3 +43,62 @@ pub fn fetch(host: &str, port: &str, selector: &str) -> io::Result { Err(e) => Err(e), } } + +enum Parsing { + Host, + Port, + Selector, +} + +// Parses gopher URL into parts. +pub fn parse_url<'a>(url: &'a str) -> (Type, &'a str, &'a str, &'a str) { + let url = url.trim_start_matches("gopher://"); + + let mut host = ""; + let mut port = "70"; + let mut sel = "/"; + let mut typ = Type::Text; + let mut state = Parsing::Host; + let mut start = 0; + + for (i, c) in url.char_indices() { + match state { + Parsing::Host => { + match c { + ':' => state = Parsing::Port, + '/' => state = Parsing::Selector, + _ => continue, + } + host = &url[start..i]; + start = i + 1; + } + Parsing::Port => { + if c == '/' { + state = Parsing::Selector; + port = &url[start..i]; + start = i + 1; + } + } + Parsing::Selector => {} + } + } + + match state { + Parsing::Selector => sel = &url[start..], + Parsing::Port => port = &url[start..], + Parsing::Host => host = &url[start..], + }; + + let mut chars = sel.chars(); + if let (Some(fst), Some('/')) = (chars.nth(0), chars.nth(1)) { + match fst { + '0' => typ = Type::Text, + '1' => typ = Type::Menu, + 'h' => typ = Type::HTML, + _ => {} + } + sel = &sel[2..]; + } + + (typ, host, port, sel) +} diff --git a/src/menu.rs b/src/menu.rs index cd60c60..ede2d6d 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -29,6 +29,13 @@ pub struct Line { } impl View for MenuView { + fn render(&self) -> String { + let mut out = self.menu.raw.to_string(); + out.push('\n'); + out.push_str(&format!("{:#?}", self)); + out + } + fn process_input(&mut self, key: Key) -> Action { match key { Key::Char('\n') => return Action::Open, diff --git a/src/ui.rs b/src/ui.rs index 92559fe..ec04dba 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -32,6 +32,7 @@ pub enum Action { pub trait View { fn process_input(&mut self, c: Key) -> Action; + fn render(&self) -> String; } impl UI { @@ -56,7 +57,12 @@ impl UI { pub fn render(&self) -> String { // let (cols, rows) = termion::terminal_size().expect("can't get terminal size"); - String::new() + if self.pages.len() > 0 && self.page < self.pages.len() { + if let Some(page) = self.pages.get(self.page) { + return page.render(); + } + } + String::from("N/A") } pub fn load(&mut self, url: String) {