diff --git a/crates/wastebin_highlight/src/highlight.rs b/crates/wastebin_highlight/src/highlight.rs index 6284f8d7..e4768d1f 100644 --- a/crates/wastebin_highlight/src/highlight.rs +++ b/crates/wastebin_highlight/src/highlight.rs @@ -1,4 +1,3 @@ -use std::cmp::Ordering; use std::fmt::Write; use syntect::html::{ClassStyle, line_tokens_to_classed_spans}; @@ -26,7 +25,7 @@ pub struct Html(String); #[derive(Clone)] pub struct Highlighter { syntax_set: SyntaxSet, - syntaxes: Vec, + ordered_syntaxes: Vec, } /// Syntax reference. @@ -41,16 +40,11 @@ impl Default for Highlighter { fn default() -> Self { let syntax_set = two_face::syntax::extra_newlines(); let mut syntaxes = syntax_set.syntaxes().to_vec(); - syntaxes.sort_by(|a, b| { - a.name - .to_lowercase() - .partial_cmp(&b.name.to_lowercase()) - .unwrap_or(Ordering::Less) - }); + syntaxes.sort_unstable_by_key(|s| s.name.to_lowercase()); Self { syntax_set, - syntaxes, + ordered_syntaxes: syntaxes, } } } @@ -62,22 +56,18 @@ fn escape(s: &str, buf: &mut String) -> std::fmt::Result { let pile_o_bits = s; let mut last = 0; for (i, ch) in s.bytes().enumerate() { - match ch as char { - '<' | '>' | '&' | '\'' | '"' => { - buf.write_str(&pile_o_bits[last..i])?; - let s = match ch as char { - '>' => ">", - '<' => "<", - '&' => "&", - '\'' => "'", - '"' => """, - _ => unreachable!(), - }; - buf.write_str(s)?; - last = i + 1; - } - _ => {} - } + let escaping = match ch as char { + '>' => ">", + '<' => "<", + '&' => "&", + '\'' => "'", + '"' => """, + _ => continue, + }; + + buf.write_str(&pile_o_bits[last..i])?; + buf.write_str(escaping)?; + last = i + 1; } if last < s.len() { @@ -135,10 +125,10 @@ fn line_tokens_to_classed_spans_md( // Insert href and close attribute ... escape(&line[cur_index..i], &mut s)?; s.push_str(r#"">"#); - escape(&line[cur_index..i], &mut s)?; - } else { - escape(&line[cur_index..i], &mut s)?; } + + escape(&line[cur_index..i], &mut s)?; + cur_index = i; } stack.apply_with_hook(op, |basic_op, _| match basic_op { @@ -225,6 +215,7 @@ impl Highlighter { } // Strip stray newlines that cause vertically stretched lines. + html.reserve(formatted.len()); for c in formatted.chars().filter(|c| *c != '\n') { html.push(c); } @@ -244,7 +235,7 @@ impl Highlighter { /// Return iterator over all available [`Syntax`]es with their canonical name and usual file /// extensions. pub fn syntaxes(&self) -> impl Iterator> { - self.syntaxes.iter().map(|syntax| Syntax { + self.ordered_syntaxes.iter().map(|syntax| Syntax { name: syntax.name.as_ref(), extensions: syntax.file_extensions.as_slice(), }) diff --git a/crates/wastebin_highlight/src/theme.rs b/crates/wastebin_highlight/src/theme.rs index 9a8f8e04..59360b2b 100644 --- a/crates/wastebin_highlight/src/theme.rs +++ b/crates/wastebin_highlight/src/theme.rs @@ -114,17 +114,16 @@ fn combined_css(color_scheme: &str, theme: &highlighting::Theme) -> Vec { let fg = theme.settings.foreground.expect("existing color"); let bg = theme.settings.background.expect("existing color"); - let main_colors = format!( - ":root {{ - color-scheme: {color_scheme}; - --main-bg-color: rgb({}, {}, {}, {}); - --main-fg-color: rgb({}, {}, {}, {}); -}}", - bg.r, bg.g, bg.b, bg.a, fg.r, fg.g, fg.b, fg.a - ); - format!( - "{main_colors} {}", + "{} {}", + format_args!( + ":root {{ + color-scheme: {color_scheme}; + --main-bg-color: rgb({}, {}, {}, {}); + --main-fg-color: rgb({}, {}, {}, {}); + }}", + bg.r, bg.g, bg.b, bg.a, fg.r, fg.g, fg.b, fg.a + ), css_for_theme_with_class_style(theme, ClassStyle::Spaced).expect("generating CSS") ) .into_bytes() diff --git a/crates/wastebin_server/src/handlers/download.rs b/crates/wastebin_server/src/handlers/download.rs index 8c069e44..2b728914 100644 --- a/crates/wastebin_server/src/handlers/download.rs +++ b/crates/wastebin_server/src/handlers/download.rs @@ -40,11 +40,11 @@ pub async fn get( } fn get_download(key: &Key, data: Data) -> impl IntoResponse { - let filename = data.metadata.title.unwrap_or_else(|| format!("{key}")); + let filename = data.metadata.title.unwrap_or_else(|| key.to_string()); let content_type = "text; charset=utf-8"; let content_disposition = - HeaderValue::from_str(&format!(r#"attachment; filename="{filename}""#)) + HeaderValue::try_from(format!(r#"attachment; filename="{filename}""#)) .expect("constructing valid header value"); ( diff --git a/crates/wastebin_server/src/handlers/insert/form.rs b/crates/wastebin_server/src/handlers/insert/form.rs index 1cad21e6..78d2af80 100644 --- a/crates/wastebin_server/src/handlers/insert/form.rs +++ b/crates/wastebin_server/src/handlers/insert/form.rs @@ -67,14 +67,17 @@ pub async fn post( entry.uid = Some(uid); let id = Id::rand(); - let mut url = id.to_url_path(&entry); - if entry.burn_after_reading.unwrap_or(false) { - url = format!("burn/{url}"); - } + let url = { + let url_path = id.to_url_path(&entry); + if entry.burn_after_reading.unwrap_or(false) { + format!("/burn/{url_path}") + } else { + format!("/{url_path}") + } + }; db.insert(id, entry).await?; - let url = format!("/{url}"); let cookie = Cookie::build(("uid", uid.to_string())) .http_only(true)