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
use std::fmt;

use wast::parser::{Parse, Parser, Result};

use crate::{Expr, Module, ToWat, ToWatParams};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Document {
    module: Module,
}

impl Document {
    pub fn new(module: Module) -> Self {
        Self { module }
    }
}

impl fmt::Display for Document {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{}",
            Expr::SExpr(Box::new(self.module.clone())).to_wat(&ToWatParams {
                indent_size:  2,
                indent_level: 0,
            })
        )
    }
}

impl Parse<'_> for Document {
    fn parse(parser: Parser<'_>) -> Result<Self> {
        let module = parser.parens(|p| p.parse::<Module>())?;

        Ok(Self { module })
    }
}

#[cfg(test)]
mod tests {
    use crate::*;

    #[test]
    fn empty_module() {
        assert_eq!(
            wast::parser::parse::<Document>(
                &wast::parser::ParseBuffer::new("(module)").unwrap()
            )
            .unwrap(),
            Document {
                module: Module::with_sections(Vec::new()),
            },
        )
    }

    #[test]
    fn output_empty_module() {
        assert_eq!(
            Document {
                module: Module::with_sections(Vec::new()),
            }
            .to_string(),
            "(module)",
        );
    }
}