use std::{collections::HashSet, io::Write, path::Path}; use crate::{ logger::Logger, normalizer::{NormalizeError, NormalizedPath, Normalizer}, renderer::Renderer, util::path_display::display_path, }; use super::MarkdownGenerator; pub(super) struct MarkdownGeneration<'a, W: Write, LW: Write> { logger: &'a Logger, normalizer: Normalizer, paths: &'a [&'a Path], project_title: String, renderer: Renderer<'a, W, LW>, seen_paths: HashSet, } impl<'a, W: Write, LW: Write> MarkdownGeneration<'a, W, LW> { pub fn new( generator: MarkdownGenerator<'a>, output: W, logger: &'a Logger, ) -> Result { Ok(Self { logger, normalizer: Normalizer::new(generator.root, generator.origin_base)?, paths: generator.paths, project_title: generator.get_or_derive_project_title().to_string(), renderer: Renderer::new(output, logger, generator.render_options), seen_paths: HashSet::new(), }) } pub fn run(mut self) -> Result<(), Box> { self.renderer.render_header(&self.project_title)?; for path in self.paths { self.render_path(path)?; } Ok(()) } fn render_path(&mut self, path: &Path) -> Result<(), Box> { let normalized_path = self.normalizer.normalize(path)?; if self.seen_paths.insert(normalized_path.clone()) { self.renderer.render_path(&normalized_path)?; } else { self.logger.warn(format!( "skipping duplicate file: {}", display_path(&normalized_path.root_relative) )); } Ok(()) } }