ephemeris_documents/markdown/
spec.rs1use facet::Facet;
4
5use super::ast::{MarkdownBlock, MarkdownSelector};
6use crate::error::DocumentError;
7use crate::header::GENERATED;
8use crate::line_ending::LineEndingSpec;
9use crate::source::Source;
10use crate::spec::Payload;
11use crate::text::CommentSyntax;
12
13#[derive(Debug, Clone, Facet)]
15#[facet(deny_unknown_fields)]
16pub struct MarkdownSpec {
17 pub ownership: MarkdownOwnership,
19 #[facet(default)]
21 pub line_ending: LineEndingSpec,
22}
23
24#[derive(Debug, Clone, Facet)]
26#[facet(tag = "type", deny_unknown_fields)]
27#[repr(u8)]
28pub enum MarkdownOwnership {
29 #[facet(rename = "whole")]
31 Whole {
32 blocks: Vec<MarkdownBlock>,
34 },
35 #[facet(rename = "selected")]
37 Selected {
38 selectors: Vec<MarkdownSelector>,
40 },
41}
42
43impl MarkdownOwnership {
44 const fn is_partial(&self) -> bool {
46 match self {
47 Self::Whole { blocks: _ } => false,
48 Self::Selected { selectors: _ } => true,
49 }
50 }
51}
52
53impl MarkdownSpec {
54 #[must_use]
56 pub const fn is_partial(&self) -> bool {
57 self.ownership.is_partial()
58 }
59}
60
61impl Payload for MarkdownSpec {
62 fn line_ending(&self) -> LineEndingSpec {
63 self.line_ending
64 }
65
66 fn reconcile(&self, source: &Source<'_>) -> Result<Vec<u8>, DocumentError> {
67 match &self.ownership {
68 MarkdownOwnership::Whole { blocks } => {
69 let header = CommentSyntax::Xml.comment(GENERATED);
70 let body = MarkdownBlock::render_all(blocks)?;
71 Ok(source.write(&format_args!("{header}\n{body}")))
72 }
73 MarkdownOwnership::Selected { selectors } => {
74 MarkdownSelector::reconcile_all(source, selectors)
75 }
76 }
77 }
78
79 fn validate(&self) -> Result<(), DocumentError> {
80 match &self.ownership {
81 MarkdownOwnership::Whole { blocks: _ } => Ok(()),
82 MarkdownOwnership::Selected { selectors } => {
83 Ok(MarkdownSelector::validate_all(selectors)?)
84 }
85 }
86 }
87}