The (very WIP) home of the next versions of my web presences

lx: fix all Clippy lints!

+96 -96
+10
.zed/settings.json
··· 9 9 "languages": { 10 10 "TOML": { "tab_size": 4 }, 11 11 "YAML": { "tab_size": 2 }, 12 + "Shell Script": { "tab_size": 2 }, 12 13 "Rust": { 13 14 "soft_wrap": "bounded", 14 15 "preferred_line_length": 90 ··· 18 19 "soft_wrap": "bounded", 19 20 "preferred_line_length": 80, 20 21 "tab_size": 4 22 + } 23 + }, 24 + "lsp": { 25 + "rust-analyzer": { 26 + "initialization_options": { 27 + "check": { 28 + "command": "clippy" // rust-analyzer.check.command (default: "check") 29 + } 30 + } 21 31 } 22 32 } 23 33 }
+4 -4
lx/crates/markdown/src/first_pass.rs
··· 101 101 /// received the 'end the metadata block' event. 102 102 #[derive(Debug)] 103 103 pub(super) struct ExtractedMetadata<'e>(CowStr<'e>); 104 - impl<'e> ParseState for ExtractedMetadata<'e> {} 104 + impl ParseState for ExtractedMetadata<'_> {} 105 105 106 106 impl<'e> State<ExtractedMetadata<'e>> { 107 107 pub(super) fn start_content(self) -> State<Content<'e>> { ··· 132 132 } 133 133 } 134 134 135 - impl<'e> ParseState for Content<'e> {} 135 + impl ParseState for Content<'_> {} 136 136 137 137 impl<'e> State<Content<'e>> { 138 138 /// "Handling" events consists, at this stage, of just distinguishing between ··· 209 209 pub(crate) trait Sealed {} 210 210 impl Sealed for super::Initial {} 211 211 impl Sealed for super::ExtractingMetadata {} 212 - impl<'e> Sealed for super::ExtractedMetadata<'e> {} 213 - impl<'e> Sealed for super::Content<'e> {} 212 + impl Sealed for super::ExtractedMetadata<'_> {} 213 + impl Sealed for super::Content<'_> {} 214 214 }
+2 -2
lx/crates/markdown/src/lib.rs
··· 90 90 } 91 91 92 92 impl Markdown { 93 - pub fn new() -> Markdown { 93 + pub fn new(syntax_set: Option<SyntaxSet>) -> Markdown { 94 94 Markdown { 95 - syntax_set: load_syntaxes(), // TODO: pull from location? 95 + syntax_set: syntax_set.unwrap_or_else(load_syntaxes), // TODO: pull from location? 96 96 } 97 97 } 98 98
+2 -2
lx/crates/markdown/src/second_pass.rs
··· 69 69 Ok(state.into_iter()) 70 70 } 71 71 72 - impl<'e, 's> State<'e, 's> { 72 + impl<'e> State<'e, '_> { 73 73 /// Returns `Some(String)` when it could successfully emit an event but there was 74 74 /// something unexpected about it, e.g. a footnote with a missing definition. 75 75 fn handle( ··· 371 371 KnownSyntax(ClassedHTMLGenerator<'s>), 372 372 } 373 373 374 - impl<'a> std::fmt::Debug for Highlighting<'a> { 374 + impl std::fmt::Debug for Highlighting<'_> { 375 375 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 376 376 match self { 377 377 Self::RequiresFirstLineParse => write!(f, "RequiresFirstLineParse"),
+36 -47
lx/src/build.rs
··· 1 - use std::path::{Path, PathBuf}; 1 + use std::{ 2 + error, fmt, fs, io, 3 + path::{Path, PathBuf}, 4 + }; 2 5 3 6 use lazy_static::lazy_static; 4 7 use log::{debug, error, trace}; ··· 22 25 23 26 pub fn build_in(directory: Canonicalized) -> Result<(), Error> { 24 27 let config = config_for(&directory)?; 25 - let md = Markdown::new(); 28 + let md = Markdown::new(None); 26 29 27 30 // TODO: further split this apart. 28 31 build(directory, &config, &md) ··· 45 48 trace!("Building in {directory}"); 46 49 trace!("Removing output directory {}", config.output.display()); 47 50 48 - if let Err(io_err) = std::fs::remove_dir_all(&config.output) { 49 - if io_err.kind() != std::io::ErrorKind::NotFound { 51 + if let Err(io_err) = fs::remove_dir_all(&config.output) { 52 + if io_err.kind() != io::ErrorKind::NotFound { 50 53 return Err(Error::RemoveDir { 51 54 source: io_err, 52 55 path: config.output.clone(), ··· 61 64 let shared_dir = input_dir.parent().map(|parent| parent.join("_shared")); 62 65 let mut shared_files = shared_dir 63 66 .as_ref() 64 - .map(|dir| SharedFiles::in_dir(&dir)) 67 + .map(|dir| SharedFiles::in_dir(dir)) 65 68 .transpose()?; 66 69 67 70 trace!( ··· 100 103 })?; 101 104 102 105 // TODO: actual error handling here, please. 103 - std::fs::create_dir_all(&config.output).expect("Can create output dir"); 106 + fs::create_dir_all(&config.output).expect("Can create output dir"); 104 107 105 108 let sources = load_sources(&site_files.content)?; 106 109 ··· 116 119 // the map call depending on what kind of file it is. 117 120 .filter(|source| source.path.extension().is_some_and(|ext| ext == "md")) 118 121 .map(|source| { 119 - page::prepare(&md, &source, &cascade) 122 + page::prepare(md, source, &cascade) 120 123 .map(|prepared| (prepared, source)) 121 124 .map_err(|e| (source.path.clone(), e)) 122 125 }) ··· 176 179 })?; 177 180 let path = config.output.join(relative_path); 178 181 let output_dir = path.parent().expect("must have a real parent"); 179 - std::fs::create_dir_all(output_dir).map_err(|source| { 182 + fs::create_dir_all(output_dir).map_err(|source| { 180 183 Error::CreateOutputDirectory { 181 184 path: output_dir.to_owned(), 182 185 source, 183 186 } 184 187 })?; 185 - std::fs::copy(&static_file, &path).map_err(|source| Error::CopyFile { 188 + fs::copy(static_file, &path).map_err(|source| Error::CopyFile { 186 189 from: static_file.clone(), 187 190 to: path, 188 191 source, ··· 200 203 })?; 201 204 let path = config.output.join(relative_path); 202 205 let output_dir = path.parent().expect("must have a real parent"); 203 - std::fs::create_dir_all(output_dir).map_err(|source| { 204 - Error::CreateOutputDirectory { 205 - path: output_dir.to_owned(), 206 - source, 207 - } 206 + fs::create_dir_all(output_dir).map_err(|source| Error::CreateOutputDirectory { 207 + path: output_dir.to_owned(), 208 + source, 208 209 })?; 209 - std::fs::copy(&static_file, &path).map_err(|source| Error::CopyFile { 210 + fs::copy(static_file, &path).map_err(|source| Error::CopyFile { 210 211 from: static_file.clone(), 211 212 to: path, 212 213 source, ··· 224 225 .parent() 225 226 .unwrap_or_else(|| panic!("{} should have a containing dir!", path.display())); 226 227 227 - std::fs::create_dir_all(containing_dir).map_err(|e| { 228 - Error::CreateOutputDirectory { 229 - path: containing_dir.to_owned(), 230 - source: e, 231 - } 228 + fs::create_dir_all(containing_dir).map_err(|e| Error::CreateOutputDirectory { 229 + path: containing_dir.to_owned(), 230 + source: e, 232 231 })?; 233 232 234 233 let mut buf = Vec::new(); 235 234 templates::render(&jinja_env, &page, config, &mut buf)?; 236 235 237 - std::fs::write(&path, buf).map_err(|source| Error::WriteFile { path, source })?; 236 + fs::write(&path, buf).map_err(|source| Error::WriteFile { path, source })?; 238 237 } 239 238 240 239 for sass_file in site_files ··· 253 252 })?; 254 253 255 254 let path = config.output.join(relative_path).with_extension("css"); 256 - std::fs::write(&path, converted) 257 - .map_err(|source| Error::WriteFile { path, source })?; 255 + fs::write(&path, converted).map_err(|source| Error::WriteFile { path, source })?; 258 256 } 259 257 260 258 Ok(()) ··· 269 267 let mut errors = Vec::new(); 270 268 for path in source_files { 271 269 let path = path.as_ref(); 272 - match std::fs::read_to_string(path) { 270 + match fs::read_to_string(path) { 273 271 Ok(contents) => sources.push(Source { 274 272 path: path.to_owned(), 275 273 contents, ··· 321 319 Page(PageError), 322 320 323 321 #[error("could not create output directory '{path}'")] 324 - CreateOutputDirectory { 325 - path: PathBuf, 326 - source: std::io::Error, 327 - }, 322 + CreateOutputDirectory { path: PathBuf, source: io::Error }, 328 323 329 324 #[error("could not copy from {from} to {to}")] 330 325 CopyFile { 331 326 from: PathBuf, 332 327 to: PathBuf, 333 - source: std::io::Error, 328 + source: io::Error, 334 329 }, 335 330 336 331 #[error("could not write to {path}")] 337 - WriteFile { 338 - path: PathBuf, 339 - source: std::io::Error, 340 - }, 332 + WriteFile { path: PathBuf, source: io::Error }, 341 333 342 334 #[error("bad glob pattern: '{pattern}'")] 343 335 GlobPattern { ··· 361 353 TemplatePath { path: PathBuf }, 362 354 363 355 #[error("could not delete directory '{path}'")] 364 - RemoveDir { 365 - path: PathBuf, 366 - source: std::io::Error, 367 - }, 356 + RemoveDir { path: PathBuf, source: io::Error }, 368 357 } 369 358 370 359 impl Error { 371 360 fn rewrite( 372 361 source: minijinja::Error, 373 362 text: &str, 374 - ) -> Box<dyn std::error::Error + Send + Sync> { 363 + ) -> Box<dyn error::Error + Send + Sync> { 375 364 Box::new(Error::Rewrite { 376 365 source, 377 366 text: text.to_owned(), ··· 405 394 kind: PageErrorKind, 406 395 } 407 396 408 - impl std::fmt::Display for PageError { 409 - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 397 + impl fmt::Display for PageError { 398 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 410 399 let count = self.errors.len(); 411 400 match self.kind { 412 401 PageErrorKind::Prepare => { ··· 427 416 #[derive(Error, Debug)] 428 417 pub struct RewriteErrors(Vec<(PathBuf, minijinja::Error)>); 429 418 430 - impl std::fmt::Display for RewriteErrors { 431 - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 419 + impl fmt::Display for RewriteErrors { 420 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 432 421 let errors = &self.0; 433 422 writeln!(f, "could not rewrite {} pages", errors.len())?; 434 423 for (path, error) in errors { ··· 443 432 #[derive(Error, Debug)] 444 433 #[error("Could not load file {path}")] 445 434 pub struct ContentError { 446 - source: std::io::Error, 435 + source: io::Error, 447 436 path: PathBuf, 448 437 } 449 438 ··· 487 476 } 488 477 } 489 478 490 - impl std::fmt::Display for SiteFiles { 491 - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 479 + impl fmt::Display for SiteFiles { 480 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 492 481 let sep = String::from("\n "); 493 482 let empty = String::from(" (none)"); 494 483 ··· 538 527 } 539 528 } 540 529 541 - impl std::fmt::Display for SharedFiles { 542 - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 530 + impl fmt::Display for SharedFiles { 531 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 543 532 let sep = String::from("\n "); 544 533 let empty = String::from(" (none)"); 545 534
+6 -6
lx/src/data/item/mod.rs
··· 82 82 let title = work 83 83 .as_ref() 84 84 .map(|work| work.title.clone()) 85 - .or_else(|| item.title) 85 + .or(item.title) 86 86 .ok_or_else(|| Error::MissingRequiredField { 87 87 name: "title".to_string(), 88 88 })?; ··· 525 525 } 526 526 } 527 527 528 - const DISCUSSES: &'static str = "<b>Heads up:</b> this post directly discusses"; 528 + const DISCUSSES: &str = "<b>Heads up:</b> this post directly discusses"; 529 529 530 530 #[cfg(test)] 531 531 mod tests { ··· 578 578 #[test] 579 579 fn nice_list_formatting() { 580 580 assert_eq!( 581 - nice_list(&vec!["a", "b", "c"]), 581 + nice_list(&["a", "b", "c"]), 582 582 Some(String::from("a, b, and c")) 583 583 ); 584 - assert_eq!(nice_list(&vec!["a", "b"]), Some(String::from("a and b"))); 585 - assert_eq!(nice_list(&vec!["a"]), Some(String::from("a"))); 586 - assert_eq!(nice_list(&vec![]), None); 584 + assert_eq!(nice_list(&["a", "b"]), Some(String::from("a and b"))); 585 + assert_eq!(nice_list(&["a"]), Some(String::from("a"))); 586 + assert_eq!(nice_list(&[]), None); 587 587 } 588 588 }
+24 -24
lx/src/md.rs
··· 17 17 .read_to_string(&mut src) 18 18 .map_err(|source| Error::ReadBuffer { source })?; 19 19 20 - let (meta, rendered) = lx_md::Markdown::new() 20 + let (meta, rendered) = lx_md::Markdown::new(None) 21 21 .render(&src, |s| Ok(s.to_string())) 22 22 .map_err(Error::from)?; 23 23 ··· 72 72 } 73 73 } 74 74 75 - write(&rendered.html(), &mut output)?; 75 + write(rendered.html(), &mut output)?; 76 76 77 77 if include.wrapping_html { 78 78 write("</body></html>", &mut output)?; ··· 89 89 90 90 fn yaml_to_html( 91 91 source: &serde_yaml::Value, 92 - mut output: &mut Box<dyn Write>, 92 + output: &mut Box<dyn Write>, 93 93 ) -> Result<(), Error> { 94 94 match source { 95 - Value::Null => write("(null)", &mut output), 96 - Value::Bool(bool) => write(&bool.to_string(), &mut output), 97 - Value::Number(number) => write(&number.to_string(), &mut output), 98 - Value::String(string) => write(&string, &mut output), 95 + Value::Null => write("(null)", output), 96 + Value::Bool(bool) => write(&bool.to_string(), output), 97 + Value::Number(number) => write(&number.to_string(), output), 98 + Value::String(string) => write(string, output), 99 99 Value::Sequence(values) => { 100 - write("<ul>", &mut output)?; 100 + write("<ul>", output)?; 101 101 for value in values { 102 - yaml_to_html(value, &mut output)?; 102 + yaml_to_html(value, output)?; 103 103 } 104 - write("</ul>", &mut output)?; 104 + write("</ul>", output)?; 105 105 Ok(()) 106 106 } 107 107 Value::Mapping(mapping) => { 108 - write("<table>", &mut output)?; 108 + write("<table>", output)?; 109 109 let (keys, values) = mapping.into_iter().collect::<(Vec<_>, Vec<_>)>(); 110 - if keys.len() > 0 { 111 - write("<thead><tr>", &mut output)?; 110 + if !keys.is_empty() { 111 + write("<thead><tr>", output)?; 112 112 for key in keys { 113 - write("<th>", &mut output)?; 114 - yaml_to_html(key, &mut output)?; 115 - write("</th>", &mut output)?; 113 + write("<th>", output)?; 114 + yaml_to_html(key, output)?; 115 + write("</th>", output)?; 116 116 } 117 - write("</tr></thead>", &mut output)?; 117 + write("</tr></thead>", output)?; 118 118 119 - write("<tbody><tr>", &mut output)?; 119 + write("<tbody><tr>", output)?; 120 120 for value in values { 121 - write("<td>", &mut output)?; 122 - yaml_to_html(value, &mut output)?; 123 - write("</td>", &mut output)?; 121 + write("<td>", output)?; 122 + yaml_to_html(value, output)?; 123 + write("</td>", output)?; 124 124 } 125 - write("</tr></tbody>", &mut output)?; 125 + write("</tr></tbody>", output)?; 126 126 } 127 127 128 - write("</table>", &mut output)?; 128 + write("</table>", output)?; 129 129 Ok(()) 130 130 } 131 - Value::Tagged(tagged_value) => write(&format!("{tagged_value:?}"), &mut output), 131 + Value::Tagged(tagged_value) => write(&format!("{tagged_value:?}"), output), 132 132 } 133 133 } 134 134
+8 -7
lx/src/page.rs
··· 1 1 use std::{ 2 2 collections::HashMap, 3 + fmt, 3 4 hash::Hash, 4 5 os::unix::prelude::OsStrExt, 5 6 path::{Path, PathBuf}, ··· 35 36 source, 36 37 cascade, 37 38 String::from("base.jinja"), // TODO: not this 38 - &md, 39 + md, 39 40 ) 40 41 .map_err(Error::from) 41 42 })?; ··· 50 51 to_render: ToRender<'e>, 51 52 } 52 53 53 - impl<'e> Prepared<'e> { 54 + impl Prepared<'_> { 54 55 pub fn render( 55 56 self, 56 57 md: &Markdown, ··· 84 85 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Deserialize, Serialize)] 85 86 pub struct Id(Uuid); 86 87 87 - impl Id { 88 - fn to_string(&self) -> String { 89 - self.0.to_string() 88 + impl fmt::Display for Id { 89 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 90 + write!(f, "{}", self.0) 90 91 } 91 92 } 92 93 ··· 211 212 212 213 // TODO: This will need to take `From` a different type, one that wraps `Page` 213 214 // and probably also `Config` (e.g. to build the full URL). 214 - impl<'p, 'c, 'e> From<PageAndConfig<'p, 'c, 'e>> for json_feed::FeedItem { 215 + impl From<PageAndConfig<'_, '_, '_>> for json_feed::FeedItem { 215 216 fn from(PageAndConfig(page, config): PageAndConfig) -> Self { 216 217 json_feed::FeedItem { 217 218 id: page.id.to_string(), ··· 239 240 fn updated(&self) -> DateTime<FixedOffset>; 240 241 } 241 242 242 - impl<'e> Updated for [Page<'e>] { 243 + impl Updated for [Page<'_>] { 243 244 fn updated(&self) -> chrono::DateTime<chrono::FixedOffset> { 244 245 self 245 246 .iter()
+1 -1
lx/src/server.rs
··· 51 51 // This does not presently change for any reason. In principle it *could*, e.g. if I 52 52 // wanted to reload it when config changed to support reloading syntaxes. For now, 53 53 // though, this is sufficient. 54 - let md = Markdown::new(); 54 + let md = Markdown::new(None); 55 55 56 56 // 1. Run an initial build. 57 57 // 2. Create a watcher on the *input* directory, *not* the output directory.
+1 -1
lx/src/templates/functions.rs
··· 80 80 fn fancy_debug(name: Option<&str>, args: Rest<Value>) -> String { 81 81 let title = name.map(|n| format!("<p>{n}:</p>")).unwrap_or_default(); 82 82 let args = if args.is_empty() { 83 - format!("{{no args!}}") 83 + "{no args!}".to_string() 84 84 } else if args.len() == 1 { 85 85 format!("{:#?}", args.0[0]) 86 86 } else {
+2 -2
lx/src/templates/mod.rs
··· 57 57 for path in templates { 58 58 let path = path.as_ref(); 59 59 let name = trim_root(path)?.to_string_lossy().to_string(); 60 - let content = std::fs::read_to_string(&path)?; 60 + let content = std::fs::read_to_string(path)?; 61 61 trace!("Adding template at {name}"); 62 62 env.add_template_owned(name, content).map_err(|source| { 63 63 Error::CouldNotAddTemplate { ··· 109 109 data: &page.data, 110 110 config: site, 111 111 path: &page.path, 112 - source: &page.source, 112 + source: page.source, 113 113 }, 114 114 into, 115 115 )