1use crate::component::*;
2use crate::kw;
3use crate::parser::{Cursor, Parse, Parser, Peek, Result};
4use crate::token::{Id, Index, LParen, NameAnnotation, Span};
5
6#[derive(Debug)]
8pub struct ComponentImport<'a> {
9 pub span: Span,
11 pub name: ComponentExternName<'a>,
13 pub item: ItemSig<'a>,
15}
16
17impl<'a> Parse<'a> for ComponentImport<'a> {
18 fn parse(parser: Parser<'a>) -> Result<Self> {
19 let span = parser.parse::<kw::import>()?.0;
20 let name = parser.parse()?;
21 let item = parser.parens(|p| p.parse())?;
22 Ok(ComponentImport { span, name, item })
23 }
24}
25
26#[derive(Debug, Copy, Clone)]
28pub struct ComponentExternName<'a> {
29 pub name: &'a str,
31 pub implements: Option<&'a str>,
33}
34
35impl<'a> Parse<'a> for ComponentExternName<'a> {
36 fn parse(parser: Parser<'a>) -> Result<Self> {
37 let name = if parser.peek::<LParen>()? {
44 parser.parens(|p| {
45 p.parse::<kw::interface>()?;
46 p.parse()
47 })?
48 } else {
49 parser.parse()?
50 };
51 let implements = if parser.peek2::<kw::implements>()? {
52 Some(parser.parens(|p| {
53 p.parse::<kw::implements>()?;
54 p.parse()
55 })?)
56 } else {
57 None
58 };
59 Ok(ComponentExternName { name, implements })
60 }
61}
62
63#[derive(Debug)]
65pub struct ItemSig<'a> {
66 pub span: Span,
68 pub id: Option<Id<'a>>,
71 pub name: Option<NameAnnotation<'a>>,
74 pub kind: ItemSigKind<'a>,
76}
77
78impl<'a> Parse<'a> for ItemSig<'a> {
79 fn parse(parser: Parser<'a>) -> Result<Self> {
80 parse_item_sig(parser, true)
81 }
82}
83
84#[derive(Debug)]
86pub struct ItemSigNoName<'a>(pub ItemSig<'a>);
87
88impl<'a> Parse<'a> for ItemSigNoName<'a> {
89 fn parse(parser: Parser<'a>) -> Result<Self> {
90 Ok(ItemSigNoName(parse_item_sig(parser, false)?))
91 }
92}
93
94fn parse_item_sig<'a>(parser: Parser<'a>, name: bool) -> Result<ItemSig<'a>> {
95 let mut l = parser.lookahead1();
96 let (span, parse_kind): (_, fn(Parser<'a>) -> Result<ItemSigKind<'a>>) =
97 if l.peek::<kw::core>()? {
98 let span = parser.parse::<kw::core>()?.0;
99 parser.parse::<kw::module>()?;
100 (span, |parser| Ok(ItemSigKind::CoreModule(parser.parse()?)))
101 } else if l.peek::<kw::func>()? {
102 let span = parser.parse::<kw::func>()?.0;
103 (span, |parser| Ok(ItemSigKind::Func(parser.parse()?)))
104 } else if l.peek::<kw::component>()? {
105 let span = parser.parse::<kw::component>()?.0;
106 (span, |parser| Ok(ItemSigKind::Component(parser.parse()?)))
107 } else if l.peek::<kw::instance>()? {
108 let span = parser.parse::<kw::instance>()?.0;
109 (span, |parser| Ok(ItemSigKind::Instance(parser.parse()?)))
110 } else if l.peek::<kw::value>()? {
111 let span = parser.parse::<kw::value>()?.0;
112 (span, |parser| Ok(ItemSigKind::Value(parser.parse()?)))
113 } else if l.peek::<kw::r#type>()? {
114 let span = parser.parse::<kw::r#type>()?.0;
115 (span, |parser| {
116 Ok(ItemSigKind::Type(parser.parens(|parser| parser.parse())?))
117 })
118 } else {
119 return Err(l.error());
120 };
121 Ok(ItemSig {
122 span,
123 id: if name { parser.parse()? } else { None },
124 name: if name { parser.parse()? } else { None },
125 kind: parse_kind(parser)?,
126 })
127}
128
129#[derive(Debug)]
131pub enum ItemSigKind<'a> {
132 CoreModule(CoreTypeUse<'a, ModuleType<'a>>),
134 Func(ComponentTypeUse<'a, ComponentFunctionType<'a>>),
136 Component(ComponentTypeUse<'a, ComponentType<'a>>),
138 Instance(ComponentTypeUse<'a, InstanceType<'a>>),
140 Value(ComponentValTypeUse<'a>),
142 Type(TypeBounds<'a>),
144}
145
146#[derive(Debug)]
148pub enum TypeBounds<'a> {
149 Eq(Index<'a>),
151 SubResource,
153}
154
155impl<'a> Parse<'a> for TypeBounds<'a> {
156 fn parse(parser: Parser<'a>) -> Result<Self> {
157 let mut l = parser.lookahead1();
158 if l.peek::<kw::eq>()? {
159 parser.parse::<kw::eq>()?;
160 Ok(Self::Eq(parser.parse()?))
161 } else if l.peek::<kw::sub>()? {
162 parser.parse::<kw::sub>()?;
163 parser.parse::<kw::resource>()?;
164 Ok(Self::SubResource)
165 } else {
166 Err(l.error())
167 }
168 }
169}
170
171#[derive(Debug, Clone)]
176pub struct InlineImport<'a> {
177 pub name: ComponentExternName<'a>,
179}
180
181impl<'a> Parse<'a> for InlineImport<'a> {
182 fn parse(parser: Parser<'a>) -> Result<Self> {
183 parser.parens(|p| {
184 p.parse::<kw::import>()?;
185 Ok(InlineImport { name: p.parse()? })
186 })
187 }
188}
189
190impl Peek for InlineImport<'_> {
191 fn peek(cursor: Cursor<'_>) -> Result<bool> {
192 let cursor = match cursor.lparen()? {
193 Some(cursor) => cursor,
194 None => return Ok(false),
195 };
196 let cursor = match cursor.keyword()? {
197 Some(("import", cursor)) => cursor,
198 _ => return Ok(false),
199 };
200
201 if let Some((_, cursor)) = cursor.string()? {
203 return Ok(cursor.rparen()?.is_some());
204 }
205
206 let cursor = match cursor.lparen()? {
208 Some(cursor) => cursor,
209 None => return Ok(false),
210 };
211 let cursor = match cursor.keyword()? {
212 Some(("interface", cursor)) => cursor,
213 _ => return Ok(false),
214 };
215 let cursor = match cursor.string()? {
216 Some((_, cursor)) => cursor,
217 _ => return Ok(false),
218 };
219 let cursor = match cursor.rparen()? {
220 Some(cursor) => cursor,
221 _ => return Ok(false),
222 };
223 Ok(cursor.rparen()?.is_some())
224 }
225
226 fn display() -> &'static str {
227 "inline import"
228 }
229}