yaml_schema/
engine.rs

1use saphyr::LoadableYamlNode;
2use std::cell::RefCell;
3use std::rc::Rc;
4
5use crate::Error;
6use crate::Result;
7use crate::RootSchema;
8use crate::Schema;
9use crate::validation::Context;
10
11#[derive(Debug)]
12pub struct Engine<'a> {
13    pub root_schema: &'a RootSchema,
14    pub context: Rc<RefCell<Context<'a>>>,
15}
16
17impl<'a> Engine<'a> {
18    pub fn new(root_schema: &'a RootSchema, context: Context<'a>) -> Self {
19        Engine {
20            root_schema,
21            context: Rc::new(RefCell::new(context)),
22        }
23    }
24
25    pub fn evaluate<'b: 'a>(
26        root_schema: &'b RootSchema,
27        value: &str,
28        fail_fast: bool,
29    ) -> Result<Context<'b>> {
30        let context = Context::with_root_schema(root_schema, fail_fast);
31        let engine = Engine::new(root_schema, context);
32        let docs = saphyr::MarkedYaml::load_from_str(value).map_err(Error::YamlParsingError)?;
33        if docs.is_empty() {
34            if let Some(sub_schema) = &engine.root_schema.schema.as_ref().schema {
35                match sub_schema {
36                    Schema::Empty => (),
37                    Schema::BooleanLiteral(false) => {
38                        engine
39                            .context
40                            .borrow_mut()
41                            .add_doc_error("Empty YAML document is not allowed");
42                    }
43                    Schema::BooleanLiteral(true) => (),
44                    _ => engine
45                        .context
46                        .borrow_mut()
47                        .add_doc_error("Empty YAML document is not allowed"),
48                }
49            }
50        } else {
51            let yaml = docs.first().unwrap();
52            engine
53                .root_schema
54                .validate(&engine.context.borrow(), yaml)?;
55        }
56        Ok(engine.context.take())
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63    use crate::YamlSchema;
64
65    #[test]
66    fn test_engine_empty_schema() {
67        let root_schema = RootSchema::new(YamlSchema::empty());
68        let context = Engine::evaluate(&root_schema, "", false).unwrap();
69        assert!(!context.has_errors());
70    }
71
72    #[test]
73    fn test_engine_boolean_literal_true() {
74        let root_schema = RootSchema::new(YamlSchema::boolean_literal(true));
75        let context = Engine::evaluate(&root_schema, "", false).unwrap();
76        assert!(!context.has_errors());
77    }
78
79    #[test]
80    fn test_engine_boolean_literal_false() {
81        let root_schema = RootSchema::new(YamlSchema::boolean_literal(false));
82        let context = Engine::evaluate(&root_schema, "", false).unwrap();
83        assert!(context.has_errors());
84    }
85}