♻️ Simple & Efficient Gemini-to-HTTP Proxy fuwn.net
proxy gemini-protocol protocol gemini http rust
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(html,url): Resolve clippy pedantic lints and reduce allocations

Fuwn 9b0e10dd 54e36fc4

+30 -34
+16 -15
src/html.rs
··· 76 76 77 77 let align_adjacent_links = |html: &str| { 78 78 if previous_link_count > 0 { 79 - html 80 - .chars() 81 - .rev() 82 - .collect::<String>() 83 - .replacen(&GEMINI_FRAGMENT.chars().rev().collect::<String>(), "", 1) 84 - .chars() 85 - .rev() 86 - .collect::<String>() 79 + html.rfind(GEMINI_FRAGMENT).map_or_else( 80 + || html.to_string(), 81 + |position| { 82 + let mut result = 83 + String::with_capacity(html.len() - GEMINI_FRAGMENT.len()); 84 + 85 + result.push_str(&html[..position]); 86 + result.push_str(&html[position + GEMINI_FRAGMENT.len()..]); 87 + 88 + result 89 + }, 90 + ) 87 91 } else { 88 92 html.to_string() 89 93 } ··· 121 125 let _ = write!(&mut html, "<p>{}</p>", safe(text)); 122 126 } 123 127 Node::Link { to, text } => { 124 - let mut href = to.to_string(); 128 + let mut href = to.clone(); 125 129 let mut surface = false; 126 130 127 131 if href.starts_with("./") || href.starts_with("../") { ··· 133 137 if href.contains("://") && !href.starts_with("gemini://") { 134 138 surface = true; 135 139 } else if !href.contains("://") && href.contains(':') { 136 - href = href.to_string(); 140 + // href contains a scheme-like pattern (e.g., mailto:), keep as-is 137 141 } else if !href.starts_with("gemini://") && !href.starts_with('/') { 138 142 href = format!( 139 143 "{}/{}", ··· 255 259 } 256 260 257 261 if title.is_empty() && *level == 1 { 258 - title = safe(text).to_string(); 262 + title = safe(text); 259 263 } 260 264 261 265 let _ = write!( ··· 285 289 let _ = write!(&mut html, "<blockquote>{}</blockquote>", safe(text)); 286 290 } 287 291 Node::PreformattedText { text, .. } => { 288 - let mut new_text = text.to_string(); 289 - 290 - new_text.pop(); 291 - 292 + let new_text = text.strip_suffix('\n').unwrap_or(text); 292 293 let _ = write!(&mut html, "<pre>{new_text}</pre>"); 293 294 } 294 295 Node::Whitespace => {}
+14 -19
src/url.rs
··· 63 63 return path == pattern; 64 64 } 65 65 66 - let parts: Vec<&str> = pattern.split('*').collect(); 66 + let mut parts = pattern.split('*').peekable(); 67 67 let mut position = if pattern.starts_with('*') { 68 68 0 69 69 } else { 70 - let first = parts.first().unwrap(); 70 + let first = parts.next().unwrap_or(""); 71 71 72 72 if !path.starts_with(first) { 73 73 return false; ··· 75 75 76 76 first.len() 77 77 }; 78 - let before_last = parts.len().saturating_sub(1); 79 78 80 - for part in &parts[1..before_last] { 81 - if part.is_empty() { 82 - continue; 83 - } 79 + while let Some(part) = parts.next() { 80 + let is_last = parts.peek().is_none(); 84 81 85 - if let Some(found) = path[position..].find(part) { 86 - position += found + part.len(); 87 - } else { 88 - return false; 89 - } 90 - } 91 - 92 - if !pattern.ends_with('*') { 93 - let last = parts.last().unwrap(); 94 - 95 - if !path[position..].ends_with(last) { 96 - return false; 82 + if is_last { 83 + if !pattern.ends_with('*') && !path[position..].ends_with(part) { 84 + return false; 85 + } 86 + } else if !part.is_empty() { 87 + if let Some(found) = path[position..].find(part) { 88 + position += found + part.len(); 89 + } else { 90 + return false; 91 + } 97 92 } 98 93 } 99 94