use crate::component::*;
use crate::kw;
use crate::parser::{Parse, Parser, Result};
use crate::token::{Id, Index, LParen, NameAnnotation, Span};
#[derive(Debug)]
pub struct CoreFunc<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: Option<NameAnnotation<'a>>,
pub kind: CoreFuncKind<'a>,
}
impl<'a> Parse<'a> for CoreFunc<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::core>()?.0;
parser.parse::<kw::func>()?;
let id = parser.parse()?;
let name = parser.parse()?;
let kind = parser.parse()?;
Ok(Self {
span,
id,
name,
kind,
})
}
}
#[derive(Debug)]
#[allow(missing_docs)]
pub enum CoreFuncKind<'a> {
Lower(CanonLower<'a>),
Alias(InlineExportAlias<'a, true>),
ResourceNew(CanonResourceNew<'a>),
ResourceDrop(CanonResourceDrop<'a>),
ResourceRep(CanonResourceRep<'a>),
ThreadSpawn(CanonThreadSpawn<'a>),
ThreadHwConcurrency(CanonThreadHwConcurrency),
TaskBackpressure,
TaskReturn(CanonTaskReturn<'a>),
TaskWait(CanonTaskWait<'a>),
TaskPoll(CanonTaskPoll<'a>),
TaskYield(CanonTaskYield),
SubtaskDrop,
StreamNew(CanonStreamNew<'a>),
StreamRead(CanonStreamRead<'a>),
StreamWrite(CanonStreamWrite<'a>),
StreamCancelRead(CanonStreamCancelRead<'a>),
StreamCancelWrite(CanonStreamCancelWrite<'a>),
StreamCloseReadable(CanonStreamCloseReadable<'a>),
StreamCloseWritable(CanonStreamCloseWritable<'a>),
FutureNew(CanonFutureNew<'a>),
FutureRead(CanonFutureRead<'a>),
FutureWrite(CanonFutureWrite<'a>),
FutureCancelRead(CanonFutureCancelRead<'a>),
FutureCancelWrite(CanonFutureCancelWrite<'a>),
FutureCloseReadable(CanonFutureCloseReadable<'a>),
FutureCloseWritable(CanonFutureCloseWritable<'a>),
ErrorContextNew(CanonErrorContextNew<'a>),
ErrorContextDebugMessage(CanonErrorContextDebugMessage<'a>),
ErrorContextDrop,
}
impl<'a> Parse<'a> for CoreFuncKind<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parens(|parser| {
let mut l = parser.lookahead1();
if l.peek::<kw::canon>()? {
parser.parse::<kw::canon>()?;
} else if l.peek::<kw::alias>()? {
return Ok(Self::Alias(parser.parse()?));
} else {
return Err(l.error());
}
let mut l = parser.lookahead1();
if l.peek::<kw::lower>()? {
Ok(CoreFuncKind::Lower(parser.parse()?))
} else if l.peek::<kw::resource_new>()? {
Ok(CoreFuncKind::ResourceNew(parser.parse()?))
} else if l.peek::<kw::resource_drop>()? {
Ok(CoreFuncKind::ResourceDrop(parser.parse()?))
} else if l.peek::<kw::resource_rep>()? {
Ok(CoreFuncKind::ResourceRep(parser.parse()?))
} else if l.peek::<kw::thread_spawn>()? {
Ok(CoreFuncKind::ThreadSpawn(parser.parse()?))
} else if l.peek::<kw::thread_hw_concurrency>()? {
Ok(CoreFuncKind::ThreadHwConcurrency(parser.parse()?))
} else if l.peek::<kw::task_backpressure>()? {
parser.parse::<kw::task_backpressure>()?;
Ok(CoreFuncKind::TaskBackpressure)
} else if l.peek::<kw::task_return>()? {
Ok(CoreFuncKind::TaskReturn(parser.parse()?))
} else if l.peek::<kw::task_wait>()? {
Ok(CoreFuncKind::TaskWait(parser.parse()?))
} else if l.peek::<kw::task_poll>()? {
Ok(CoreFuncKind::TaskPoll(parser.parse()?))
} else if l.peek::<kw::task_yield>()? {
Ok(CoreFuncKind::TaskYield(parser.parse()?))
} else if l.peek::<kw::subtask_drop>()? {
parser.parse::<kw::subtask_drop>()?;
Ok(CoreFuncKind::SubtaskDrop)
} else if l.peek::<kw::stream_new>()? {
Ok(CoreFuncKind::StreamNew(parser.parse()?))
} else if l.peek::<kw::stream_read>()? {
Ok(CoreFuncKind::StreamRead(parser.parse()?))
} else if l.peek::<kw::stream_write>()? {
Ok(CoreFuncKind::StreamWrite(parser.parse()?))
} else if l.peek::<kw::stream_cancel_read>()? {
Ok(CoreFuncKind::StreamCancelRead(parser.parse()?))
} else if l.peek::<kw::stream_cancel_write>()? {
Ok(CoreFuncKind::StreamCancelWrite(parser.parse()?))
} else if l.peek::<kw::stream_close_readable>()? {
Ok(CoreFuncKind::StreamCloseReadable(parser.parse()?))
} else if l.peek::<kw::stream_close_writable>()? {
Ok(CoreFuncKind::StreamCloseWritable(parser.parse()?))
} else if l.peek::<kw::future_new>()? {
Ok(CoreFuncKind::FutureNew(parser.parse()?))
} else if l.peek::<kw::future_read>()? {
Ok(CoreFuncKind::FutureRead(parser.parse()?))
} else if l.peek::<kw::future_write>()? {
Ok(CoreFuncKind::FutureWrite(parser.parse()?))
} else if l.peek::<kw::future_cancel_read>()? {
Ok(CoreFuncKind::FutureCancelRead(parser.parse()?))
} else if l.peek::<kw::future_cancel_write>()? {
Ok(CoreFuncKind::FutureCancelWrite(parser.parse()?))
} else if l.peek::<kw::future_close_readable>()? {
Ok(CoreFuncKind::FutureCloseReadable(parser.parse()?))
} else if l.peek::<kw::future_close_writable>()? {
Ok(CoreFuncKind::FutureCloseWritable(parser.parse()?))
} else if l.peek::<kw::error_context_new>()? {
Ok(CoreFuncKind::ErrorContextNew(parser.parse()?))
} else if l.peek::<kw::error_context_debug_message>()? {
Ok(CoreFuncKind::ErrorContextDebugMessage(parser.parse()?))
} else if l.peek::<kw::error_context_drop>()? {
parser.parse::<kw::error_context_drop>()?;
Ok(CoreFuncKind::ErrorContextDrop)
} else {
Err(l.error())
}
})
}
}
#[derive(Debug)]
pub struct Func<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: Option<NameAnnotation<'a>>,
pub exports: InlineExport<'a>,
pub kind: FuncKind<'a>,
}
impl<'a> Parse<'a> for Func<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::func>()?.0;
let id = parser.parse()?;
let name = parser.parse()?;
let exports = parser.parse()?;
let kind = parser.parse()?;
Ok(Self {
span,
id,
name,
exports,
kind,
})
}
}
#[derive(Debug)]
pub enum FuncKind<'a> {
Import {
import: InlineImport<'a>,
ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>,
},
Lift {
ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>,
info: CanonLift<'a>,
},
Alias(InlineExportAlias<'a, false>),
}
impl<'a> Parse<'a> for FuncKind<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if let Some(import) = parser.parse()? {
Ok(Self::Import {
import,
ty: parser.parse()?,
})
} else if parser.peek::<LParen>()? && parser.peek2::<kw::alias>()? {
parser.parens(|parser| Ok(Self::Alias(parser.parse()?)))
} else {
Ok(Self::Lift {
ty: parser.parse()?,
info: parser.parens(|parser| {
parser.parse::<kw::canon>()?;
parser.parse()
})?,
})
}
}
}
#[derive(Debug)]
pub struct CanonicalFunc<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: Option<NameAnnotation<'a>>,
pub kind: CanonicalFuncKind<'a>,
}
impl<'a> Parse<'a> for CanonicalFunc<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::canon>()?.0;
if parser.peek::<kw::lift>()? {
let info = parser.parse()?;
let (id, name, ty) = parser.parens(|parser| {
parser.parse::<kw::func>()?;
let id = parser.parse()?;
let name = parser.parse()?;
let ty = parser.parse()?;
Ok((id, name, ty))
})?;
Ok(Self {
span,
id,
name,
kind: CanonicalFuncKind::Lift { info, ty },
})
} else if parser.peek::<kw::lower>()? {
Self::parse_core_func(span, parser, CanonicalFuncKind::Lower)
} else if parser.peek::<kw::resource_new>()? {
Self::parse_core_func(span, parser, CanonicalFuncKind::ResourceNew)
} else if parser.peek::<kw::resource_drop>()? {
Self::parse_core_func(span, parser, CanonicalFuncKind::ResourceDrop)
} else if parser.peek::<kw::resource_rep>()? {
Self::parse_core_func(span, parser, CanonicalFuncKind::ResourceRep)
} else {
Err(parser.error("expected `canon lift` or `canon lower`"))
}
}
}
impl<'a> CanonicalFunc<'a> {
fn parse_core_func<T>(
span: Span,
parser: Parser<'a>,
variant: fn(T) -> CanonicalFuncKind<'a>,
) -> Result<Self>
where
T: Parse<'a>,
{
let info = parser.parse()?;
let (id, name) = parser.parens(|parser| {
parser.parse::<kw::core>()?;
parser.parse::<kw::func>()?;
let id = parser.parse()?;
let name = parser.parse()?;
Ok((id, name))
})?;
Ok(Self {
span,
id,
name,
kind: variant(info),
})
}
}
#[derive(Debug)]
#[allow(missing_docs)]
pub enum CanonicalFuncKind<'a> {
Lift {
ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>,
info: CanonLift<'a>,
},
Lower(CanonLower<'a>),
ResourceNew(CanonResourceNew<'a>),
ResourceDrop(CanonResourceDrop<'a>),
ResourceRep(CanonResourceRep<'a>),
ThreadSpawn(CanonThreadSpawn<'a>),
ThreadHwConcurrency(CanonThreadHwConcurrency),
TaskBackpressure,
TaskReturn(CanonTaskReturn<'a>),
TaskWait(CanonTaskWait<'a>),
TaskPoll(CanonTaskPoll<'a>),
TaskYield(CanonTaskYield),
SubtaskDrop,
StreamNew(CanonStreamNew<'a>),
StreamRead(CanonStreamRead<'a>),
StreamWrite(CanonStreamWrite<'a>),
StreamCancelRead(CanonStreamCancelRead<'a>),
StreamCancelWrite(CanonStreamCancelWrite<'a>),
StreamCloseReadable(CanonStreamCloseReadable<'a>),
StreamCloseWritable(CanonStreamCloseWritable<'a>),
FutureNew(CanonFutureNew<'a>),
FutureRead(CanonFutureRead<'a>),
FutureWrite(CanonFutureWrite<'a>),
FutureCancelRead(CanonFutureCancelRead<'a>),
FutureCancelWrite(CanonFutureCancelWrite<'a>),
FutureCloseReadable(CanonFutureCloseReadable<'a>),
FutureCloseWritable(CanonFutureCloseWritable<'a>),
ErrorContextNew(CanonErrorContextNew<'a>),
ErrorContextDebugMessage(CanonErrorContextDebugMessage<'a>),
ErrorContextDrop,
}
#[derive(Debug)]
pub struct CanonLift<'a> {
pub func: CoreItemRef<'a, kw::func>,
pub opts: Vec<CanonOpt<'a>>,
}
impl<'a> Parse<'a> for CanonLift<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::lift>()?;
Ok(Self {
func: parser.parens(|parser| {
parser.parse::<kw::core>()?;
parser.parse()
})?,
opts: parser.parse()?,
})
}
}
impl Default for CanonLift<'_> {
fn default() -> Self {
let span = Span::from_offset(0);
Self {
func: CoreItemRef {
kind: kw::func(span),
idx: Index::Num(0, span),
export_name: None,
},
opts: Vec::new(),
}
}
}
#[derive(Debug)]
pub struct CanonLower<'a> {
pub func: ItemRef<'a, kw::func>,
pub opts: Vec<CanonOpt<'a>>,
}
impl<'a> Parse<'a> for CanonLower<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::lower>()?;
Ok(Self {
func: parser.parens(|parser| parser.parse())?,
opts: parser.parse()?,
})
}
}
impl Default for CanonLower<'_> {
fn default() -> Self {
let span = Span::from_offset(0);
Self {
func: ItemRef {
kind: kw::func(span),
idx: Index::Num(0, span),
export_names: Vec::new(),
},
opts: Vec::new(),
}
}
}
#[derive(Debug)]
pub struct CanonResourceNew<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonResourceNew<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::resource_new>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonResourceDrop<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonResourceDrop<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::resource_drop>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonResourceRep<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonResourceRep<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::resource_rep>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonThreadSpawn<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonThreadSpawn<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::thread_spawn>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonThreadHwConcurrency;
impl<'a> Parse<'a> for CanonThreadHwConcurrency {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::thread_hw_concurrency>()?;
Ok(Self)
}
}
#[derive(Debug)]
pub struct CanonTaskReturn<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonTaskReturn<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::task_return>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonTaskWait<'a> {
pub async_: bool,
pub memory: CoreItemRef<'a, kw::memory>,
}
impl<'a> Parse<'a> for CanonTaskWait<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::task_wait>()?;
let async_ = parser.parse::<Option<kw::r#async>>()?.is_some();
let memory = parser.parens(|parser| {
let span = parser.parse::<kw::memory>()?.0;
parse_trailing_item_ref(kw::memory(span), parser)
})?;
Ok(Self { async_, memory })
}
}
#[derive(Debug)]
pub struct CanonTaskPoll<'a> {
pub async_: bool,
pub memory: CoreItemRef<'a, kw::memory>,
}
impl<'a> Parse<'a> for CanonTaskPoll<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::task_poll>()?;
let async_ = parser.parse::<Option<kw::r#async>>()?.is_some();
let memory = parser.parens(|parser| {
let span = parser.parse::<kw::memory>()?.0;
parse_trailing_item_ref(kw::memory(span), parser)
})?;
Ok(Self { async_, memory })
}
}
#[derive(Debug)]
pub struct CanonTaskYield {
pub async_: bool,
}
impl<'a> Parse<'a> for CanonTaskYield {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::task_yield>()?;
let async_ = parser.parse::<Option<kw::r#async>>()?.is_some();
Ok(Self { async_ })
}
}
#[derive(Debug)]
pub struct CanonStreamNew<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonStreamNew<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::stream_new>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonStreamRead<'a> {
pub ty: Index<'a>,
pub opts: Vec<CanonOpt<'a>>,
}
impl<'a> Parse<'a> for CanonStreamRead<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::stream_read>()?;
Ok(Self {
ty: parser.parse()?,
opts: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonStreamWrite<'a> {
pub ty: Index<'a>,
pub opts: Vec<CanonOpt<'a>>,
}
impl<'a> Parse<'a> for CanonStreamWrite<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::stream_write>()?;
Ok(Self {
ty: parser.parse()?,
opts: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonStreamCancelRead<'a> {
pub ty: Index<'a>,
pub async_: bool,
}
impl<'a> Parse<'a> for CanonStreamCancelRead<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::stream_cancel_read>()?;
Ok(Self {
ty: parser.parse()?,
async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
})
}
}
#[derive(Debug)]
pub struct CanonStreamCancelWrite<'a> {
pub ty: Index<'a>,
pub async_: bool,
}
impl<'a> Parse<'a> for CanonStreamCancelWrite<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::stream_cancel_write>()?;
Ok(Self {
ty: parser.parse()?,
async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
})
}
}
#[derive(Debug)]
pub struct CanonStreamCloseReadable<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonStreamCloseReadable<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::stream_close_readable>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonStreamCloseWritable<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonStreamCloseWritable<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::stream_close_writable>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonFutureNew<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonFutureNew<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::future_new>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonFutureRead<'a> {
pub ty: Index<'a>,
pub opts: Vec<CanonOpt<'a>>,
}
impl<'a> Parse<'a> for CanonFutureRead<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::future_read>()?;
Ok(Self {
ty: parser.parse()?,
opts: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonFutureWrite<'a> {
pub ty: Index<'a>,
pub opts: Vec<CanonOpt<'a>>,
}
impl<'a> Parse<'a> for CanonFutureWrite<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::future_write>()?;
Ok(Self {
ty: parser.parse()?,
opts: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonFutureCancelRead<'a> {
pub ty: Index<'a>,
pub async_: bool,
}
impl<'a> Parse<'a> for CanonFutureCancelRead<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::future_cancel_read>()?;
Ok(Self {
ty: parser.parse()?,
async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
})
}
}
#[derive(Debug)]
pub struct CanonFutureCancelWrite<'a> {
pub ty: Index<'a>,
pub async_: bool,
}
impl<'a> Parse<'a> for CanonFutureCancelWrite<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::future_cancel_write>()?;
Ok(Self {
ty: parser.parse()?,
async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
})
}
}
#[derive(Debug)]
pub struct CanonFutureCloseReadable<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonFutureCloseReadable<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::future_close_readable>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonFutureCloseWritable<'a> {
pub ty: Index<'a>,
}
impl<'a> Parse<'a> for CanonFutureCloseWritable<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::future_close_writable>()?;
Ok(Self {
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonErrorContextNew<'a> {
pub opts: Vec<CanonOpt<'a>>,
}
impl<'a> Parse<'a> for CanonErrorContextNew<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::error_context_new>()?;
Ok(Self {
opts: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct CanonErrorContextDebugMessage<'a> {
pub opts: Vec<CanonOpt<'a>>,
}
impl<'a> Parse<'a> for CanonErrorContextDebugMessage<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::error_context_debug_message>()?;
Ok(Self {
opts: parser.parse()?,
})
}
}
#[derive(Debug)]
pub enum CanonOpt<'a> {
StringUtf8,
StringUtf16,
StringLatin1Utf16,
Memory(CoreItemRef<'a, kw::memory>),
Realloc(CoreItemRef<'a, kw::func>),
PostReturn(CoreItemRef<'a, kw::func>),
Async,
Callback(CoreItemRef<'a, kw::func>),
}
impl<'a> Parse<'a> for CanonOpt<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut l = parser.lookahead1();
if l.peek::<kw::string_utf8>()? {
parser.parse::<kw::string_utf8>()?;
Ok(Self::StringUtf8)
} else if l.peek::<kw::string_utf16>()? {
parser.parse::<kw::string_utf16>()?;
Ok(Self::StringUtf16)
} else if l.peek::<kw::string_latin1_utf16>()? {
parser.parse::<kw::string_latin1_utf16>()?;
Ok(Self::StringLatin1Utf16)
} else if l.peek::<kw::r#async>()? {
parser.parse::<kw::r#async>()?;
Ok(Self::Async)
} else if l.peek::<LParen>()? {
parser.parens(|parser| {
let mut l = parser.lookahead1();
if l.peek::<kw::memory>()? {
let span = parser.parse::<kw::memory>()?.0;
Ok(CanonOpt::Memory(parse_trailing_item_ref(
kw::memory(span),
parser,
)?))
} else if l.peek::<kw::realloc>()? {
parser.parse::<kw::realloc>()?;
Ok(CanonOpt::Realloc(
parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
))
} else if l.peek::<kw::post_return>()? {
parser.parse::<kw::post_return>()?;
Ok(CanonOpt::PostReturn(
parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
))
} else if l.peek::<kw::callback>()? {
parser.parse::<kw::callback>()?;
Ok(CanonOpt::Callback(
parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
))
} else {
Err(l.error())
}
})
} else {
Err(l.error())
}
}
}
fn parse_trailing_item_ref<T>(kind: T, parser: Parser) -> Result<CoreItemRef<T>> {
Ok(CoreItemRef {
kind,
idx: parser.parse()?,
export_name: parser.parse()?,
})
}
impl<'a> Parse<'a> for Vec<CanonOpt<'a>> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut funcs = Vec::new();
while !parser.is_empty() {
funcs.push(parser.parse()?);
}
Ok(funcs)
}
}