1 | use crate::component::Component; |
2 | use crate::core::{Module, ModuleField, ModuleKind}; |
3 | use crate::kw; |
4 | use crate::parser::{Parse, Parser, Result}; |
5 | use crate::token::Span; |
6 | |
7 | /// A `*.wat` file parser, or a parser for one parenthesized module. |
8 | /// |
9 | /// This is the top-level type which you'll frequently parse when working with |
10 | /// this crate. A `*.wat` file is either one `module` s-expression or a sequence |
11 | /// of s-expressions that are module fields. |
12 | #[derive (Debug)] |
13 | #[allow (missing_docs)] |
14 | pub enum Wat<'a> { |
15 | Module(Module<'a>), |
16 | Component(Component<'a>), |
17 | } |
18 | |
19 | impl Wat<'_> { |
20 | fn validate(&self, parser: Parser<'_>) -> Result<()> { |
21 | match self { |
22 | Wat::Module(m: &Module<'_>) => m.validate(parser), |
23 | Wat::Component(c: &Component<'_>) => c.validate(parser), |
24 | } |
25 | } |
26 | |
27 | /// Encodes this `Wat` to binary form. This calls either [`Module::encode`] |
28 | /// or [`Component::encode`]. |
29 | pub fn encode(&mut self) -> std::result::Result<Vec<u8>, crate::Error> { |
30 | crate::core::EncodeOptions::default().encode_wat(self) |
31 | } |
32 | |
33 | /// Returns the defining span of this file. |
34 | pub fn span(&self) -> Span { |
35 | match self { |
36 | Wat::Module(m: &Module<'_>) => m.span, |
37 | Wat::Component(c: &Component<'_>) => c.span, |
38 | } |
39 | } |
40 | } |
41 | |
42 | impl<'a> Parse<'a> for Wat<'a> { |
43 | fn parse(parser: Parser<'a>) -> Result<Self> { |
44 | if !parser.has_meaningful_tokens() { |
45 | return Err(parser.error("expected at least one module field" )); |
46 | } |
47 | |
48 | parser.with_standard_annotations_registered(|parser| { |
49 | let wat = if parser.peek2::<kw::module>()? { |
50 | Wat::Module(parser.parens(|parser| parser.parse())?) |
51 | } else if parser.peek2::<kw::component>()? { |
52 | Wat::Component(parser.parens(|parser| parser.parse())?) |
53 | } else { |
54 | let fields = ModuleField::parse_remaining(parser)?; |
55 | Wat::Module(Module { |
56 | span: Span { offset: 0 }, |
57 | id: None, |
58 | name: None, |
59 | kind: ModuleKind::Text(fields), |
60 | }) |
61 | }; |
62 | wat.validate(parser)?; |
63 | Ok(wat) |
64 | }) |
65 | } |
66 | } |
67 | |