use crate::core::*; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, NameAnnotation, Span}; /// A WebAssembly tag directive, part of the exception handling proposal. #[derive(Debug)] pub struct Tag<'a> { /// Where this tag was defined pub span: Span, /// An optional name by which to refer to this tag in name resolution. pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, /// Optional export directives for this tag. pub exports: InlineExport<'a>, /// The type of tag that is defined. pub ty: TagType<'a>, /// What kind of tag this is defined as. pub kind: TagKind<'a>, } /// Listing of various types of tags that can be defined in a wasm module. #[derive(Clone, Debug)] pub enum TagType<'a> { /// An exception tag, where the payload is the type signature of the tag /// (constructor parameters, etc). Exception(TypeUse<'a, FunctionType<'a>>), } /// Different kinds of tags that can be defined in a module. #[derive(Debug)] pub enum TagKind<'a> { /// An tag which is actually defined as an import, such as: /// /// ```text /// (tag (type 0) (import "foo" "bar")) /// ``` Import(InlineImport<'a>), /// A tag defined inline in the module itself Inline(), } impl<'a> Parse<'a> for Tag<'a> { fn parse(parser: Parser<'a>) -> Result { let span = parser.parse::()?.0; let id = parser.parse()?; let name = parser.parse()?; let exports = parser.parse()?; let (ty, kind) = if let Some(import) = parser.parse()? { (parser.parse()?, TagKind::Import(import)) } else { (parser.parse()?, TagKind::Inline()) }; Ok(Tag { span, id, name, exports, ty, kind, }) } } impl<'a> Parse<'a> for TagType<'a> { fn parse(parser: Parser<'a>) -> Result { Ok(TagType::Exception(parser.parse()?)) } }