nmd_core/dossier/document/
chapter.rs

1pub mod paragraph;
2pub mod heading;
3pub mod chapter_tag;
4pub mod chapter_header;
5
6
7use chapter_header::ChapterHeader;
8use getset::{Getters, MutGetters, Setters};
9use paragraph::Paragraph;
10use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
11use serde::Serialize;
12use crate::{codex::Codex, compilation::{compilable::Compilable, compilation_configuration::{compilation_configuration_overlay::CompilationConfigurationOverLay, CompilationConfiguration}, compilation_error::CompilationError, compilation_outcome::CompilationOutcome}, output_format::OutputFormat};
13
14
15#[derive(Debug, Getters, MutGetters, Setters, Serialize)]
16pub struct Chapter {
17
18    #[getset(get = "pub", get_mut = "pub", set = "pub")]
19    header: ChapterHeader,
20    
21    #[getset(get = "pub", get_mut = "pub", set = "pub")]
22    #[serde(skip)]      // TODO
23    paragraphs: Vec<Box<dyn Paragraph>>,
24}
25
26
27impl Chapter {
28
29    pub fn new(header: ChapterHeader, paragraphs: Vec<Box<dyn Paragraph>>) -> Self {
30        Self {
31            header,
32            paragraphs
33        }
34    }    
35}
36
37
38impl Compilable for Chapter {
39    fn standard_compile(&mut self, format: &OutputFormat, codex: &Codex, compilation_configuration: &CompilationConfiguration, compilation_configuration_overlay: CompilationConfigurationOverLay) -> Result<CompilationOutcome, CompilationError> {
40        
41        log::debug!("compile chapter: {:?}", self.header);
42
43        let compiled_heading = self.header.heading_mut().compile(format, codex, compilation_configuration, compilation_configuration_overlay.clone())?;
44        
45        let mut paragraph_outcomes: Vec<CompilationOutcome> = Vec::new();
46
47        if compilation_configuration.parallelization() {
48
49            let paragraph_results: Vec<Result<CompilationOutcome, CompilationError>> = self.paragraphs.par_iter_mut()
50                .map(|paragraph| {
51
52                    paragraph.compile(format, codex, compilation_configuration, compilation_configuration_overlay.clone())
53                
54                }).collect();
55
56            let mut paragraph_errors: Vec<CompilationError> = Vec::new();
57
58            paragraph_results.into_iter().for_each(|result| {
59
60                match result {
61                    Ok(outcome) => paragraph_outcomes.push(outcome),
62                    Err(err) => paragraph_errors.push(err),
63                }
64            });
65
66            if !paragraph_errors.is_empty() {
67                return Err(CompilationError::BucketOfErrors(paragraph_errors))
68            }
69
70        } else {
71
72            for paragraph in self.paragraphs.iter_mut() {
73
74                paragraph_outcomes.push(paragraph.compile(format, codex, compilation_configuration, compilation_configuration_overlay.clone())?);
75            }
76        }
77
78        Ok(CompilationOutcome::from(codex.assembler().assemble_chapter(self.header().tags(), &compiled_heading, &paragraph_outcomes, compilation_configuration_overlay.assembler_configuration())?))  
79    }
80}