Skip to main content

ephemeris_documents/annotation/
validate.rs

1//! Checking an annotated tree against the features of a format.
2
3use super::{Annotated, AnnotatedValue};
4use crate::error::{DocumentError, Feature};
5use crate::format::Format;
6use crate::path::Segment;
7
8impl Annotated {
9    /// Check that `format` can express this value and everything below it.
10    ///
11    /// Backends still check what depends on content, such as a string that
12    /// a literal block cannot reproduce.
13    ///
14    /// # Errors
15    /// Returns the unsupported feature error for `format`, at the path of
16    /// the first value that needs a feature the format lacks.
17    pub(crate) fn validate(&self, format: Format) -> Result<(), DocumentError> {
18        if self.comment.is_some() {
19            format
20                .require(Feature::Comment)
21                .map_err(DocumentError::value)?;
22        }
23        match &self.value {
24            AnnotatedValue::Scalar(scalar) => scalar.check(format).map_err(DocumentError::value),
25            AnnotatedValue::Array(items) => {
26                items.iter().enumerate().try_for_each(|(index, item)| {
27                    item.validate(format)
28                        .map_err(|error| error.under(Segment::Index(index)))
29                })
30            }
31            AnnotatedValue::Object(entries) => {
32                if entries.is_dotted() {
33                    format
34                        .require(Feature::DottedTable)
35                        .map_err(DocumentError::value)?;
36                }
37                entries.into_iter().try_for_each(|(key, value)| {
38                    value
39                        .validate(format)
40                        .map_err(|error| error.under(Segment::Key(key.clone())))
41                })
42            }
43        }
44    }
45}