use crate::component::*;
use crate::core;
use crate::kw;
use crate::parser::{Parse, Parser, Result};
use crate::token::{Id, LParen, NameAnnotation, Span};
#[derive(Debug)]
pub struct CoreInstance<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: Option<NameAnnotation<'a>>,
pub kind: CoreInstanceKind<'a>,
}
impl<'a> Parse<'a> for CoreInstance<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::core>()?.0;
parser.parse::<kw::instance>()?;
let id = parser.parse()?;
let name = parser.parse()?;
let kind = parser.parse()?;
Ok(Self {
span,
id,
name,
kind,
})
}
}
#[derive(Debug)]
pub enum CoreInstanceKind<'a> {
Instantiate {
module: ItemRef<'a, kw::module>,
args: Vec<CoreInstantiationArg<'a>>,
},
BundleOfExports(Vec<CoreInstanceExport<'a>>),
}
impl<'a> Parse<'a> for CoreInstanceKind<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? {
parser.parens(|parser| {
parser.parse::<kw::instantiate>()?;
Ok(Self::Instantiate {
module: parser.parse::<IndexOrRef<'_, _>>()?.0,
args: parser.parse()?,
})
})
} else {
Ok(Self::BundleOfExports(parser.parse()?))
}
}
}
impl Default for kw::module {
fn default() -> kw::module {
kw::module(Span::from_offset(0))
}
}
#[derive(Debug)]
pub struct CoreInstantiationArg<'a> {
pub name: &'a str,
pub kind: CoreInstantiationArgKind<'a>,
}
impl<'a> Parse<'a> for CoreInstantiationArg<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::with>()?;
Ok(Self {
name: parser.parse()?,
kind: parser.parse()?,
})
}
}
impl<'a> Parse<'a> for Vec<CoreInstantiationArg<'a>> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut args = Vec::new();
while !parser.is_empty() {
args.push(parser.parens(|parser| parser.parse())?);
}
Ok(args)
}
}
#[derive(Debug)]
pub enum CoreInstantiationArgKind<'a> {
Instance(CoreItemRef<'a, kw::instance>),
BundleOfExports(Span, Vec<CoreInstanceExport<'a>>),
}
impl<'a> Parse<'a> for CoreInstantiationArgKind<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parens(|parser| {
if let Some(r) = parser.parse()? {
Ok(Self::Instance(r))
} else {
let span = parser.parse::<kw::instance>()?.0;
Ok(Self::BundleOfExports(span, parser.parse()?))
}
})
}
}
#[derive(Debug)]
pub struct CoreInstanceExport<'a> {
pub span: Span,
pub name: &'a str,
pub item: CoreItemRef<'a, core::ExportKind>,
}
impl<'a> Parse<'a> for CoreInstanceExport<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
Ok(Self {
span: parser.parse::<kw::export>()?.0,
name: parser.parse()?,
item: parser.parens(|parser| parser.parse())?,
})
}
}
impl<'a> Parse<'a> for Vec<CoreInstanceExport<'a>> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut exports = Vec::new();
while !parser.is_empty() {
exports.push(parser.parens(|parser| parser.parse())?);
}
Ok(exports)
}
}
#[derive(Debug)]
pub struct Instance<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: Option<NameAnnotation<'a>>,
pub exports: InlineExport<'a>,
pub kind: InstanceKind<'a>,
}
impl<'a> Parse<'a> for Instance<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::instance>()?.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 InstanceKind<'a> {
Import {
import: InlineImport<'a>,
ty: ComponentTypeUse<'a, InstanceType<'a>>,
},
Instantiate {
component: ItemRef<'a, kw::component>,
args: Vec<InstantiationArg<'a>>,
},
BundleOfExports(Vec<ComponentExport<'a>>),
}
impl<'a> Parse<'a> for InstanceKind<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if let Some(import) = parser.parse()? {
return Ok(Self::Import {
import,
ty: parser.parse()?,
});
}
if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? {
parser.parens(|parser| {
parser.parse::<kw::instantiate>()?;
Ok(Self::Instantiate {
component: parser.parse::<IndexOrRef<'_, _>>()?.0,
args: parser.parse()?,
})
})
} else {
Ok(Self::BundleOfExports(parser.parse()?))
}
}
}
impl Default for kw::component {
fn default() -> kw::component {
kw::component(Span::from_offset(0))
}
}
#[derive(Debug)]
pub struct InstantiationArg<'a> {
pub name: &'a str,
pub kind: InstantiationArgKind<'a>,
}
impl<'a> Parse<'a> for InstantiationArg<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::with>()?;
Ok(Self {
name: parser.parse()?,
kind: parser.parse()?,
})
}
}
impl<'a> Parse<'a> for Vec<InstantiationArg<'a>> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut args = Vec::new();
while !parser.is_empty() {
args.push(parser.parens(|parser| parser.parse())?);
}
Ok(args)
}
}
#[derive(Debug)]
pub enum InstantiationArgKind<'a> {
Item(ComponentExportKind<'a>),
BundleOfExports(Span, Vec<ComponentExport<'a>>),
}
impl<'a> Parse<'a> for InstantiationArgKind<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if let Some(item) = parser.parse()? {
Ok(Self::Item(item))
} else {
parser.parens(|parser| {
let span = parser.parse::<kw::instance>()?.0;
Ok(Self::BundleOfExports(span, parser.parse()?))
})
}
}
}