-- Leo's gemini proxy

-- Connecting to typed-hole.org:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

commit 36c10b5e3f878c631fbdfe0fe8a9ac256c478cb3

Author: Julien Blanchard <julien@sideburns.eu>

Date: Mon Jul 29 19:01:07 2019 +0200


Improve header and links parsing


diff --git a/src/main.rs b/src/main.rs

index db5eadf..5ec1801 100644

--- a/src/main.rs

+++ b/src/main.rs

@@ -1,9 +1,9 @@

use cursive::align::HAlign;

+use cursive::theme::Effect;

use cursive::traits::*;

+use cursive::utils::markup::StyledString;

use cursive::view::Scrollable;

use cursive::views::{Dialog, EditView, Panel, SelectView};

-use cursive::utils::markup::StyledString;

-use cursive::theme::Effect;

use cursive::Cursive;


extern crate native_tls;

@@ -23,55 +23,67 @@ use url::Url;


struct Header {

- code: i8,

- meta: String

+ code: i16,

+ meta: String,

}


struct Link {

url: String,

- label: String

+ label: String,

}


+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]

+struct ParseError;

+

+const HEADER_REGEX: &str = r"^(\d{1,3})[ \t](.*)$";

+const LINK_REGEX: &str = r"^=>\s(\S*)\s*(.*)?$";

+

impl FromStr for Header {

- type Err = std::string::ParseError;

+ type Err = ParseError;


- // Parses a string into an instance of 'Header'

+ // Parses a &str into an instance of 'Header'

fn from_str(line: &str) -> Result<Self, Self::Err> {

- let text = format!("{}", line);

- let link_regexp = Regex::new(r"^(\d*)\t(.*)$").unwrap();

+ let header_regexp = Regex::new(HEADER_REGEX).unwrap();


- let caps = link_regexp.captures(&text).unwrap();

- let code_str = caps.get(1).map_or("", |m| m.as_str());

- let meta_str = caps.get(2).map_or("", |m| m.as_str());

+ match header_regexp.captures(&line) {

+ Some(caps) => {

+ let code_str = caps.get(1).map_or("", |m| m.as_str());

+ let meta_str = caps.get(2).map_or("", |m| m.as_str());


- let code = code_str.parse::<i8>().unwrap();

- let meta = meta_str.to_string();

+ let code: i16 = code_str.parse().expect("2");

+ let meta = meta_str.to_string();


- Ok(Header {code, meta})

+ Ok(Header { code, meta })

+ }

+ None => Err(ParseError),

+ }

}

}


impl FromStr for Link {

- type Err = std::string::ParseError;

+ type Err = ParseError;


- // Parses a string into an instance of 'Link'

+ // Parses a &str into an instance of 'Link'

fn from_str(line: &str) -> Result<Self, Self::Err> {

- let text = format!("{}", line);

- let link_regexp = Regex::new(r"^=>\s(\S*)\s*(.*)?$").unwrap();

+ let link_regexp = Regex::new(LINK_REGEX).unwrap();


- let caps = link_regexp.captures(&text).unwrap();

- let url_str = caps.get(1).map_or("", |m| m.as_str());

- let label_str = caps.get(2).map_or("", |m| m.as_str());

+ match link_regexp.captures(&line) {

+ Some(caps) => {

+ let url_str = caps.get(1).map_or("", |m| m.as_str());

+ let label_str = caps.get(2).map_or("", |m| m.as_str());


- let url = url_str.to_string();

- let label = if label_str.is_empty() {

- url_str.to_string()

- } else {

- label_str.to_string()

- };

+ let url = url_str.to_string();

+ let label = if label_str.is_empty() {

+ url_str.to_string()

+ } else {

+ label_str.to_string()

+ };


- Ok(Link {url, label})

+ Ok(Link { url, label })

+ }

+ None => Err(ParseError),

+ }

}

}


@@ -95,12 +107,12 @@ fn main() {


siv.add_fullscreen_layer(

Dialog::around(Panel::new(

- select.with_id("main").scrollable().full_screen()

+ select.with_id("main").scrollable().full_screen(),

))

.title("Asuka Browser")

.h_align(HAlign::Center)

.button("Quit", |s| s.quit())

- .with_id("container")

+ .with_id("container"),

);


// We can quit by pressing q

@@ -119,11 +131,8 @@ fn prompt_for_url(s: &mut Cursive) {

.title("Enter URL")

// Padding is (left, right, top, bottom)

.padding((1, 1, 1, 0))

- .content(

- EditView::new()

- .on_submit(goto_url)

- .fixed_width(20)

- ).with_id("url_popup")

+ .content(EditView::new().on_submit(goto_url).fixed_width(20))

+ .with_id("url_popup"),

);

}


@@ -145,14 +154,12 @@ fn visit_url(s: &mut Cursive, url_s: &str) {

}


match parse_link(url_s) {

- Ok(url) => {

- match get_data(url) {

- Ok(new_content) => {

- draw_content(s, url_s, new_content);

- }

- Err(msg) => {

- s.add_layer(Dialog::info(msg));

- }

+ Ok(url) => match get_data(url) {

+ Ok(new_content) => {

+ draw_content(s, url_s, new_content);

+ }

+ Err(msg) => {

+ s.add_layer(Dialog::info(msg));

}

},

Err(_) => {

@@ -174,7 +181,7 @@ fn parse_link(url: &str) -> Result<url::Url, url::ParseError> {

};


Url::parse(&url_s)

- },

+ }

None => {

let url_s = if url.starts_with("gemini://") {

url.to_owned()

@@ -194,45 +201,31 @@ fn draw_content(s: &mut Cursive, url: &str, content: String) {

container.set_title(url);

main_view.clear();


- for line in content.lines() {

- if is_header(line) {

- // let _header = Header::from_str(line);

- } else if is_link(line) {

- let link = Link::from_str(line).unwrap();

- let mut formatted = StyledString::new();

- formatted.append(StyledString::styled(

- link.label,

- Effect::Underline,

- ));

-

- main_view.add_item(formatted, link.url)

- } else {

- main_view.add_item(line, "0".to_owned())

- }

+ match Header::from_str(content.lines().next().unwrap()) {

+ Ok(_header) => {}

+ Err(_) => {}

}


- main_view.set_on_submit(follow_link);

-}

-

-fn is_header(line: &str) -> bool {

- let text = format!("{}", line);

- let header_regexp = Regex::new(r"^(\d*)\t(\S*)$").unwrap();

-

- header_regexp.is_match(&text)

-}

+ for line in content.lines().skip(1) {

+ match Link::from_str(line) {

+ Ok(link) => {

+ let mut formatted = StyledString::new();

+ formatted.append(StyledString::styled(link.label, Effect::Underline));


-fn is_link(line: &str) -> bool {

- let text = format!("{}", line);

- let link_regexp = Regex::new(r"^=>\s(\S*)(.*)?$").unwrap();

+ main_view.add_item(formatted, link.url)

+ }

+ Err(_) => main_view.add_item(line, "0".to_owned()),

+ }

+ }


- link_regexp.is_match(&text)

+ main_view.set_on_submit(follow_link);

}


fn is_gemini_link(line: &str) -> bool {

line != "0"

}


-fn follow_link (s: &mut Cursive, line: &str) {

+fn follow_link(s: &mut Cursive, line: &str) {

if is_gemini_link(&line) {

let next_url = parse_link(&line);

visit_url(s, next_url.expect("Not an URL").as_str())

@@ -291,8 +284,8 @@ fn get_last_host() -> Option<String> {

Some(url) => {

let urlp = Url::parse(url).expect("not an URL");

Some(urlp.host_str().unwrap().to_owned())

- },

- None => None

+ }

+ None => None,

}

}




---

Served by Pollux Gemini Server.

-- Response ended

-- Page fetched on Sun May 19 10:50:44 2024