1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use std::{
    path::{Path, PathBuf},
    error::Error,
};
use aces::{ContextHandle, Content, ContentFormat, CompilableMut};
use crate::CesFile;

#[derive(Clone, Default, Debug)]
pub struct AscesisFormat {
    path: Option<PathBuf>,
}

impl AscesisFormat {
    pub fn new() -> Self {
        Default::default()
    }

    pub fn from_path<P: AsRef<Path>>(path: P) -> Self {
        let path = path.as_ref().to_path_buf();

        AscesisFormat { path: Some(path) }
    }
}

impl ContentFormat for AscesisFormat {
    fn expected_extensions(&self) -> &[&str] {
        &["ces"]
    }

    fn script_is_acceptable(&self, script: &str) -> bool {
        let mut words = script.split_whitespace();

        if let Some(word) = words.next() {
            match word {
                "ces" => true,
                _ => {
                    if word.contains('{') {
                        word.trim_start_matches(|c: char| c.is_ascii_alphabetic()).starts_with('{')
                    } else if word.trim_start_matches(|c: char| c.is_ascii_alphabetic()).is_empty()
                    {
                        if let Some(word) = words.next() {
                            word.starts_with('{')
                        } else {
                            // Script is a single token, maybe a keyword, but not a block.
                            false
                        }
                    } else {
                        // Script is a single word, which is not a block.
                        false
                    }
                }
            }
        } else {
            // Script is empty.
            false
        }
    }

    fn script_to_content(
        &self,
        ctx: &ContextHandle,
        script: &str,
    ) -> Result<Box<dyn Content>, Box<dyn Error>> {
        let mut ces_file = CesFile::from_script(script)?;

        ces_file.set_root_name("Main")?;
        if let Some(title) = ces_file.get_vis_name("title") {
            info!("Using '{}' as the root structure: \"{}\"", ces_file.get_name().unwrap(), title);
        } else {
            info!("Using '{}' as the root structure", ces_file.get_name().unwrap());
        }

        ces_file.compile_mut(ctx)?;
        debug!("{:?}", ces_file);

        Ok(ces_file.into())
    }
}