nmd_core/dossier/document/
chapter.rs1pub 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)] 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, ¶graph_outcomes, compilation_configuration_overlay.assembler_configuration())?))
79 }
80}