2
0
mirror of https://github.com/xvxx/phetch synced 2024-11-10 13:10:54 +00:00

parse links

This commit is contained in:
dvkt 2019-12-16 13:49:06 -08:00
parent 02940ec955
commit 7689cc10a0
3 changed files with 109 additions and 49 deletions

View File

@ -1,4 +1,3 @@
use std::error::Error;
use std::io; use std::io;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::net::TcpStream; use std::net::TcpStream;
@ -7,9 +6,9 @@ use types::Type;
#[derive(Debug)] #[derive(Debug)]
pub struct Link { pub struct Link {
pos: usize, // which link in the page pos: usize, // which link in the page
title: String, name: String,
host: String, host: String,
port: usize, port: String,
selector: String, selector: String,
typ: Type, typ: Type,
} }
@ -26,25 +25,14 @@ pub struct Page {
} }
impl Page { impl Page {
fn new() -> Page { pub fn from(url: String, gopher_response: String) -> Page {
Page { Self::parse(url, gopher_response)
raw: String::new(),
url: String::new(),
links: vec![],
link: 0,
typ: Type::Menu,
input: String::new(),
offset: 0,
}
} }
// Loads a Page given a URL.
pub fn load(host: &str, port: &str, selector: &str) -> io::Result<Page> { pub fn load(host: &str, port: &str, selector: &str) -> io::Result<Page> {
let mut page = Self::new();
match Self::fetch(host, port, selector) { match Self::fetch(host, port, selector) {
Ok(res) => { Ok(res) => Ok(Page::from(format!("{}:{}{}", host, port, selector), res)),
page.raw = res;
Ok(page)
}
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@ -67,4 +55,69 @@ impl Page {
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
// Parses the links in a raw Gopher response;
fn parse(url: String, raw: String) -> Page {
let mut links = vec![];
let mut start = true;
let mut is_link = false;
let mut link = (0, 0, Type::Menu);
let mut count = 0;
for (i, c) in raw.char_indices() {
if start {
match c {
'0' => {
is_link = true;
link.0 = i + 1;
link.2 = Type::Text;
}
'1' => {
is_link = true;
link.0 = i + 1;
link.2 = Type::Menu;
}
'h' => {
is_link = true;
link.0 = i + 1;
link.2 = Type::HTML;
}
'\n' => continue,
_ => is_link = false,
}
start = false;
} else if c == '\n' {
start = true;
if is_link && i > link.0 {
link.1 = i;
let mut line = [""; 4];
for (j, s) in raw[link.0..link.1].split('\t').enumerate() {
if j < line.len() {
line[j] = s;
}
}
links.push(Link {
name: line[0].to_string(),
selector: line[1].to_string(),
host: line[2].to_string(),
port: line[3].trim_end_matches('\r').to_string(),
typ: link.2,
pos: count,
});
count += 1;
is_link = false;
}
}
}
Page {
raw,
url,
links,
link: 0,
typ: Type::Menu,
input: String::new(),
offset: 0,
}
}
} }

View File

@ -2,22 +2,21 @@
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Debug)]
pub enum Type { pub enum Type {
Text, // 0 Text = '0' as isize, // 0
Menu, // 1 Menu, // 1
CSOEntity, // 2 CSOEntity, // 2
Error, // 3 Error, // 3
BinhexFile, // 4 Binhex, // 4
DOSFile, // 5 DOSFile, // 5
UUEncodedFile, // 6 UUEncoded, // 6
Search, // 7 Search, // 7
Telnet, // 8 Telnet, // 8
BinaryFile, // 9 Binary, // 9
Mirror, // + Mirror = '+' as isize, // +
GIF, // g GIF = 'g' as isize, // g
Image, // i Telnet3270 = 'T' as isize, // T
Telnet3270, // T HTML = 'h' as isize, // h
HTMLFile, // h Information = 'i' as isize, // i
Information, // i Sound = 's' as isize, // s
Sound, // s Document = 'd' as isize, // d
Document, // d
} }

View File

@ -14,9 +14,25 @@ impl UI {
} }
} }
pub fn run(&self) {
loop {
self.print();
self.respond_to_user();
}
}
pub fn print(&self) {
// print!("{}", self.render());
print!("{:#?}", self);
}
pub fn render(&self) -> String {
String::new()
}
pub fn load(&mut self, host: &str, port: &str, selector: &str) { pub fn load(&mut self, host: &str, port: &str, selector: &str) {
match Page::load(host, port, selector) { match Page::load(host, port, selector) {
Ok(page) => self.pages.push(page), Ok(page) => self.add_page(page),
Err(e) => { Err(e) => {
eprintln!( eprintln!(
"\x1B[91merror loading \x1b[93m{}:{}{}: \x1B[0m{}", "\x1B[91merror loading \x1b[93m{}:{}{}: \x1B[0m{}",
@ -27,18 +43,10 @@ impl UI {
} }
} }
pub fn print(&self) { fn add_page(&mut self, page: Page) {
print!("{}", self.render()); self.pages.push(page);
} if self.pages.len() > 1 {
self.page += 1;
pub fn render(&self) -> String {
String::new()
}
pub fn run(&self) {
loop {
self.print();
self.respond_to_user();
} }
} }