diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/environment.rs | 56 | ||||
| -rw-r--r-- | src/html.rs | 43 | ||||
| -rw-r--r-- | src/main.rs | 1 | ||||
| -rw-r--r-- | src/response.rs | 30 | ||||
| -rw-r--r-- | src/url.rs | 11 |
5 files changed, 85 insertions, 56 deletions
diff --git a/src/environment.rs b/src/environment.rs new file mode 100644 index 0000000..dd10171 --- /dev/null +++ b/src/environment.rs @@ -0,0 +1,56 @@ +use std::sync::LazyLock; + +pub static ENVIRONMENT: LazyLock<Environment> = + LazyLock::new(Environment::from_environment); + +pub struct Environment { + pub root: String, + pub css_external: Option<String>, + pub primary_colour: Option<String>, + pub favicon_external: Option<String>, + pub mathjax: bool, + pub head: Option<String>, + pub header: Option<String>, + pub plain_text_route: Option<String>, + pub condense_links: Vec<String>, + pub condense_links_at_headings: Vec<String>, + pub proxy_by_default: bool, + pub keep_gemini: Option<Vec<String>>, + pub embed_images: Option<String>, +} + +impl Environment { + fn from_environment() -> Self { + Self { + root: std::env::var("ROOT").unwrap_or_else(|_| { + log::warn!( + "could not use ROOT from environment variables, proceeding with \ + default root: gemini://fuwn.me" + ); + "gemini://fuwn.me".to_string() + }), + css_external: std::env::var("CSS_EXTERNAL").ok(), + primary_colour: std::env::var("PRIMARY_COLOUR").ok(), + favicon_external: std::env::var("FAVICON_EXTERNAL").ok(), + mathjax: std::env::var("MATHJAX") + .map(|v| v.to_lowercase() == "true") + .unwrap_or(true), + head: std::env::var("HEAD").ok(), + header: std::env::var("HEADER").ok(), + plain_text_route: std::env::var("PLAIN_TEXT_ROUTE").ok(), + condense_links: std::env::var("CONDENSE_LINKS") + .map(|s| s.split(',').map(String::from).collect()) + .unwrap_or_default(), + condense_links_at_headings: std::env::var("CONDENSE_LINKS_AT_HEADINGS") + .map(|s| s.split(',').map(String::from).collect()) + .unwrap_or_default(), + proxy_by_default: std::env::var("PROXY_BY_DEFAULT") + .map(|v| v.to_lowercase() == "true") + .unwrap_or(true), + keep_gemini: std::env::var("KEEP_GEMINI") + .ok() + .map(|s| s.split(',').map(String::from).collect()), + embed_images: std::env::var("EMBED_IMAGES").ok(), + } + } +} diff --git a/src/html.rs b/src/html.rs index ae79489..11ad698 100644 --- a/src/html.rs +++ b/src/html.rs @@ -1,7 +1,7 @@ use { - crate::url::matches_pattern, + crate::{environment::ENVIRONMENT, url::matches_pattern}, germ::ast::Node, - std::{env::var, fmt::Write}, + std::fmt::Write, url::Url, }; @@ -47,26 +47,14 @@ pub fn from_gemini( let mut title = String::new(); let mut previous_link = false; let mut previous_link_count = 0; - let condense_links = { - let links = var("CONDENSE_LINKS").map_or_else( - |_| vec![], - |condense_links| { - condense_links - .split(',') - .map(std::string::ToString::to_string) - .collect() - }, - ); - - links.contains(&url.path().to_string()) || links.contains(&"*".to_string()) - }; - let condensible_headings_value = - var("CONDENSE_LINKS_AT_HEADINGS").unwrap_or_default(); - let condensible_headings = if condensible_headings_value.is_empty() { - vec![] - } else { - condensible_headings_value.split(',').collect::<Vec<_>>() - }; + let condense_links = + ENVIRONMENT.condense_links.contains(&url.path().to_string()) + || ENVIRONMENT.condense_links.contains(&"*".to_string()); + let condensible_headings = ENVIRONMENT + .condense_links_at_headings + .iter() + .map(String::as_str) + .collect::<Vec<_>>(); let mut in_condense_links_flag_trap = !condensible_headings.is_empty(); for node in ast { @@ -154,10 +142,7 @@ pub fn from_gemini( href = link_from_host_href(url, &href)?; } - if var("PROXY_BY_DEFAULT") - .unwrap_or_else(|_| "true".to_string()) - .to_lowercase() - == "true" + if ENVIRONMENT.proxy_by_default && href.contains("gemini://") && !surface { @@ -190,9 +175,7 @@ pub fn from_gemini( } } - if let Ok(keeps) = var("KEEP_GEMINI") { - let patterns = keeps.split(',').collect::<Vec<_>>(); - + if let Some(patterns) = &ENVIRONMENT.keep_gemini { if (href.starts_with('/') || !href.contains("://")) && !surface { let temporary_href = link_from_host_href(url, &href)?; let should_exclude = patterns @@ -213,7 +196,7 @@ pub fn from_gemini( } } - if let Ok(embed_images) = var("EMBED_IMAGES") { + if let Some(embed_images) = &ENVIRONMENT.embed_images { if let Some(extension) = std::path::Path::new(&href).extension() { if extension == "png" || extension == "jpg" diff --git a/src/main.rs b/src/main.rs index 56402c9..a39e83e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ #![recursion_limit = "128"] #![allow(clippy::cast_precision_loss)] +mod environment; mod html; mod response; mod url; diff --git a/src/response.rs b/src/response.rs index 68c1690..5a3f204 100644 --- a/src/response.rs +++ b/src/response.rs @@ -1,9 +1,12 @@ pub mod configuration; use { - crate::url::{from_path as url_from_path, matches_pattern}, + crate::{ + environment::ENVIRONMENT, + url::{from_path as url_from_path, matches_pattern}, + }, actix_web::{Error, HttpResponse}, - std::{env::var, fmt::Write, time::Instant}, + std::{fmt::Write, time::Instant}, }; const CSS: &str = include_str!("../default.css"); @@ -142,11 +145,8 @@ pub async fn default( ); } - if let Ok(css) = var("CSS_EXTERNAL") { - let stylesheets = - css.split(',').filter(|s| !s.is_empty()).collect::<Vec<_>>(); - - for stylesheet in stylesheets { + if let Some(css) = &ENVIRONMENT.css_external { + for stylesheet in css.split(',').filter(|s| !s.is_empty()) { let _ = write!( &mut html_context, "<link rel=\"stylesheet\" type=\"text/css\" href=\"{stylesheet}\">", @@ -158,7 +158,7 @@ pub async fn default( r#"<link rel="stylesheet" href="https://latex.vercel.app/style.css"><style>{CSS}</style>"# ); - if let Ok(primary) = var("PRIMARY_COLOUR") { + if let Some(primary) = &ENVIRONMENT.primary_colour { let _ = write!( &mut html_context, "<style>:root {{ --primary: {primary} }}</style>" @@ -171,16 +171,14 @@ pub async fn default( } } - if let Ok(favicon) = var("FAVICON_EXTERNAL") { + if let Some(favicon) = &ENVIRONMENT.favicon_external { let _ = write!( &mut html_context, "<link rel=\"icon\" type=\"image/x-icon\" href=\"{favicon}\">", ); } - if var("MATHJAX").unwrap_or_else(|_| "true".to_string()).to_lowercase() - == "true" - { + if ENVIRONMENT.mathjax { html_context.push_str( r#"<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"> @@ -188,15 +186,15 @@ pub async fn default( ); } - if let Ok(head) = var("HEAD") { - html_context.push_str(&head); + if let Some(head) = &ENVIRONMENT.head { + html_context.push_str(head); } let _ = write!(&mut html_context, "<title>{gemini_title}</title>"); let _ = write!(&mut html_context, "</head><body>"); if !http_request.path().starts_with("/proxy") { - if let Ok(header) = var("HEADER") { + if let Some(header) = &ENVIRONMENT.header { let _ = write!( &mut html_context, "<big><blockquote>{header}</blockquote></big>" @@ -260,7 +258,7 @@ pub async fn default( env!("VERGEN_GIT_SHA").get(0..5).unwrap_or("UNKNOWN"), ); - if let Ok(plain_texts) = var("PLAIN_TEXT_ROUTE") { + if let Some(plain_texts) = &ENVIRONMENT.plain_text_route { if plain_texts.split(',').any(|r| { matches_pattern(r, http_request.path()) || matches_pattern(r, http_request.path().trim_end_matches('/')) @@ -42,16 +42,7 @@ pub fn from_path( } else { format!( "{}{}{}", - { - std::env::var("ROOT").unwrap_or_else(|_| { - warn!( - "could not use ROOT from environment variables, proceeding with \ - default root: gemini://fuwn.me" - ); - - "gemini://fuwn.me".to_string() - }) - }, + &crate::environment::ENVIRONMENT.root, path, if fallback { "/" } else { "" } ) |