wac_parser/ast/
type.rs

1use super::{
2    parse_delimited, parse_optional, parse_token, DocComment, Error, Ident, Lookahead, PackagePath,
3    Parse, ParseResult, Peek,
4};
5use crate::lexer::{Lexer, Token};
6use miette::SourceSpan;
7use serde::Serialize;
8
9/// Represents a type statement in the AST.
10#[derive(Debug, Clone, Serialize)]
11#[serde(rename_all = "camelCase")]
12pub enum TypeStatement<'a> {
13    /// The statement is for an interface declaration.
14    Interface(InterfaceDecl<'a>),
15    /// The statement is for a world declaration.
16    World(WorldDecl<'a>),
17    /// The statement is for a type declaration.
18    Type(TypeDecl<'a>),
19}
20
21impl<'a> Parse<'a> for TypeStatement<'a> {
22    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
23        let mut lookahead = Lookahead::new(lexer);
24        if InterfaceDecl::peek(&mut lookahead) {
25            Ok(Self::Interface(Parse::parse(lexer)?))
26        } else if WorldDecl::peek(&mut lookahead) {
27            Ok(Self::World(Parse::parse(lexer)?))
28        } else if TypeDecl::peek(&mut lookahead) {
29            Ok(Self::Type(Parse::parse(lexer)?))
30        } else {
31            Err(lookahead.error())
32        }
33    }
34}
35
36impl Peek for TypeStatement<'_> {
37    fn peek(lookahead: &mut Lookahead) -> bool {
38        lookahead.peek(Token::InterfaceKeyword)
39            || lookahead.peek(Token::WorldKeyword)
40            || TypeDecl::peek(lookahead)
41    }
42}
43
44/// Represents a top-level type declaration in the AST.
45///
46/// Unlike tin interfaces and worlds, resources cannot
47/// be declared at the top-level.
48#[derive(Debug, Clone, Serialize)]
49#[serde(rename_all = "camelCase")]
50pub enum TypeDecl<'a> {
51    /// The declaration is for a variant.
52    Variant(VariantDecl<'a>),
53    /// The declaration is for a record.
54    Record(RecordDecl<'a>),
55    /// The declaration is for a flags.
56    Flags(FlagsDecl<'a>),
57    /// The declaration is for an enum.
58    Enum(EnumDecl<'a>),
59    /// The declaration is for a type alias.
60    Alias(TypeAlias<'a>),
61}
62
63impl TypeDecl<'_> {
64    /// Gets the identifier of the type being declared.
65    pub fn id(&self) -> &Ident {
66        match self {
67            Self::Variant(variant) => &variant.id,
68            Self::Record(record) => &record.id,
69            Self::Flags(flags) => &flags.id,
70            Self::Enum(e) => &e.id,
71            Self::Alias(alias) => &alias.id,
72        }
73    }
74}
75
76impl<'a> Parse<'a> for TypeDecl<'a> {
77    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
78        let mut lookahead = Lookahead::new(lexer);
79        if lookahead.peek(Token::VariantKeyword) {
80            Ok(Self::Variant(Parse::parse(lexer)?))
81        } else if lookahead.peek(Token::RecordKeyword) {
82            Ok(Self::Record(Parse::parse(lexer)?))
83        } else if lookahead.peek(Token::FlagsKeyword) {
84            Ok(Self::Flags(Parse::parse(lexer)?))
85        } else if lookahead.peek(Token::EnumKeyword) {
86            Ok(Self::Enum(Parse::parse(lexer)?))
87        } else if lookahead.peek(Token::TypeKeyword) {
88            Ok(Self::Alias(Parse::parse(lexer)?))
89        } else {
90            Err(lookahead.error())
91        }
92    }
93}
94
95impl Peek for TypeDecl<'_> {
96    fn peek(lookahead: &mut Lookahead) -> bool {
97        lookahead.peek(Token::VariantKeyword)
98            || lookahead.peek(Token::RecordKeyword)
99            || lookahead.peek(Token::FlagsKeyword)
100            || lookahead.peek(Token::EnumKeyword)
101            || lookahead.peek(Token::TypeKeyword)
102    }
103}
104
105/// Represents a resource declaration in the AST.
106#[derive(Debug, Clone, Serialize)]
107#[serde(rename_all = "camelCase")]
108pub struct ResourceDecl<'a> {
109    /// The doc comments for the resource.
110    pub docs: Vec<DocComment<'a>>,
111    /// The identifier of the resource.
112    pub id: Ident<'a>,
113    /// The methods of the resource.
114    pub methods: Vec<ResourceMethod<'a>>,
115}
116
117impl<'a> Parse<'a> for ResourceDecl<'a> {
118    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
119        let docs = Parse::parse(lexer)?;
120        parse_token(lexer, Token::ResourceKeyword)?;
121        let id = Ident::parse(lexer)?;
122        let mut lookahead = Lookahead::new(lexer);
123        let methods = if lookahead.peek(Token::Semicolon) {
124            lexer.next();
125            Default::default()
126        } else if lookahead.peek(Token::OpenBrace) {
127            parse_token(lexer, Token::OpenBrace)?;
128            let methods = parse_delimited(lexer, Token::CloseBrace, false)?;
129            parse_token(lexer, Token::CloseBrace)?;
130            methods
131        } else {
132            return Err(lookahead.error());
133        };
134
135        Ok(Self { docs, id, methods })
136    }
137}
138
139/// Represents a variant declaration in the AST.
140#[derive(Debug, Clone, Serialize)]
141#[serde(rename_all = "camelCase")]
142pub struct VariantDecl<'a> {
143    /// The doc comments for the variant.
144    pub docs: Vec<DocComment<'a>>,
145    /// The identifier of the variant.
146    pub id: Ident<'a>,
147    /// The cases of the variant.
148    pub cases: Vec<VariantCase<'a>>,
149}
150
151impl<'a> Parse<'a> for VariantDecl<'a> {
152    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
153        let docs = Parse::parse(lexer)?;
154        parse_token(lexer, Token::VariantKeyword)?;
155        let id = Ident::parse(lexer)?;
156        parse_token(lexer, Token::OpenBrace)?;
157        let cases = parse_delimited(lexer, Token::CloseBrace, true)?;
158        let close = parse_token(lexer, Token::CloseBrace)?;
159
160        if cases.is_empty() {
161            return Err(Error::EmptyType {
162                ty: "variant",
163                kind: "case",
164                span: close,
165            });
166        }
167
168        Ok(Self { docs, id, cases })
169    }
170}
171
172/// Represents a variant case in the AST.
173#[derive(Debug, Clone, Serialize)]
174#[serde(rename_all = "camelCase")]
175pub struct VariantCase<'a> {
176    /// The doc comments for the case.
177    pub docs: Vec<DocComment<'a>>,
178    /// The identifier of the case.
179    pub id: Ident<'a>,
180    /// The type of the case.
181    pub ty: Option<Type<'a>>,
182}
183
184impl<'a> Parse<'a> for VariantCase<'a> {
185    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
186        let docs = Parse::parse(lexer)?;
187        let id = Ident::parse(lexer)?;
188        let ty = parse_optional(lexer, Token::OpenParen, |lexer| {
189            let ty = Parse::parse(lexer)?;
190            parse_token(lexer, Token::CloseParen)?;
191            Ok(ty)
192        })?;
193        Ok(Self { docs, id, ty })
194    }
195}
196
197impl Peek for VariantCase<'_> {
198    fn peek(lookahead: &mut Lookahead) -> bool {
199        lookahead.peek(Token::Ident)
200    }
201}
202
203/// Represents a record declaration in the AST.
204#[derive(Debug, Clone, Serialize)]
205#[serde(rename_all = "camelCase")]
206pub struct RecordDecl<'a> {
207    /// The doc comments for the record.
208    pub docs: Vec<DocComment<'a>>,
209    /// The identifier of the record.
210    pub id: Ident<'a>,
211    /// The fields of the record.
212    pub fields: Vec<Field<'a>>,
213}
214
215impl<'a> Parse<'a> for RecordDecl<'a> {
216    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
217        let docs = Parse::parse(lexer)?;
218        parse_token(lexer, Token::RecordKeyword)?;
219        let id = Ident::parse(lexer)?;
220        parse_token(lexer, Token::OpenBrace)?;
221        let fields = parse_delimited(lexer, Token::CloseBrace, true)?;
222        let close = parse_token(lexer, Token::CloseBrace)?;
223
224        if fields.is_empty() {
225            return Err(Error::EmptyType {
226                ty: "record",
227                kind: "field",
228                span: close,
229            });
230        }
231
232        Ok(Self { docs, id, fields })
233    }
234}
235
236/// Represents a record field in the AST.
237#[derive(Debug, Clone, Serialize)]
238#[serde(rename_all = "camelCase")]
239pub struct Field<'a> {
240    /// The docs for the field.
241    pub docs: Vec<DocComment<'a>>,
242    /// The identifier of the field.
243    pub id: Ident<'a>,
244    /// The type of the field.
245    pub ty: Type<'a>,
246}
247
248impl<'a> Parse<'a> for Field<'a> {
249    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
250        let docs = Parse::parse(lexer)?;
251        let named: NamedType = Parse::parse(lexer)?;
252        Ok(Self {
253            docs,
254            id: named.id,
255            ty: named.ty,
256        })
257    }
258}
259
260impl Peek for Field<'_> {
261    fn peek(lookahead: &mut Lookahead) -> bool {
262        NamedType::peek(lookahead)
263    }
264}
265
266/// Represents a flags declaration in the AST.
267#[derive(Debug, Clone, Serialize)]
268#[serde(rename_all = "camelCase")]
269pub struct FlagsDecl<'a> {
270    /// The doc comments for the flags.
271    pub docs: Vec<DocComment<'a>>,
272    /// The identifier of the flags.
273    pub id: Ident<'a>,
274    /// The flag values.
275    pub flags: Vec<Flag<'a>>,
276}
277
278impl<'a> Parse<'a> for FlagsDecl<'a> {
279    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
280        let docs = Parse::parse(lexer)?;
281        parse_token(lexer, Token::FlagsKeyword)?;
282        let id = Ident::parse(lexer)?;
283        parse_token(lexer, Token::OpenBrace)?;
284        let flags = parse_delimited(lexer, Token::CloseBrace, true)?;
285        let close = parse_token(lexer, Token::CloseBrace)?;
286
287        if flags.is_empty() {
288            return Err(Error::EmptyType {
289                ty: "flags",
290                kind: "flag",
291                span: close,
292            });
293        }
294
295        Ok(Self { docs, id, flags })
296    }
297}
298
299/// Represents a flag in the AST.
300#[derive(Debug, Clone, Serialize)]
301#[serde(rename_all = "camelCase")]
302pub struct Flag<'a> {
303    /// The doc comments for the flag.
304    pub docs: Vec<DocComment<'a>>,
305    /// The identifier of the flag.
306    pub id: Ident<'a>,
307}
308
309impl<'a> Parse<'a> for Flag<'a> {
310    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
311        let docs = Parse::parse(lexer)?;
312        let id = Ident::parse(lexer)?;
313        Ok(Self { docs, id })
314    }
315}
316
317impl Peek for Flag<'_> {
318    fn peek(lookahead: &mut Lookahead) -> bool {
319        lookahead.peek(Token::Ident)
320    }
321}
322
323/// Represents an enum declaration in the AST.
324#[derive(Debug, Clone, Serialize)]
325#[serde(rename_all = "camelCase")]
326pub struct EnumDecl<'a> {
327    /// The doc comments for the enum.
328    pub docs: Vec<DocComment<'a>>,
329    /// The identifier of the enum.
330    pub id: Ident<'a>,
331    /// The cases of the enum.
332    pub cases: Vec<EnumCase<'a>>,
333}
334
335impl<'a> Parse<'a> for EnumDecl<'a> {
336    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
337        let docs = Parse::parse(lexer)?;
338        parse_token(lexer, Token::EnumKeyword)?;
339        let id = Ident::parse(lexer)?;
340        parse_token(lexer, Token::OpenBrace)?;
341        let cases = parse_delimited(lexer, Token::CloseBrace, true)?;
342        let close = parse_token(lexer, Token::CloseBrace)?;
343
344        if cases.is_empty() {
345            return Err(Error::EmptyType {
346                ty: "enum",
347                kind: "case",
348                span: close,
349            });
350        }
351
352        Ok(Self { docs, id, cases })
353    }
354}
355
356/// Represents an enum case in the AST.
357#[derive(Debug, Clone, Serialize)]
358#[serde(rename_all = "camelCase")]
359pub struct EnumCase<'a> {
360    /// The doc comments for the enum case.
361    pub docs: Vec<DocComment<'a>>,
362    /// The identifier of the enum case.
363    pub id: Ident<'a>,
364}
365
366impl<'a> Parse<'a> for EnumCase<'a> {
367    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
368        let docs = Parse::parse(lexer)?;
369        let id = Ident::parse(lexer)?;
370        Ok(Self { docs, id })
371    }
372}
373
374impl Peek for EnumCase<'_> {
375    fn peek(lookahead: &mut Lookahead) -> bool {
376        lookahead.peek(Token::Ident)
377    }
378}
379
380/// Represents a resource method in the AST.
381#[derive(Debug, Clone, Serialize)]
382#[serde(rename_all = "camelCase")]
383pub enum ResourceMethod<'a> {
384    /// The method is a constructor.
385    Constructor(Constructor<'a>),
386    /// The method is a instance or static method.
387    Method(Method<'a>),
388}
389
390impl<'a> Parse<'a> for ResourceMethod<'a> {
391    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
392        let mut lookahead = Lookahead::new(lexer);
393        if lookahead.peek(Token::ConstructorKeyword) {
394            Ok(Self::Constructor(Parse::parse(lexer)?))
395        } else if Ident::peek(&mut lookahead) {
396            Ok(Self::Method(Parse::parse(lexer)?))
397        } else {
398            Err(lookahead.error())
399        }
400    }
401}
402
403impl Peek for ResourceMethod<'_> {
404    fn peek(lookahead: &mut Lookahead) -> bool {
405        lookahead.peek(Token::ConstructorKeyword) || Ident::peek(lookahead)
406    }
407}
408
409/// Represents a resource constructor in the AST.
410#[derive(Debug, Clone, Serialize)]
411#[serde(rename_all = "camelCase")]
412pub struct Constructor<'a> {
413    /// The doc comments for the constructor.
414    pub docs: Vec<DocComment<'a>>,
415    /// The span of the constructor keyword.
416    pub span: SourceSpan,
417    /// The parameters of the constructor.
418    pub params: Vec<NamedType<'a>>,
419}
420
421impl<'a> Parse<'a> for Constructor<'a> {
422    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
423        let docs = Parse::parse(lexer)?;
424        let span = parse_token(lexer, Token::ConstructorKeyword)?;
425        parse_token(lexer, Token::OpenParen)?;
426        let params = parse_delimited(lexer, Token::CloseParen, true)?;
427        parse_token(lexer, Token::CloseParen)?;
428        parse_token(lexer, Token::Semicolon)?;
429        Ok(Self { docs, span, params })
430    }
431}
432
433/// Represents a resource method in the AST.
434#[derive(Debug, Clone, Serialize)]
435#[serde(rename_all = "camelCase")]
436pub struct Method<'a> {
437    /// The doc comments for the method.
438    pub docs: Vec<DocComment<'a>>,
439    /// The identifier of the method.
440    pub id: Ident<'a>,
441    /// Wether or not the method is static.
442    pub is_static: bool,
443    /// The function type of the method.
444    pub ty: FuncType<'a>,
445}
446
447impl<'a> Parse<'a> for Method<'a> {
448    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
449        let docs = Parse::parse(lexer)?;
450        let id = Ident::parse(lexer)?;
451        parse_token(lexer, Token::Colon)?;
452        let is_static = lexer
453            .peek()
454            .map(|(r, _)| matches!(r, Ok(Token::StaticKeyword)))
455            .unwrap_or(false);
456
457        if is_static {
458            lexer.next();
459        }
460
461        let ty = Parse::parse(lexer)?;
462        parse_token(lexer, Token::Semicolon)?;
463        Ok(Self {
464            docs,
465            id,
466            is_static,
467            ty,
468        })
469    }
470}
471
472/// Represents a function type reference in the AST.
473#[derive(Debug, Clone, Serialize)]
474#[serde(rename_all = "camelCase")]
475pub enum FuncTypeRef<'a> {
476    /// The reference is a function type.
477    Func(FuncType<'a>),
478    /// The reference is an identifier to a function type.
479    Ident(Ident<'a>),
480}
481
482impl<'a> Parse<'a> for FuncTypeRef<'a> {
483    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
484        let mut lookahead = Lookahead::new(lexer);
485        if lookahead.peek(Token::FuncKeyword) {
486            Ok(Self::Func(Parse::parse(lexer)?))
487        } else if Ident::peek(&mut lookahead) {
488            Ok(Self::Ident(Parse::parse(lexer)?))
489        } else {
490            Err(lookahead.error())
491        }
492    }
493}
494
495/// Represents a function type in the AST.
496#[derive(Debug, Clone, Serialize)]
497#[serde(rename_all = "camelCase")]
498pub struct FuncType<'a> {
499    /// The parameters of the function.
500    pub params: Vec<NamedType<'a>>,
501    /// The results of the function.
502    pub results: ResultList<'a>,
503}
504
505impl<'a> Parse<'a> for FuncType<'a> {
506    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
507        parse_token(lexer, Token::FuncKeyword)?;
508        parse_token(lexer, Token::OpenParen)?;
509        let params = parse_delimited(lexer, Token::CloseParen, true)?;
510        parse_token(lexer, Token::CloseParen)?;
511        let results =
512            parse_optional(lexer, Token::Arrow, Parse::parse)?.unwrap_or(ResultList::Empty);
513
514        Ok(Self { params, results })
515    }
516}
517
518impl Peek for FuncType<'_> {
519    fn peek(lookahead: &mut Lookahead) -> bool {
520        lookahead.peek(Token::FuncKeyword)
521    }
522}
523
524/// Represents a result list in the AST.
525#[derive(Debug, Clone, Serialize)]
526#[serde(rename_all = "camelCase")]
527pub enum ResultList<'a> {
528    /// The function has no results.
529    Empty,
530    /// The function returns a scalar value.
531    Scalar(Type<'a>),
532    /// The function has named results.
533    Named(Vec<NamedType<'a>>),
534}
535
536impl<'a> Parse<'a> for ResultList<'a> {
537    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
538        let mut lookahead = Lookahead::new(lexer);
539        if lookahead.peek(Token::OpenParen) {
540            parse_token(lexer, Token::OpenParen)?;
541            let results = parse_delimited(lexer, Token::CloseParen, true)?;
542            parse_token(lexer, Token::CloseParen)?;
543            Ok(Self::Named(results))
544        } else if Type::peek(&mut lookahead) {
545            Ok(Self::Scalar(Parse::parse(lexer)?))
546        } else {
547            Ok(Self::Empty)
548        }
549    }
550}
551
552/// Represents a name and an associated type in the AST.
553#[derive(Debug, Clone, Serialize)]
554#[serde(rename_all = "camelCase")]
555pub struct NamedType<'a> {
556    /// The identifier of the type.
557    pub id: Ident<'a>,
558    /// The type.
559    pub ty: Type<'a>,
560}
561
562impl<'a> Parse<'a> for NamedType<'a> {
563    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
564        let id = Ident::parse(lexer)?;
565        parse_token(lexer, Token::Colon)?;
566        let ty = Parse::parse(lexer)?;
567        Ok(Self { id, ty })
568    }
569}
570
571impl Peek for NamedType<'_> {
572    fn peek(lookahead: &mut Lookahead) -> bool {
573        Ident::peek(lookahead)
574    }
575}
576
577/// Represents a type alias in the AST.
578#[derive(Debug, Clone, Serialize)]
579#[serde(rename_all = "camelCase")]
580pub struct TypeAlias<'a> {
581    /// The docs for the type alias.
582    pub docs: Vec<DocComment<'a>>,
583    /// The identifier of the type alias.
584    pub id: Ident<'a>,
585    /// The kind of type alias.
586    pub kind: TypeAliasKind<'a>,
587}
588
589impl<'a> Parse<'a> for TypeAlias<'a> {
590    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
591        let docs = Parse::parse(lexer)?;
592        parse_token(lexer, Token::TypeKeyword)?;
593        let id = Ident::parse(lexer)?;
594        parse_token(lexer, Token::Equals)?;
595        let kind = Parse::parse(lexer)?;
596        parse_token(lexer, Token::Semicolon)?;
597        Ok(Self { docs, id, kind })
598    }
599}
600
601/// Represents a type alias kind in the AST.
602#[derive(Debug, Clone, Serialize)]
603#[serde(rename_all = "camelCase")]
604pub enum TypeAliasKind<'a> {
605    /// The alias is to a function type.
606    Func(FuncType<'a>),
607    /// The alias is to another type.
608    Type(Type<'a>),
609}
610
611impl<'a> Parse<'a> for TypeAliasKind<'a> {
612    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
613        let mut lookahead = Lookahead::new(lexer);
614        if lookahead.peek(Token::FuncKeyword) {
615            Ok(Self::Func(Parse::parse(lexer)?))
616        } else if Type::peek(&mut lookahead) {
617            Ok(Self::Type(Parse::parse(lexer)?))
618        } else {
619            Err(lookahead.error())
620        }
621    }
622}
623
624/// Represents a type in the AST.
625#[derive(Debug, Clone, Serialize)]
626#[serde(rename_all = "camelCase")]
627pub enum Type<'a> {
628    /// A `u8` type.
629    U8(SourceSpan),
630    /// A `s8` type.
631    S8(SourceSpan),
632    /// A `u16` type.
633    U16(SourceSpan),
634    /// A `s16` type.
635    S16(SourceSpan),
636    /// A `u32` type.
637    U32(SourceSpan),
638    /// A `s32` type.
639    S32(SourceSpan),
640    /// A `u64` type.
641    U64(SourceSpan),
642    /// A `s64` type.
643    S64(SourceSpan),
644    /// A `f32` type.
645    F32(SourceSpan),
646    /// A `f64` type.
647    F64(SourceSpan),
648    /// A `char` type.
649    Char(SourceSpan),
650    /// A `bool` type.
651    Bool(SourceSpan),
652    /// A `string` type.
653    String(SourceSpan),
654    /// A tuple type.
655    Tuple(Vec<Type<'a>>, SourceSpan),
656    /// A list type.
657    List(Box<Type<'a>>, SourceSpan),
658    /// An option type.
659    Option(Box<Type<'a>>, SourceSpan),
660    /// A result type.
661    Result {
662        /// The `ok` of the result type.
663        ok: Option<Box<Type<'a>>>,
664        /// The `err` of the result type.
665        err: Option<Box<Type<'a>>>,
666        /// The span of the result type.
667        span: SourceSpan,
668    },
669    /// A borrow type.
670    Borrow(Ident<'a>, SourceSpan),
671    /// An identifier to a value type.
672    Ident(Ident<'a>),
673}
674
675impl<'a> Type<'a> {
676    /// Gets the span of the type.
677    pub fn span(&self) -> SourceSpan {
678        match self {
679            Self::U8(span)
680            | Self::S8(span)
681            | Self::U16(span)
682            | Self::S16(span)
683            | Self::U32(span)
684            | Self::S32(span)
685            | Self::U64(span)
686            | Self::S64(span)
687            | Self::F32(span)
688            | Self::F64(span)
689            | Self::Char(span)
690            | Self::Bool(span)
691            | Self::String(span)
692            | Self::Tuple(_, span)
693            | Self::List(_, span)
694            | Self::Option(_, span)
695            | Self::Result { span, .. }
696            | Self::Borrow(_, span) => *span,
697            Self::Ident(ident) => ident.span,
698        }
699    }
700}
701
702impl<'a> Parse<'a> for Type<'a> {
703    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
704        let mut lookahead = Lookahead::new(lexer);
705        if lookahead.peek(Token::U8Keyword) {
706            Ok(Self::U8(lexer.next().unwrap().1))
707        } else if lookahead.peek(Token::S8Keyword) {
708            Ok(Self::S8(lexer.next().unwrap().1))
709        } else if lookahead.peek(Token::U16Keyword) {
710            Ok(Self::U16(lexer.next().unwrap().1))
711        } else if lookahead.peek(Token::S16Keyword) {
712            Ok(Self::S16(lexer.next().unwrap().1))
713        } else if lookahead.peek(Token::U32Keyword) {
714            Ok(Self::U32(lexer.next().unwrap().1))
715        } else if lookahead.peek(Token::S32Keyword) {
716            Ok(Self::S32(lexer.next().unwrap().1))
717        } else if lookahead.peek(Token::U64Keyword) {
718            Ok(Self::U64(lexer.next().unwrap().1))
719        } else if lookahead.peek(Token::S64Keyword) {
720            Ok(Self::S64(lexer.next().unwrap().1))
721        } else if lookahead.peek(Token::F32Keyword) {
722            Ok(Self::F32(lexer.next().unwrap().1))
723        } else if lookahead.peek(Token::F64Keyword) {
724            Ok(Self::F64(lexer.next().unwrap().1))
725        } else if lookahead.peek(Token::CharKeyword) {
726            Ok(Self::Char(lexer.next().unwrap().1))
727        } else if lookahead.peek(Token::BoolKeyword) {
728            Ok(Self::Bool(lexer.next().unwrap().1))
729        } else if lookahead.peek(Token::StringKeyword) {
730            Ok(Self::String(lexer.next().unwrap().1))
731        } else if lookahead.peek(Token::TupleKeyword) {
732            let span = lexer.next().unwrap().1;
733            parse_token(lexer, Token::OpenAngle)?;
734
735            // There must be at least one type in the tuple.
736            let mut lookahead = Lookahead::new(lexer);
737            if !Type::peek(&mut lookahead) {
738                return Err(lookahead.error());
739            }
740
741            let types = parse_delimited(lexer, Token::CloseAngle, true)?;
742            assert!(!types.is_empty());
743            let close = parse_token(lexer, Token::CloseAngle)?;
744            Ok(Self::Tuple(
745                types,
746                SourceSpan::new(
747                    span.offset().into(),
748                    (close.offset() + close.len()) - span.offset(),
749                ),
750            ))
751        } else if lookahead.peek(Token::ListKeyword) {
752            let span = lexer.next().unwrap().1;
753            parse_token(lexer, Token::OpenAngle)?;
754            let ty = Box::new(Parse::parse(lexer)?);
755            let close = parse_token(lexer, Token::CloseAngle)?;
756            Ok(Self::List(
757                ty,
758                SourceSpan::new(
759                    span.offset().into(),
760                    (close.offset() + close.len()) - span.offset(),
761                ),
762            ))
763        } else if lookahead.peek(Token::OptionKeyword) {
764            let span = lexer.next().unwrap().1;
765            parse_token(lexer, Token::OpenAngle)?;
766            let ty = Box::new(Parse::parse(lexer)?);
767            let close = parse_token(lexer, Token::CloseAngle)?;
768            Ok(Self::Option(
769                ty,
770                SourceSpan::new(
771                    span.offset().into(),
772                    (close.offset() + close.len()) - span.offset(),
773                ),
774            ))
775        } else if lookahead.peek(Token::ResultKeyword) {
776            let mut span = lexer.next().unwrap().1;
777
778            let parse = |lexer: &mut Lexer<'a>| {
779                let mut lookahead = Lookahead::new(lexer);
780                let ok = if lookahead.peek(Token::Underscore) {
781                    lexer.next();
782                    None
783                } else if Type::peek(&mut lookahead) {
784                    Some(Box::new(Parse::parse(lexer)?))
785                } else {
786                    return Err(lookahead.error());
787                };
788
789                let err = parse_optional(lexer, Token::Comma, |lexer| {
790                    let mut lookahead = Lookahead::new(lexer);
791                    if lookahead.peek(Token::Underscore) {
792                        lexer.next();
793                        Ok(None)
794                    } else if Type::peek(&mut lookahead) {
795                        Ok(Some(Box::new(Parse::parse(lexer)?)))
796                    } else {
797                        return Err(lookahead.error());
798                    }
799                })?
800                .unwrap_or(None);
801
802                let close = parse_token(lexer, Token::CloseAngle)?;
803                span = SourceSpan::new(
804                    span.offset().into(),
805                    (close.offset() + close.len()) - span.offset(),
806                );
807                Ok((ok, err))
808            };
809
810            let (ok, err) = match parse_optional(lexer, Token::OpenAngle, parse)? {
811                Some((ok, err)) => (ok, err),
812                None => (None, None),
813            };
814            Ok(Self::Result { ok, err, span })
815        } else if lookahead.peek(Token::BorrowKeyword) {
816            let span = lexer.next().unwrap().1;
817            parse_token(lexer, Token::OpenAngle)?;
818            let id = Parse::parse(lexer)?;
819            let close = parse_token(lexer, Token::CloseAngle)?;
820            Ok(Self::Borrow(
821                id,
822                SourceSpan::new(
823                    span.offset().into(),
824                    (close.offset() + close.len()) - span.offset(),
825                ),
826            ))
827        } else if Ident::peek(&mut lookahead) {
828            Ok(Self::Ident(Parse::parse(lexer)?))
829        } else {
830            Err(lookahead.error())
831        }
832    }
833}
834
835impl Peek for Type<'_> {
836    fn peek(lookahead: &mut Lookahead) -> bool {
837        lookahead.peek(Token::U8Keyword)
838            || lookahead.peek(Token::S8Keyword)
839            || lookahead.peek(Token::U16Keyword)
840            || lookahead.peek(Token::S16Keyword)
841            || lookahead.peek(Token::U32Keyword)
842            || lookahead.peek(Token::S32Keyword)
843            || lookahead.peek(Token::U64Keyword)
844            || lookahead.peek(Token::S64Keyword)
845            || lookahead.peek(Token::F32Keyword)
846            || lookahead.peek(Token::F64Keyword)
847            || lookahead.peek(Token::CharKeyword)
848            || lookahead.peek(Token::BoolKeyword)
849            || lookahead.peek(Token::StringKeyword)
850            || lookahead.peek(Token::TupleKeyword)
851            || lookahead.peek(Token::ListKeyword)
852            || lookahead.peek(Token::OptionKeyword)
853            || lookahead.peek(Token::ResultKeyword)
854            || lookahead.peek(Token::BorrowKeyword)
855            || Ident::peek(lookahead)
856    }
857}
858
859/// Represents an interface or world type declaration in the AST.
860///
861/// Unlike top-level type declarations, interfaces and worlds can
862/// also declare resources.
863#[derive(Debug, Clone, Serialize)]
864#[serde(rename_all = "camelCase")]
865pub enum ItemTypeDecl<'a> {
866    /// The declaration is for a resource.
867    Resource(ResourceDecl<'a>),
868    /// The declaration is for a variant.
869    Variant(VariantDecl<'a>),
870    /// The declaration is for a record.
871    Record(RecordDecl<'a>),
872    /// The declaration is for a flags.
873    Flags(FlagsDecl<'a>),
874    /// The declaration is for an enum.
875    Enum(EnumDecl<'a>),
876    /// The declaration is for a type alias.
877    Alias(TypeAlias<'a>),
878}
879
880impl<'a> Parse<'a> for ItemTypeDecl<'a> {
881    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
882        let mut lookahead = Lookahead::new(lexer);
883        if lookahead.peek(Token::ResourceKeyword) {
884            Ok(Self::Resource(Parse::parse(lexer)?))
885        } else if lookahead.peek(Token::VariantKeyword) {
886            Ok(Self::Variant(Parse::parse(lexer)?))
887        } else if lookahead.peek(Token::RecordKeyword) {
888            Ok(Self::Record(Parse::parse(lexer)?))
889        } else if lookahead.peek(Token::FlagsKeyword) {
890            Ok(Self::Flags(Parse::parse(lexer)?))
891        } else if lookahead.peek(Token::EnumKeyword) {
892            Ok(Self::Enum(Parse::parse(lexer)?))
893        } else if lookahead.peek(Token::TypeKeyword) {
894            Ok(Self::Alias(Parse::parse(lexer)?))
895        } else {
896            Err(lookahead.error())
897        }
898    }
899}
900
901impl Peek for ItemTypeDecl<'_> {
902    fn peek(lookahead: &mut Lookahead) -> bool {
903        lookahead.peek(Token::ResourceKeyword)
904            || lookahead.peek(Token::VariantKeyword)
905            || lookahead.peek(Token::RecordKeyword)
906            || lookahead.peek(Token::FlagsKeyword)
907            || lookahead.peek(Token::EnumKeyword)
908            || lookahead.peek(Token::TypeKeyword)
909    }
910}
911
912impl ItemTypeDecl<'_> {
913    /// Gets the identifier of the type being declared.
914    pub fn id(&self) -> &Ident {
915        match self {
916            Self::Resource(resource) => &resource.id,
917            Self::Variant(variant) => &variant.id,
918            Self::Record(record) => &record.id,
919            Self::Flags(flags) => &flags.id,
920            Self::Enum(e) => &e.id,
921            Self::Alias(alias) => &alias.id,
922        }
923    }
924}
925
926/// Represents an interface declaration in the AST.
927#[derive(Debug, Clone, Serialize)]
928#[serde(rename_all = "camelCase")]
929pub struct InterfaceDecl<'a> {
930    /// The doc comments for the interface.
931    pub docs: Vec<DocComment<'a>>,
932    /// The identifier of the interface.
933    pub id: Ident<'a>,
934    /// The items of the interface.
935    pub items: Vec<InterfaceItem<'a>>,
936}
937
938impl<'a> Parse<'a> for InterfaceDecl<'a> {
939    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
940        let docs = Parse::parse(lexer)?;
941        parse_token(lexer, Token::InterfaceKeyword)?;
942        let id = Ident::parse(lexer)?;
943        parse_token(lexer, Token::OpenBrace)?;
944        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
945        parse_token(lexer, Token::CloseBrace)?;
946        Ok(Self { docs, id, items })
947    }
948}
949
950impl Peek for InterfaceDecl<'_> {
951    fn peek(lookahead: &mut Lookahead) -> bool {
952        lookahead.peek(Token::InterfaceKeyword)
953    }
954}
955
956/// Represents an interface item in the AST.
957#[derive(Debug, Clone, Serialize)]
958#[serde(rename_all = "camelCase")]
959pub enum InterfaceItem<'a> {
960    /// The item is a use of other types.
961    Use(Box<Use<'a>>),
962    /// The item is a type declaration.
963    Type(ItemTypeDecl<'a>),
964    /// The item is an interface export.
965    Export(InterfaceExport<'a>),
966}
967
968impl<'a> Parse<'a> for InterfaceItem<'a> {
969    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
970        let mut lookahead = Lookahead::new(lexer);
971        if Use::peek(&mut lookahead) {
972            Ok(Self::Use(Box::new(Parse::parse(lexer)?)))
973        } else if InterfaceExport::peek(&mut lookahead) {
974            Ok(Self::Export(Parse::parse(lexer)?))
975        } else if ItemTypeDecl::peek(&mut lookahead) {
976            Ok(Self::Type(Parse::parse(lexer)?))
977        } else {
978            Err(lookahead.error())
979        }
980    }
981}
982
983impl Peek for InterfaceItem<'_> {
984    fn peek(lookahead: &mut Lookahead) -> bool {
985        Use::peek(lookahead) || InterfaceExport::peek(lookahead) || ItemTypeDecl::peek(lookahead)
986    }
987}
988
989/// Represents a "use" in the AST.
990#[derive(Debug, Clone, Serialize)]
991#[serde(rename_all = "camelCase")]
992pub struct Use<'a> {
993    /// The doc comments for the use.
994    pub docs: Vec<DocComment<'a>>,
995    /// The path to the interface or world being used.
996    pub path: UsePath<'a>,
997    /// The items being used.
998    pub items: Vec<UseItem<'a>>,
999}
1000
1001impl<'a> Parse<'a> for Use<'a> {
1002    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1003        let docs = Parse::parse(lexer)?;
1004        parse_token(lexer, Token::UseKeyword)?;
1005        let path = Parse::parse(lexer)?;
1006        parse_token(lexer, Token::Dot)?;
1007        parse_token(lexer, Token::OpenBrace)?;
1008        let items = parse_delimited(lexer, Token::CloseBrace, true)?;
1009        parse_token(lexer, Token::CloseBrace)?;
1010        parse_token(lexer, Token::Semicolon)?;
1011        Ok(Self { docs, path, items })
1012    }
1013}
1014
1015impl Peek for Use<'_> {
1016    fn peek(lookahead: &mut Lookahead) -> bool {
1017        lookahead.peek(Token::UseKeyword)
1018    }
1019}
1020
1021/// Represents a use path in the AST.
1022#[derive(Debug, Clone, Serialize)]
1023#[serde(rename_all = "camelCase")]
1024pub enum UsePath<'a> {
1025    /// The path is a package path.
1026    Package(PackagePath<'a>),
1027    /// The path is an identifier.
1028    Ident(Ident<'a>),
1029}
1030
1031impl<'a> Parse<'a> for UsePath<'a> {
1032    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1033        let mut lookahead = Lookahead::new(lexer);
1034        if PackagePath::peek(&mut lookahead) {
1035            Ok(Self::Package(Parse::parse(lexer)?))
1036        } else if Ident::peek(&mut lookahead) {
1037            Ok(Self::Ident(Parse::parse(lexer)?))
1038        } else {
1039            Err(lookahead.error())
1040        }
1041    }
1042}
1043
1044impl Peek for UsePath<'_> {
1045    fn peek(lookahead: &mut Lookahead) -> bool {
1046        PackagePath::peek(lookahead) | Ident::peek(lookahead)
1047    }
1048}
1049
1050/// Represents a use item in the AST.
1051#[derive(Debug, Clone, Serialize)]
1052#[serde(rename_all = "camelCase")]
1053pub struct UseItem<'a> {
1054    /// The identifier of the item.
1055    pub id: Ident<'a>,
1056    /// The optional `as` identifier of the item.
1057    pub as_id: Option<Ident<'a>>,
1058}
1059
1060impl<'a> Parse<'a> for UseItem<'a> {
1061    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1062        let id = Ident::parse(lexer)?;
1063        let as_id = parse_optional(lexer, Token::AsKeyword, Ident::parse)?;
1064        Ok(Self { id, as_id })
1065    }
1066}
1067
1068impl Peek for UseItem<'_> {
1069    fn peek(lookahead: &mut Lookahead) -> bool {
1070        Ident::peek(lookahead)
1071    }
1072}
1073
1074/// Represents an interface export in the AST.
1075#[derive(Debug, Clone, Serialize)]
1076#[serde(rename_all = "camelCase")]
1077pub struct InterfaceExport<'a> {
1078    /// The doc comments for the export.
1079    pub docs: Vec<DocComment<'a>>,
1080    /// The identifier of the export.
1081    pub id: Ident<'a>,
1082    /// The type of the export.
1083    pub ty: FuncTypeRef<'a>,
1084}
1085
1086impl<'a> Parse<'a> for InterfaceExport<'a> {
1087    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1088        let docs = Parse::parse(lexer)?;
1089        let id = Ident::parse(lexer)?;
1090        parse_token(lexer, Token::Colon)?;
1091        let ty = Parse::parse(lexer)?;
1092        parse_token(lexer, Token::Semicolon)?;
1093        Ok(Self { docs, id, ty })
1094    }
1095}
1096
1097impl Peek for InterfaceExport<'_> {
1098    fn peek(lookahead: &mut Lookahead) -> bool {
1099        Ident::peek(lookahead)
1100    }
1101}
1102
1103/// Represents a world declaration in the AST.
1104#[derive(Debug, Clone, Serialize)]
1105#[serde(rename_all = "camelCase")]
1106pub struct WorldDecl<'a> {
1107    /// The doc comments for the world.
1108    pub docs: Vec<DocComment<'a>>,
1109    /// The identifier of the world.
1110    pub id: Ident<'a>,
1111    /// The items of the world.
1112    pub items: Vec<WorldItem<'a>>,
1113}
1114
1115impl<'a> Parse<'a> for WorldDecl<'a> {
1116    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1117        let docs = Parse::parse(lexer)?;
1118        parse_token(lexer, Token::WorldKeyword)?;
1119        let id = Ident::parse(lexer)?;
1120        parse_token(lexer, Token::OpenBrace)?;
1121        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
1122        parse_token(lexer, Token::CloseBrace)?;
1123        Ok(Self { docs, id, items })
1124    }
1125}
1126
1127impl Peek for WorldDecl<'_> {
1128    fn peek(lookahead: &mut Lookahead) -> bool {
1129        lookahead.peek(Token::WorldKeyword)
1130    }
1131}
1132
1133/// Represents a world item in the AST.
1134#[derive(Debug, Clone, Serialize)]
1135#[serde(rename_all = "camelCase")]
1136pub enum WorldItem<'a> {
1137    /// The item is a use.
1138    Use(Use<'a>),
1139    /// The item is a type declaration.
1140    Type(ItemTypeDecl<'a>),
1141    /// The item is a world export.
1142    Import(WorldImport<'a>),
1143    /// The item is a world export.
1144    Export(WorldExport<'a>),
1145    /// The item is a world include.
1146    Include(WorldInclude<'a>),
1147}
1148
1149impl<'a> Parse<'a> for WorldItem<'a> {
1150    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1151        let mut lookahead = Lookahead::new(lexer);
1152        if Use::peek(&mut lookahead) {
1153            Ok(Self::Use(Parse::parse(lexer)?))
1154        } else if WorldImport::peek(&mut lookahead) {
1155            Ok(Self::Import(Parse::parse(lexer)?))
1156        } else if WorldExport::peek(&mut lookahead) {
1157            Ok(Self::Export(Parse::parse(lexer)?))
1158        } else if WorldInclude::peek(&mut lookahead) {
1159            Ok(Self::Include(Parse::parse(lexer)?))
1160        } else if ItemTypeDecl::peek(&mut lookahead) {
1161            Ok(Self::Type(Parse::parse(lexer)?))
1162        } else {
1163            Err(lookahead.error())
1164        }
1165    }
1166}
1167
1168impl Peek for WorldItem<'_> {
1169    fn peek(lookahead: &mut Lookahead) -> bool {
1170        Use::peek(lookahead)
1171            || WorldImport::peek(lookahead)
1172            || WorldExport::peek(lookahead)
1173            || WorldInclude::peek(lookahead)
1174            || ItemTypeDecl::peek(lookahead)
1175    }
1176}
1177
1178/// Represents a world import in the AST.
1179#[derive(Debug, Clone, Serialize)]
1180#[serde(rename_all = "camelCase")]
1181pub struct WorldImport<'a> {
1182    /// The doc comments for the world import.
1183    pub docs: Vec<DocComment<'a>>,
1184    /// The path of the imported item.
1185    pub path: WorldItemPath<'a>,
1186}
1187
1188impl<'a> Parse<'a> for WorldImport<'a> {
1189    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1190        let docs = Parse::parse(lexer)?;
1191        parse_token(lexer, Token::ImportKeyword)?;
1192        let path = Parse::parse(lexer)?;
1193        parse_token(lexer, Token::Semicolon)?;
1194        Ok(Self { docs, path })
1195    }
1196}
1197
1198impl Peek for WorldImport<'_> {
1199    fn peek(lookahead: &mut Lookahead) -> bool {
1200        lookahead.peek(Token::ImportKeyword)
1201    }
1202}
1203
1204/// Represents a world export in the AST.
1205#[derive(Debug, Clone, Serialize)]
1206#[serde(rename_all = "camelCase")]
1207pub struct WorldExport<'a> {
1208    /// The doc comments for the world export.
1209    pub docs: Vec<DocComment<'a>>,
1210    /// The path of the exported item.
1211    pub path: WorldItemPath<'a>,
1212}
1213
1214impl<'a> Parse<'a> for WorldExport<'a> {
1215    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1216        let docs = Parse::parse(lexer)?;
1217        parse_token(lexer, Token::ExportKeyword)?;
1218        let path = Parse::parse(lexer)?;
1219        parse_token(lexer, Token::Semicolon)?;
1220        Ok(Self { docs, path })
1221    }
1222}
1223
1224impl Peek for WorldExport<'_> {
1225    fn peek(lookahead: &mut Lookahead) -> bool {
1226        lookahead.peek(Token::ExportKeyword)
1227    }
1228}
1229
1230/// Represents a world item path in the AST.
1231#[derive(Debug, Clone, Serialize)]
1232#[serde(rename_all = "camelCase")]
1233pub enum WorldItemPath<'a> {
1234    /// The path is by name.
1235    Named(NamedWorldItem<'a>),
1236    /// The path is by a package path.
1237    Package(PackagePath<'a>),
1238    /// The path is by identifier.
1239    Ident(Ident<'a>),
1240}
1241
1242impl<'a> Parse<'a> for WorldItemPath<'a> {
1243    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1244        let mut lookahead = Lookahead::new(lexer);
1245        if PackagePath::peek(&mut lookahead) {
1246            Ok(Self::Package(Parse::parse(lexer)?))
1247        } else if Ident::peek(&mut lookahead) {
1248            // Peek again to see if this is a named item or an interface reference
1249            if let Some((Ok(Token::Colon), _)) = lexer.peek2() {
1250                Ok(Self::Named(Parse::parse(lexer)?))
1251            } else {
1252                Ok(Self::Ident(Parse::parse(lexer)?))
1253            }
1254        } else {
1255            Err(lookahead.error())
1256        }
1257    }
1258}
1259
1260/// Represents a named world item in the AST.
1261#[derive(Debug, Clone, Serialize)]
1262#[serde(rename_all = "camelCase")]
1263pub struct NamedWorldItem<'a> {
1264    /// The identifier of the item being imported or exported.
1265    pub id: Ident<'a>,
1266    /// The extern type of the item.
1267    pub ty: ExternType<'a>,
1268}
1269
1270impl<'a> Parse<'a> for NamedWorldItem<'a> {
1271    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1272        let id = Ident::parse(lexer)?;
1273        parse_token(lexer, Token::Colon)?;
1274        let ty = Parse::parse(lexer)?;
1275        Ok(Self { id, ty })
1276    }
1277}
1278
1279/// Represents the external type of a world item in the AST.
1280#[derive(Debug, Clone, Serialize)]
1281#[serde(rename_all = "camelCase")]
1282pub enum ExternType<'a> {
1283    /// The type is by identifier.
1284    Ident(Ident<'a>),
1285    /// The type is an inline function type.
1286    Func(FuncType<'a>),
1287    /// The type is an inline interface.
1288    Interface(InlineInterface<'a>),
1289}
1290
1291impl<'a> Parse<'a> for ExternType<'a> {
1292    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1293        let mut lookahead = Lookahead::new(lexer);
1294        if Ident::peek(&mut lookahead) {
1295            Ok(Self::Ident(Parse::parse(lexer)?))
1296        } else if FuncType::peek(&mut lookahead) {
1297            Ok(Self::Func(Parse::parse(lexer)?))
1298        } else if InlineInterface::peek(&mut lookahead) {
1299            Ok(Self::Interface(Parse::parse(lexer)?))
1300        } else {
1301            Err(lookahead.error())
1302        }
1303    }
1304}
1305
1306/// Represents an inline interface in the AST.
1307#[derive(Debug, Clone, Serialize)]
1308#[serde(rename_all = "camelCase")]
1309pub struct InlineInterface<'a> {
1310    /// The items of the interface.
1311    pub items: Vec<InterfaceItem<'a>>,
1312}
1313
1314impl<'a> Parse<'a> for InlineInterface<'a> {
1315    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1316        parse_token(lexer, Token::InterfaceKeyword)?;
1317        parse_token(lexer, Token::OpenBrace)?;
1318        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
1319        parse_token(lexer, Token::CloseBrace)?;
1320        Ok(Self { items })
1321    }
1322}
1323
1324impl Peek for InlineInterface<'_> {
1325    fn peek(lookahead: &mut Lookahead) -> bool {
1326        lookahead.peek(Token::InterfaceKeyword)
1327    }
1328}
1329
1330/// Represents a world include in the AST.
1331#[derive(Debug, Clone, Serialize)]
1332#[serde(rename_all = "camelCase")]
1333pub struct WorldInclude<'a> {
1334    /// The doc comments for the world include.
1335    pub docs: Vec<DocComment<'a>>,
1336    /// The reference to the world to include.
1337    pub world: WorldRef<'a>,
1338    /// The optional include-with items.
1339    pub with: Vec<WorldIncludeItem<'a>>,
1340}
1341
1342impl<'a> Parse<'a> for WorldInclude<'a> {
1343    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1344        let docs = Parse::parse(lexer)?;
1345        parse_token(lexer, Token::IncludeKeyword)?;
1346        let world = Parse::parse(lexer)?;
1347        let with = parse_optional(lexer, Token::WithKeyword, |lexer| {
1348            parse_token(lexer, Token::OpenBrace)?;
1349            let items = parse_delimited(lexer, Token::CloseBrace, true)?;
1350            parse_token(lexer, Token::CloseBrace)?;
1351            Ok(items)
1352        })?
1353        .unwrap_or_default();
1354        parse_token(lexer, Token::Semicolon)?;
1355        Ok(Self { docs, world, with })
1356    }
1357}
1358
1359impl Peek for WorldInclude<'_> {
1360    fn peek(lookahead: &mut Lookahead) -> bool {
1361        lookahead.peek(Token::IncludeKeyword)
1362    }
1363}
1364
1365/// Represents a reference to a world in the AST (local or foreign).
1366#[derive(Debug, Clone, Serialize)]
1367#[serde(rename_all = "camelCase")]
1368pub enum WorldRef<'a> {
1369    /// The reference is by identifier.
1370    Ident(Ident<'a>),
1371    /// The reference is by package path.
1372    Package(PackagePath<'a>),
1373}
1374
1375impl<'a> WorldRef<'a> {
1376    /// Gets the name of the world being referred to.
1377    pub fn name(&self) -> &'a str {
1378        match self {
1379            Self::Ident(id) => id.string,
1380            Self::Package(path) => path.string,
1381        }
1382    }
1383
1384    /// Gets the span of the world reference.
1385    pub fn span(&self) -> SourceSpan {
1386        match self {
1387            Self::Ident(id) => id.span,
1388            Self::Package(path) => path.span,
1389        }
1390    }
1391}
1392
1393impl<'a> Parse<'a> for WorldRef<'a> {
1394    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1395        let mut lookahead = Lookahead::new(lexer);
1396        if PackagePath::peek(&mut lookahead) {
1397            Ok(Self::Package(Parse::parse(lexer)?))
1398        } else if Ident::peek(&mut lookahead) {
1399            Ok(Self::Ident(Parse::parse(lexer)?))
1400        } else {
1401            Err(lookahead.error())
1402        }
1403    }
1404}
1405
1406/// Represents a renaming of an included name.
1407#[derive(Debug, Clone, Serialize)]
1408#[serde(rename_all = "camelCase")]
1409pub struct WorldIncludeItem<'a> {
1410    /// The `from` name for the included item.
1411    pub from: Ident<'a>,
1412    /// The `to` name for the included item.
1413    pub to: Ident<'a>,
1414}
1415
1416impl<'a> Parse<'a> for WorldIncludeItem<'a> {
1417    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1418        let from = Ident::parse(lexer)?;
1419        parse_token(lexer, Token::AsKeyword)?;
1420        let to = Ident::parse(lexer)?;
1421        Ok(Self { from, to })
1422    }
1423}
1424
1425impl Peek for WorldIncludeItem<'_> {
1426    fn peek(lookahead: &mut Lookahead) -> bool {
1427        Ident::peek(lookahead)
1428    }
1429}
1430
1431#[cfg(test)]
1432mod test {
1433    use crate::ast::test::roundtrip;
1434
1435    #[test]
1436    fn resource_roundtrip() {
1437        roundtrip(
1438            r#"package foo:bar;
1439interface i { resource foo-bar {
1440    /** A constructor */
1441    constructor(foo: u8, bar: u8);
1442    /// A method
1443    foo: func() -> string;
1444    /// A method
1445    set-foo: func(foo: string);
1446    /// A static method
1447    id: static func() -> u32;
1448}}"#,
1449            r#"package foo:bar;
1450
1451interface i {
1452    resource foo-bar {
1453        /// A constructor
1454        constructor(foo: u8, bar: u8);
1455
1456        /// A method
1457        foo: func() -> string;
1458
1459        /// A method
1460        set-foo: func(foo: string);
1461
1462        /// A static method
1463        id: static func() -> u32;
1464    }
1465}
1466"#,
1467        )
1468        .unwrap();
1469    }
1470
1471    #[test]
1472    fn variant_roundtrip() {
1473        roundtrip(
1474            r#"package foo:bar;
1475variant foo {
1476    foo,
1477    bar(u32),
1478    baz(bar),
1479    qux(tuple<u8, u16, u32>)
1480}"#,
1481            r#"package foo:bar;
1482
1483variant foo {
1484    foo,
1485    bar(u32),
1486    baz(bar),
1487    qux(tuple<u8, u16, u32>),
1488}
1489"#,
1490        )
1491        .unwrap();
1492    }
1493
1494    #[test]
1495    fn record_roundtrip() {
1496        roundtrip(
1497            r#"package foo:bar;
1498record foo-bar2-baz {
1499    foo: foo,
1500    bar-qux: list<string>,
1501    // A comment
1502    jam: borrow<foo>,
1503}"#,
1504            r#"package foo:bar;
1505
1506record foo-bar2-baz {
1507    foo: foo,
1508    bar-qux: list<string>,
1509    jam: borrow<foo>,
1510}
1511"#,
1512        )
1513        .unwrap();
1514    }
1515
1516    #[test]
1517    fn flags_roundtrip() {
1518        roundtrip(
1519            r#"package foo:bar;
1520flags %flags {
1521    foo, bar, baz
1522}"#,
1523            r#"package foo:bar;
1524
1525flags %flags {
1526    foo,
1527    bar,
1528    baz,
1529}
1530"#,
1531        )
1532        .unwrap();
1533    }
1534
1535    #[test]
1536    fn enum_roundtrip() {
1537        roundtrip(
1538            r#"package foo:bar; enum foo {
1539    foo, bar, baz
1540}"#,
1541            r#"package foo:bar;
1542
1543enum foo {
1544    foo,
1545    bar,
1546    baz,
1547}
1548"#,
1549        )
1550        .unwrap();
1551    }
1552
1553    #[test]
1554    fn func_type_alias_roundtrip() {
1555        roundtrip(
1556            r#"package foo:bar; type x = func(a: /* comment */ string) -> string;"#,
1557            "package foo:bar;\n\ntype x = func(a: string) -> string;\n",
1558        )
1559        .unwrap();
1560    }
1561
1562    #[test]
1563    fn type_alias_roundtrip() {
1564        roundtrip(
1565            r#"package foo:bar; type x = tuple<u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, char, bool, string, tuple<string, list<u8>>, option<list<bool>>, result, result<string>, result<_, string>, result<u8, u8>, borrow<y>, y>;"#,
1566            "package foo:bar;\n\ntype x = tuple<u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, char, bool, string, tuple<string, list<u8>>, option<list<bool>>, result, result<string>, result<_, string>, result<u8, u8>, borrow<y>, y>;\n",
1567        )
1568        .unwrap();
1569    }
1570
1571    #[test]
1572    fn interface_roundtrip() {
1573        roundtrip(
1574            r#"package foo:bar;
1575
1576interface foo {
1577    /// Type t
1578    type t = list<string>;
1579
1580    /// Use x and y
1581    use foo.{ x, y, };
1582
1583    /// Function a
1584    a: func(a: string, b: string) -> string;
1585
1586    // not a doc comment
1587    type x = func() -> list<string>;
1588
1589    /// Function b
1590    b: x;
1591}
1592            "#,
1593            r#"package foo:bar;
1594
1595interface foo {
1596    /// Type t
1597    type t = list<string>;
1598
1599    /// Use x and y
1600    use foo.{ x, y };
1601
1602    /// Function a
1603    a: func(a: string, b: string) -> string;
1604
1605    type x = func() -> list<string>;
1606
1607    /// Function b
1608    b: x;
1609}
1610"#,
1611        )
1612        .unwrap();
1613    }
1614
1615    #[test]
1616    fn world_roundtrip() {
1617        roundtrip(
1618            r#"package foo:bar;
1619
1620world foo {
1621    /// Type t
1622    type t = list<string>;
1623
1624    // not a doc comment
1625    type x = func() -> list<string>;
1626
1627    use foo.{ y, };
1628
1629    /// Import with function type.
1630    import a: func(a: string, b: string) -> string;
1631
1632    /// Import with identifier.
1633    import b: x;
1634
1635    /// Import with inline interface.
1636    import c: interface {
1637        /// Function a
1638        a: func(a: string, b: string) -> string;
1639    };
1640
1641    /// Import with package path
1642    import foo:bar/baz@1.0.0;
1643
1644    /// Export with function type.
1645    export a: func(a: string, b: string) -> string;
1646
1647    /// Export with identifier.
1648    export b: x;
1649
1650    /// Export with inline interface.
1651    export c: interface {
1652        /// Function a
1653        a: func(a: string, b: string) -> string;
1654    };
1655
1656    /// Export with package path
1657    export foo:bar/baz@1.0.0;
1658
1659    /// Include world from package path with 2 renames.
1660    include foo:bar/baz with { a as a1, b as b1 };
1661
1662    /// Include world from package path with 1 rename.
1663    include foo:bar/baz with {foo as foo1};
1664
1665    /// Include world from package path (spacing).
1666    include foo:bar/baz with { foo as foo1 };
1667
1668    /// Include world from package path newline delimited renaming.
1669    include foo:bar/baz with {
1670        foo as foo1,
1671        bar as bar1
1672    };
1673
1674    /// Include local world.
1675    include foo-bar;
1676
1677    /// Include local world with renaming.
1678    include foo-bar with { foo as bar };
1679}"#,
1680            r#"package foo:bar;
1681
1682world foo {
1683    /// Type t
1684    type t = list<string>;
1685
1686    type x = func() -> list<string>;
1687
1688    use foo.{ y };
1689
1690    /// Import with function type.
1691    import a: func(a: string, b: string) -> string;
1692
1693    /// Import with identifier.
1694    import b: x;
1695
1696    /// Import with inline interface.
1697    import c: interface {
1698        /// Function a
1699        a: func(a: string, b: string) -> string;
1700    };
1701
1702    /// Import with package path
1703    import foo:bar/baz@1.0.0;
1704
1705    /// Export with function type.
1706    export a: func(a: string, b: string) -> string;
1707
1708    /// Export with identifier.
1709    export b: x;
1710
1711    /// Export with inline interface.
1712    export c: interface {
1713        /// Function a
1714        a: func(a: string, b: string) -> string;
1715    };
1716
1717    /// Export with package path
1718    export foo:bar/baz@1.0.0;
1719
1720    /// Include world from package path with 2 renames.
1721    include foo:bar/baz with {
1722        a as a1,
1723        b as b1,
1724    };
1725
1726    /// Include world from package path with 1 rename.
1727    include foo:bar/baz with {
1728        foo as foo1,
1729    };
1730
1731    /// Include world from package path (spacing).
1732    include foo:bar/baz with {
1733        foo as foo1,
1734    };
1735
1736    /// Include world from package path newline delimited renaming.
1737    include foo:bar/baz with {
1738        foo as foo1,
1739        bar as bar1,
1740    };
1741
1742    /// Include local world.
1743    include foo-bar;
1744
1745    /// Include local world with renaming.
1746    include foo-bar with {
1747        foo as bar,
1748    };
1749}
1750"#,
1751        )
1752        .unwrap();
1753    }
1754}