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}
533
534impl<'a> Parse<'a> for ResultList<'a> {
535    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
536        let mut lookahead = Lookahead::new(lexer);
537        if Type::peek(&mut lookahead) {
538            Ok(Self::Scalar(Parse::parse(lexer)?))
539        } else {
540            Ok(Self::Empty)
541        }
542    }
543}
544
545/// Represents a name and an associated type in the AST.
546#[derive(Debug, Clone, Serialize)]
547#[serde(rename_all = "camelCase")]
548pub struct NamedType<'a> {
549    /// The identifier of the type.
550    pub id: Ident<'a>,
551    /// The type.
552    pub ty: Type<'a>,
553}
554
555impl<'a> Parse<'a> for NamedType<'a> {
556    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
557        let id = Ident::parse(lexer)?;
558        parse_token(lexer, Token::Colon)?;
559        let ty = Parse::parse(lexer)?;
560        Ok(Self { id, ty })
561    }
562}
563
564impl Peek for NamedType<'_> {
565    fn peek(lookahead: &mut Lookahead) -> bool {
566        Ident::peek(lookahead)
567    }
568}
569
570/// Represents a type alias in the AST.
571#[derive(Debug, Clone, Serialize)]
572#[serde(rename_all = "camelCase")]
573pub struct TypeAlias<'a> {
574    /// The docs for the type alias.
575    pub docs: Vec<DocComment<'a>>,
576    /// The identifier of the type alias.
577    pub id: Ident<'a>,
578    /// The kind of type alias.
579    pub kind: TypeAliasKind<'a>,
580}
581
582impl<'a> Parse<'a> for TypeAlias<'a> {
583    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
584        let docs = Parse::parse(lexer)?;
585        parse_token(lexer, Token::TypeKeyword)?;
586        let id = Ident::parse(lexer)?;
587        parse_token(lexer, Token::Equals)?;
588        let kind = Parse::parse(lexer)?;
589        parse_token(lexer, Token::Semicolon)?;
590        Ok(Self { docs, id, kind })
591    }
592}
593
594/// Represents a type alias kind in the AST.
595#[derive(Debug, Clone, Serialize)]
596#[serde(rename_all = "camelCase")]
597pub enum TypeAliasKind<'a> {
598    /// The alias is to a function type.
599    Func(FuncType<'a>),
600    /// The alias is to another type.
601    Type(Type<'a>),
602}
603
604impl<'a> Parse<'a> for TypeAliasKind<'a> {
605    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
606        let mut lookahead = Lookahead::new(lexer);
607        if lookahead.peek(Token::FuncKeyword) {
608            Ok(Self::Func(Parse::parse(lexer)?))
609        } else if Type::peek(&mut lookahead) {
610            Ok(Self::Type(Parse::parse(lexer)?))
611        } else {
612            Err(lookahead.error())
613        }
614    }
615}
616
617/// Represents a type in the AST.
618#[derive(Debug, Clone, Serialize)]
619#[serde(rename_all = "camelCase")]
620pub enum Type<'a> {
621    /// A `u8` type.
622    U8(SourceSpan),
623    /// A `s8` type.
624    S8(SourceSpan),
625    /// A `u16` type.
626    U16(SourceSpan),
627    /// A `s16` type.
628    S16(SourceSpan),
629    /// A `u32` type.
630    U32(SourceSpan),
631    /// A `s32` type.
632    S32(SourceSpan),
633    /// A `u64` type.
634    U64(SourceSpan),
635    /// A `s64` type.
636    S64(SourceSpan),
637    /// A `f32` type.
638    F32(SourceSpan),
639    /// A `f64` type.
640    F64(SourceSpan),
641    /// A `char` type.
642    Char(SourceSpan),
643    /// A `bool` type.
644    Bool(SourceSpan),
645    /// A `string` type.
646    String(SourceSpan),
647    /// A tuple type.
648    Tuple(Vec<Type<'a>>, SourceSpan),
649    /// A list type.
650    List(Box<Type<'a>>, SourceSpan),
651    /// An option type.
652    Option(Box<Type<'a>>, SourceSpan),
653    /// A result type.
654    Result {
655        /// The `ok` of the result type.
656        ok: Option<Box<Type<'a>>>,
657        /// The `err` of the result type.
658        err: Option<Box<Type<'a>>>,
659        /// The span of the result type.
660        span: SourceSpan,
661    },
662    /// A borrow type.
663    Borrow(Ident<'a>, SourceSpan),
664    /// An identifier to a value type.
665    Ident(Ident<'a>),
666}
667
668impl Type<'_> {
669    /// Gets the span of the type.
670    pub fn span(&self) -> SourceSpan {
671        match self {
672            Self::U8(span)
673            | Self::S8(span)
674            | Self::U16(span)
675            | Self::S16(span)
676            | Self::U32(span)
677            | Self::S32(span)
678            | Self::U64(span)
679            | Self::S64(span)
680            | Self::F32(span)
681            | Self::F64(span)
682            | Self::Char(span)
683            | Self::Bool(span)
684            | Self::String(span)
685            | Self::Tuple(_, span)
686            | Self::List(_, span)
687            | Self::Option(_, span)
688            | Self::Result { span, .. }
689            | Self::Borrow(_, span) => *span,
690            Self::Ident(ident) => ident.span,
691        }
692    }
693}
694
695impl<'a> Parse<'a> for Type<'a> {
696    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
697        let mut lookahead = Lookahead::new(lexer);
698        if lookahead.peek(Token::U8Keyword) {
699            Ok(Self::U8(lexer.next().unwrap().1))
700        } else if lookahead.peek(Token::S8Keyword) {
701            Ok(Self::S8(lexer.next().unwrap().1))
702        } else if lookahead.peek(Token::U16Keyword) {
703            Ok(Self::U16(lexer.next().unwrap().1))
704        } else if lookahead.peek(Token::S16Keyword) {
705            Ok(Self::S16(lexer.next().unwrap().1))
706        } else if lookahead.peek(Token::U32Keyword) {
707            Ok(Self::U32(lexer.next().unwrap().1))
708        } else if lookahead.peek(Token::S32Keyword) {
709            Ok(Self::S32(lexer.next().unwrap().1))
710        } else if lookahead.peek(Token::U64Keyword) {
711            Ok(Self::U64(lexer.next().unwrap().1))
712        } else if lookahead.peek(Token::S64Keyword) {
713            Ok(Self::S64(lexer.next().unwrap().1))
714        } else if lookahead.peek(Token::F32Keyword) {
715            Ok(Self::F32(lexer.next().unwrap().1))
716        } else if lookahead.peek(Token::F64Keyword) {
717            Ok(Self::F64(lexer.next().unwrap().1))
718        } else if lookahead.peek(Token::CharKeyword) {
719            Ok(Self::Char(lexer.next().unwrap().1))
720        } else if lookahead.peek(Token::BoolKeyword) {
721            Ok(Self::Bool(lexer.next().unwrap().1))
722        } else if lookahead.peek(Token::StringKeyword) {
723            Ok(Self::String(lexer.next().unwrap().1))
724        } else if lookahead.peek(Token::TupleKeyword) {
725            let span = lexer.next().unwrap().1;
726            parse_token(lexer, Token::OpenAngle)?;
727
728            // There must be at least one type in the tuple.
729            let mut lookahead = Lookahead::new(lexer);
730            if !Type::peek(&mut lookahead) {
731                return Err(lookahead.error());
732            }
733
734            let types = parse_delimited(lexer, Token::CloseAngle, true)?;
735            assert!(!types.is_empty());
736            let close = parse_token(lexer, Token::CloseAngle)?;
737            Ok(Self::Tuple(
738                types,
739                SourceSpan::new(
740                    span.offset().into(),
741                    (close.offset() + close.len()) - span.offset(),
742                ),
743            ))
744        } else if lookahead.peek(Token::ListKeyword) {
745            let span = lexer.next().unwrap().1;
746            parse_token(lexer, Token::OpenAngle)?;
747            let ty = Box::new(Parse::parse(lexer)?);
748            let close = parse_token(lexer, Token::CloseAngle)?;
749            Ok(Self::List(
750                ty,
751                SourceSpan::new(
752                    span.offset().into(),
753                    (close.offset() + close.len()) - span.offset(),
754                ),
755            ))
756        } else if lookahead.peek(Token::OptionKeyword) {
757            let span = lexer.next().unwrap().1;
758            parse_token(lexer, Token::OpenAngle)?;
759            let ty = Box::new(Parse::parse(lexer)?);
760            let close = parse_token(lexer, Token::CloseAngle)?;
761            Ok(Self::Option(
762                ty,
763                SourceSpan::new(
764                    span.offset().into(),
765                    (close.offset() + close.len()) - span.offset(),
766                ),
767            ))
768        } else if lookahead.peek(Token::ResultKeyword) {
769            let mut span = lexer.next().unwrap().1;
770
771            let parse = |lexer: &mut Lexer<'a>| {
772                let mut lookahead = Lookahead::new(lexer);
773                let ok = if lookahead.peek(Token::Underscore) {
774                    lexer.next();
775                    None
776                } else if Type::peek(&mut lookahead) {
777                    Some(Box::new(Parse::parse(lexer)?))
778                } else {
779                    return Err(lookahead.error());
780                };
781
782                let err = parse_optional(lexer, Token::Comma, |lexer| {
783                    let mut lookahead = Lookahead::new(lexer);
784                    if lookahead.peek(Token::Underscore) {
785                        lexer.next();
786                        Ok(None)
787                    } else if Type::peek(&mut lookahead) {
788                        Ok(Some(Box::new(Parse::parse(lexer)?)))
789                    } else {
790                        return Err(lookahead.error());
791                    }
792                })?
793                .unwrap_or(None);
794
795                let close = parse_token(lexer, Token::CloseAngle)?;
796                span = SourceSpan::new(
797                    span.offset().into(),
798                    (close.offset() + close.len()) - span.offset(),
799                );
800                Ok((ok, err))
801            };
802
803            let (ok, err) = match parse_optional(lexer, Token::OpenAngle, parse)? {
804                Some((ok, err)) => (ok, err),
805                None => (None, None),
806            };
807            Ok(Self::Result { ok, err, span })
808        } else if lookahead.peek(Token::BorrowKeyword) {
809            let span = lexer.next().unwrap().1;
810            parse_token(lexer, Token::OpenAngle)?;
811            let id = Parse::parse(lexer)?;
812            let close = parse_token(lexer, Token::CloseAngle)?;
813            Ok(Self::Borrow(
814                id,
815                SourceSpan::new(
816                    span.offset().into(),
817                    (close.offset() + close.len()) - span.offset(),
818                ),
819            ))
820        } else if Ident::peek(&mut lookahead) {
821            Ok(Self::Ident(Parse::parse(lexer)?))
822        } else {
823            Err(lookahead.error())
824        }
825    }
826}
827
828impl Peek for Type<'_> {
829    fn peek(lookahead: &mut Lookahead) -> bool {
830        lookahead.peek(Token::U8Keyword)
831            || lookahead.peek(Token::S8Keyword)
832            || lookahead.peek(Token::U16Keyword)
833            || lookahead.peek(Token::S16Keyword)
834            || lookahead.peek(Token::U32Keyword)
835            || lookahead.peek(Token::S32Keyword)
836            || lookahead.peek(Token::U64Keyword)
837            || lookahead.peek(Token::S64Keyword)
838            || lookahead.peek(Token::F32Keyword)
839            || lookahead.peek(Token::F64Keyword)
840            || lookahead.peek(Token::CharKeyword)
841            || lookahead.peek(Token::BoolKeyword)
842            || lookahead.peek(Token::StringKeyword)
843            || lookahead.peek(Token::TupleKeyword)
844            || lookahead.peek(Token::ListKeyword)
845            || lookahead.peek(Token::OptionKeyword)
846            || lookahead.peek(Token::ResultKeyword)
847            || lookahead.peek(Token::BorrowKeyword)
848            || Ident::peek(lookahead)
849    }
850}
851
852/// Represents an interface or world type declaration in the AST.
853///
854/// Unlike top-level type declarations, interfaces and worlds can
855/// also declare resources.
856#[derive(Debug, Clone, Serialize)]
857#[serde(rename_all = "camelCase")]
858pub enum ItemTypeDecl<'a> {
859    /// The declaration is for a resource.
860    Resource(ResourceDecl<'a>),
861    /// The declaration is for a variant.
862    Variant(VariantDecl<'a>),
863    /// The declaration is for a record.
864    Record(RecordDecl<'a>),
865    /// The declaration is for a flags.
866    Flags(FlagsDecl<'a>),
867    /// The declaration is for an enum.
868    Enum(EnumDecl<'a>),
869    /// The declaration is for a type alias.
870    Alias(TypeAlias<'a>),
871}
872
873impl<'a> Parse<'a> for ItemTypeDecl<'a> {
874    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
875        let mut lookahead = Lookahead::new(lexer);
876        if lookahead.peek(Token::ResourceKeyword) {
877            Ok(Self::Resource(Parse::parse(lexer)?))
878        } else if lookahead.peek(Token::VariantKeyword) {
879            Ok(Self::Variant(Parse::parse(lexer)?))
880        } else if lookahead.peek(Token::RecordKeyword) {
881            Ok(Self::Record(Parse::parse(lexer)?))
882        } else if lookahead.peek(Token::FlagsKeyword) {
883            Ok(Self::Flags(Parse::parse(lexer)?))
884        } else if lookahead.peek(Token::EnumKeyword) {
885            Ok(Self::Enum(Parse::parse(lexer)?))
886        } else if lookahead.peek(Token::TypeKeyword) {
887            Ok(Self::Alias(Parse::parse(lexer)?))
888        } else {
889            Err(lookahead.error())
890        }
891    }
892}
893
894impl Peek for ItemTypeDecl<'_> {
895    fn peek(lookahead: &mut Lookahead) -> bool {
896        lookahead.peek(Token::ResourceKeyword)
897            || lookahead.peek(Token::VariantKeyword)
898            || lookahead.peek(Token::RecordKeyword)
899            || lookahead.peek(Token::FlagsKeyword)
900            || lookahead.peek(Token::EnumKeyword)
901            || lookahead.peek(Token::TypeKeyword)
902    }
903}
904
905impl ItemTypeDecl<'_> {
906    /// Gets the identifier of the type being declared.
907    pub fn id(&self) -> &Ident {
908        match self {
909            Self::Resource(resource) => &resource.id,
910            Self::Variant(variant) => &variant.id,
911            Self::Record(record) => &record.id,
912            Self::Flags(flags) => &flags.id,
913            Self::Enum(e) => &e.id,
914            Self::Alias(alias) => &alias.id,
915        }
916    }
917}
918
919/// Represents an interface declaration in the AST.
920#[derive(Debug, Clone, Serialize)]
921#[serde(rename_all = "camelCase")]
922pub struct InterfaceDecl<'a> {
923    /// The doc comments for the interface.
924    pub docs: Vec<DocComment<'a>>,
925    /// The identifier of the interface.
926    pub id: Ident<'a>,
927    /// The items of the interface.
928    pub items: Vec<InterfaceItem<'a>>,
929}
930
931impl<'a> Parse<'a> for InterfaceDecl<'a> {
932    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
933        let docs = Parse::parse(lexer)?;
934        parse_token(lexer, Token::InterfaceKeyword)?;
935        let id = Ident::parse(lexer)?;
936        parse_token(lexer, Token::OpenBrace)?;
937        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
938        parse_token(lexer, Token::CloseBrace)?;
939        Ok(Self { docs, id, items })
940    }
941}
942
943impl Peek for InterfaceDecl<'_> {
944    fn peek(lookahead: &mut Lookahead) -> bool {
945        lookahead.peek(Token::InterfaceKeyword)
946    }
947}
948
949/// Represents an interface item in the AST.
950#[derive(Debug, Clone, Serialize)]
951#[serde(rename_all = "camelCase")]
952pub enum InterfaceItem<'a> {
953    /// The item is a use of other types.
954    Use(Box<Use<'a>>),
955    /// The item is a type declaration.
956    Type(ItemTypeDecl<'a>),
957    /// The item is an interface export.
958    Export(InterfaceExport<'a>),
959}
960
961impl<'a> Parse<'a> for InterfaceItem<'a> {
962    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
963        let mut lookahead = Lookahead::new(lexer);
964        if Use::peek(&mut lookahead) {
965            Ok(Self::Use(Box::new(Parse::parse(lexer)?)))
966        } else if InterfaceExport::peek(&mut lookahead) {
967            Ok(Self::Export(Parse::parse(lexer)?))
968        } else if ItemTypeDecl::peek(&mut lookahead) {
969            Ok(Self::Type(Parse::parse(lexer)?))
970        } else {
971            Err(lookahead.error())
972        }
973    }
974}
975
976impl Peek for InterfaceItem<'_> {
977    fn peek(lookahead: &mut Lookahead) -> bool {
978        Use::peek(lookahead) || InterfaceExport::peek(lookahead) || ItemTypeDecl::peek(lookahead)
979    }
980}
981
982/// Represents a "use" in the AST.
983#[derive(Debug, Clone, Serialize)]
984#[serde(rename_all = "camelCase")]
985pub struct Use<'a> {
986    /// The doc comments for the use.
987    pub docs: Vec<DocComment<'a>>,
988    /// The path to the interface or world being used.
989    pub path: UsePath<'a>,
990    /// The items being used.
991    pub items: Vec<UseItem<'a>>,
992}
993
994impl<'a> Parse<'a> for Use<'a> {
995    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
996        let docs = Parse::parse(lexer)?;
997        parse_token(lexer, Token::UseKeyword)?;
998        let path = Parse::parse(lexer)?;
999        parse_token(lexer, Token::Dot)?;
1000        parse_token(lexer, Token::OpenBrace)?;
1001        let items = parse_delimited(lexer, Token::CloseBrace, true)?;
1002        parse_token(lexer, Token::CloseBrace)?;
1003        parse_token(lexer, Token::Semicolon)?;
1004        Ok(Self { docs, path, items })
1005    }
1006}
1007
1008impl Peek for Use<'_> {
1009    fn peek(lookahead: &mut Lookahead) -> bool {
1010        lookahead.peek(Token::UseKeyword)
1011    }
1012}
1013
1014/// Represents a use path in the AST.
1015#[derive(Debug, Clone, Serialize)]
1016#[serde(rename_all = "camelCase")]
1017pub enum UsePath<'a> {
1018    /// The path is a package path.
1019    Package(PackagePath<'a>),
1020    /// The path is an identifier.
1021    Ident(Ident<'a>),
1022}
1023
1024impl<'a> Parse<'a> for UsePath<'a> {
1025    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1026        let mut lookahead = Lookahead::new(lexer);
1027        if PackagePath::peek(&mut lookahead) {
1028            Ok(Self::Package(Parse::parse(lexer)?))
1029        } else if Ident::peek(&mut lookahead) {
1030            Ok(Self::Ident(Parse::parse(lexer)?))
1031        } else {
1032            Err(lookahead.error())
1033        }
1034    }
1035}
1036
1037impl Peek for UsePath<'_> {
1038    fn peek(lookahead: &mut Lookahead) -> bool {
1039        PackagePath::peek(lookahead) | Ident::peek(lookahead)
1040    }
1041}
1042
1043/// Represents a use item in the AST.
1044#[derive(Debug, Clone, Serialize)]
1045#[serde(rename_all = "camelCase")]
1046pub struct UseItem<'a> {
1047    /// The identifier of the item.
1048    pub id: Ident<'a>,
1049    /// The optional `as` identifier of the item.
1050    pub as_id: Option<Ident<'a>>,
1051}
1052
1053impl<'a> Parse<'a> for UseItem<'a> {
1054    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1055        let id = Ident::parse(lexer)?;
1056        let as_id = parse_optional(lexer, Token::AsKeyword, Ident::parse)?;
1057        Ok(Self { id, as_id })
1058    }
1059}
1060
1061impl Peek for UseItem<'_> {
1062    fn peek(lookahead: &mut Lookahead) -> bool {
1063        Ident::peek(lookahead)
1064    }
1065}
1066
1067/// Represents an interface export in the AST.
1068#[derive(Debug, Clone, Serialize)]
1069#[serde(rename_all = "camelCase")]
1070pub struct InterfaceExport<'a> {
1071    /// The doc comments for the export.
1072    pub docs: Vec<DocComment<'a>>,
1073    /// The identifier of the export.
1074    pub id: Ident<'a>,
1075    /// The type of the export.
1076    pub ty: FuncTypeRef<'a>,
1077}
1078
1079impl<'a> Parse<'a> for InterfaceExport<'a> {
1080    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1081        let docs = Parse::parse(lexer)?;
1082        let id = Ident::parse(lexer)?;
1083        parse_token(lexer, Token::Colon)?;
1084        let ty = Parse::parse(lexer)?;
1085        parse_token(lexer, Token::Semicolon)?;
1086        Ok(Self { docs, id, ty })
1087    }
1088}
1089
1090impl Peek for InterfaceExport<'_> {
1091    fn peek(lookahead: &mut Lookahead) -> bool {
1092        Ident::peek(lookahead)
1093    }
1094}
1095
1096/// Represents a world declaration in the AST.
1097#[derive(Debug, Clone, Serialize)]
1098#[serde(rename_all = "camelCase")]
1099pub struct WorldDecl<'a> {
1100    /// The doc comments for the world.
1101    pub docs: Vec<DocComment<'a>>,
1102    /// The identifier of the world.
1103    pub id: Ident<'a>,
1104    /// The items of the world.
1105    pub items: Vec<WorldItem<'a>>,
1106}
1107
1108impl<'a> Parse<'a> for WorldDecl<'a> {
1109    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1110        let docs = Parse::parse(lexer)?;
1111        parse_token(lexer, Token::WorldKeyword)?;
1112        let id = Ident::parse(lexer)?;
1113        parse_token(lexer, Token::OpenBrace)?;
1114        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
1115        parse_token(lexer, Token::CloseBrace)?;
1116        Ok(Self { docs, id, items })
1117    }
1118}
1119
1120impl Peek for WorldDecl<'_> {
1121    fn peek(lookahead: &mut Lookahead) -> bool {
1122        lookahead.peek(Token::WorldKeyword)
1123    }
1124}
1125
1126/// Represents a world item in the AST.
1127#[derive(Debug, Clone, Serialize)]
1128#[serde(rename_all = "camelCase")]
1129pub enum WorldItem<'a> {
1130    /// The item is a use.
1131    Use(Use<'a>),
1132    /// The item is a type declaration.
1133    Type(ItemTypeDecl<'a>),
1134    /// The item is a world export.
1135    Import(WorldImport<'a>),
1136    /// The item is a world export.
1137    Export(WorldExport<'a>),
1138    /// The item is a world include.
1139    Include(WorldInclude<'a>),
1140}
1141
1142impl<'a> Parse<'a> for WorldItem<'a> {
1143    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1144        let mut lookahead = Lookahead::new(lexer);
1145        if Use::peek(&mut lookahead) {
1146            Ok(Self::Use(Parse::parse(lexer)?))
1147        } else if WorldImport::peek(&mut lookahead) {
1148            Ok(Self::Import(Parse::parse(lexer)?))
1149        } else if WorldExport::peek(&mut lookahead) {
1150            Ok(Self::Export(Parse::parse(lexer)?))
1151        } else if WorldInclude::peek(&mut lookahead) {
1152            Ok(Self::Include(Parse::parse(lexer)?))
1153        } else if ItemTypeDecl::peek(&mut lookahead) {
1154            Ok(Self::Type(Parse::parse(lexer)?))
1155        } else {
1156            Err(lookahead.error())
1157        }
1158    }
1159}
1160
1161impl Peek for WorldItem<'_> {
1162    fn peek(lookahead: &mut Lookahead) -> bool {
1163        Use::peek(lookahead)
1164            || WorldImport::peek(lookahead)
1165            || WorldExport::peek(lookahead)
1166            || WorldInclude::peek(lookahead)
1167            || ItemTypeDecl::peek(lookahead)
1168    }
1169}
1170
1171/// Represents a world import in the AST.
1172#[derive(Debug, Clone, Serialize)]
1173#[serde(rename_all = "camelCase")]
1174pub struct WorldImport<'a> {
1175    /// The doc comments for the world import.
1176    pub docs: Vec<DocComment<'a>>,
1177    /// The path of the imported item.
1178    pub path: WorldItemPath<'a>,
1179}
1180
1181impl<'a> Parse<'a> for WorldImport<'a> {
1182    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1183        let docs = Parse::parse(lexer)?;
1184        parse_token(lexer, Token::ImportKeyword)?;
1185        let path = Parse::parse(lexer)?;
1186        parse_token(lexer, Token::Semicolon)?;
1187        Ok(Self { docs, path })
1188    }
1189}
1190
1191impl Peek for WorldImport<'_> {
1192    fn peek(lookahead: &mut Lookahead) -> bool {
1193        lookahead.peek(Token::ImportKeyword)
1194    }
1195}
1196
1197/// Represents a world export in the AST.
1198#[derive(Debug, Clone, Serialize)]
1199#[serde(rename_all = "camelCase")]
1200pub struct WorldExport<'a> {
1201    /// The doc comments for the world export.
1202    pub docs: Vec<DocComment<'a>>,
1203    /// The path of the exported item.
1204    pub path: WorldItemPath<'a>,
1205}
1206
1207impl<'a> Parse<'a> for WorldExport<'a> {
1208    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1209        let docs = Parse::parse(lexer)?;
1210        parse_token(lexer, Token::ExportKeyword)?;
1211        let path = Parse::parse(lexer)?;
1212        parse_token(lexer, Token::Semicolon)?;
1213        Ok(Self { docs, path })
1214    }
1215}
1216
1217impl Peek for WorldExport<'_> {
1218    fn peek(lookahead: &mut Lookahead) -> bool {
1219        lookahead.peek(Token::ExportKeyword)
1220    }
1221}
1222
1223/// Represents a world item path in the AST.
1224#[derive(Debug, Clone, Serialize)]
1225#[serde(rename_all = "camelCase")]
1226pub enum WorldItemPath<'a> {
1227    /// The path is by name.
1228    Named(NamedWorldItem<'a>),
1229    /// The path is by a package path.
1230    Package(PackagePath<'a>),
1231    /// The path is by identifier.
1232    Ident(Ident<'a>),
1233}
1234
1235impl<'a> Parse<'a> for WorldItemPath<'a> {
1236    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1237        let mut lookahead = Lookahead::new(lexer);
1238        if PackagePath::peek(&mut lookahead) {
1239            Ok(Self::Package(Parse::parse(lexer)?))
1240        } else if Ident::peek(&mut lookahead) {
1241            // Peek again to see if this is a named item or an interface reference
1242            if let Some((Ok(Token::Colon), _)) = lexer.peek2() {
1243                Ok(Self::Named(Parse::parse(lexer)?))
1244            } else {
1245                Ok(Self::Ident(Parse::parse(lexer)?))
1246            }
1247        } else {
1248            Err(lookahead.error())
1249        }
1250    }
1251}
1252
1253/// Represents a named world item in the AST.
1254#[derive(Debug, Clone, Serialize)]
1255#[serde(rename_all = "camelCase")]
1256pub struct NamedWorldItem<'a> {
1257    /// The identifier of the item being imported or exported.
1258    pub id: Ident<'a>,
1259    /// The extern type of the item.
1260    pub ty: ExternType<'a>,
1261}
1262
1263impl<'a> Parse<'a> for NamedWorldItem<'a> {
1264    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1265        let id = Ident::parse(lexer)?;
1266        parse_token(lexer, Token::Colon)?;
1267        let ty = Parse::parse(lexer)?;
1268        Ok(Self { id, ty })
1269    }
1270}
1271
1272/// Represents the external type of a world item in the AST.
1273#[derive(Debug, Clone, Serialize)]
1274#[serde(rename_all = "camelCase")]
1275pub enum ExternType<'a> {
1276    /// The type is by identifier.
1277    Ident(Ident<'a>),
1278    /// The type is an inline function type.
1279    Func(FuncType<'a>),
1280    /// The type is an inline interface.
1281    Interface(InlineInterface<'a>),
1282}
1283
1284impl<'a> Parse<'a> for ExternType<'a> {
1285    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1286        let mut lookahead = Lookahead::new(lexer);
1287        if Ident::peek(&mut lookahead) {
1288            Ok(Self::Ident(Parse::parse(lexer)?))
1289        } else if FuncType::peek(&mut lookahead) {
1290            Ok(Self::Func(Parse::parse(lexer)?))
1291        } else if InlineInterface::peek(&mut lookahead) {
1292            Ok(Self::Interface(Parse::parse(lexer)?))
1293        } else {
1294            Err(lookahead.error())
1295        }
1296    }
1297}
1298
1299/// Represents an inline interface in the AST.
1300#[derive(Debug, Clone, Serialize)]
1301#[serde(rename_all = "camelCase")]
1302pub struct InlineInterface<'a> {
1303    /// The items of the interface.
1304    pub items: Vec<InterfaceItem<'a>>,
1305}
1306
1307impl<'a> Parse<'a> for InlineInterface<'a> {
1308    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1309        parse_token(lexer, Token::InterfaceKeyword)?;
1310        parse_token(lexer, Token::OpenBrace)?;
1311        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
1312        parse_token(lexer, Token::CloseBrace)?;
1313        Ok(Self { items })
1314    }
1315}
1316
1317impl Peek for InlineInterface<'_> {
1318    fn peek(lookahead: &mut Lookahead) -> bool {
1319        lookahead.peek(Token::InterfaceKeyword)
1320    }
1321}
1322
1323/// Represents a world include in the AST.
1324#[derive(Debug, Clone, Serialize)]
1325#[serde(rename_all = "camelCase")]
1326pub struct WorldInclude<'a> {
1327    /// The doc comments for the world include.
1328    pub docs: Vec<DocComment<'a>>,
1329    /// The reference to the world to include.
1330    pub world: WorldRef<'a>,
1331    /// The optional include-with items.
1332    pub with: Vec<WorldIncludeItem<'a>>,
1333}
1334
1335impl<'a> Parse<'a> for WorldInclude<'a> {
1336    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1337        let docs = Parse::parse(lexer)?;
1338        parse_token(lexer, Token::IncludeKeyword)?;
1339        let world = Parse::parse(lexer)?;
1340        let with = parse_optional(lexer, Token::WithKeyword, |lexer| {
1341            parse_token(lexer, Token::OpenBrace)?;
1342            let items = parse_delimited(lexer, Token::CloseBrace, true)?;
1343            parse_token(lexer, Token::CloseBrace)?;
1344            Ok(items)
1345        })?
1346        .unwrap_or_default();
1347        parse_token(lexer, Token::Semicolon)?;
1348        Ok(Self { docs, world, with })
1349    }
1350}
1351
1352impl Peek for WorldInclude<'_> {
1353    fn peek(lookahead: &mut Lookahead) -> bool {
1354        lookahead.peek(Token::IncludeKeyword)
1355    }
1356}
1357
1358/// Represents a reference to a world in the AST (local or foreign).
1359#[derive(Debug, Clone, Serialize)]
1360#[serde(rename_all = "camelCase")]
1361pub enum WorldRef<'a> {
1362    /// The reference is by identifier.
1363    Ident(Ident<'a>),
1364    /// The reference is by package path.
1365    Package(PackagePath<'a>),
1366}
1367
1368impl<'a> WorldRef<'a> {
1369    /// Gets the name of the world being referred to.
1370    pub fn name(&self) -> &'a str {
1371        match self {
1372            Self::Ident(id) => id.string,
1373            Self::Package(path) => path.string,
1374        }
1375    }
1376
1377    /// Gets the span of the world reference.
1378    pub fn span(&self) -> SourceSpan {
1379        match self {
1380            Self::Ident(id) => id.span,
1381            Self::Package(path) => path.span,
1382        }
1383    }
1384}
1385
1386impl<'a> Parse<'a> for WorldRef<'a> {
1387    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1388        let mut lookahead = Lookahead::new(lexer);
1389        if PackagePath::peek(&mut lookahead) {
1390            Ok(Self::Package(Parse::parse(lexer)?))
1391        } else if Ident::peek(&mut lookahead) {
1392            Ok(Self::Ident(Parse::parse(lexer)?))
1393        } else {
1394            Err(lookahead.error())
1395        }
1396    }
1397}
1398
1399/// Represents a renaming of an included name.
1400#[derive(Debug, Clone, Serialize)]
1401#[serde(rename_all = "camelCase")]
1402pub struct WorldIncludeItem<'a> {
1403    /// The `from` name for the included item.
1404    pub from: Ident<'a>,
1405    /// The `to` name for the included item.
1406    pub to: Ident<'a>,
1407}
1408
1409impl<'a> Parse<'a> for WorldIncludeItem<'a> {
1410    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1411        let from = Ident::parse(lexer)?;
1412        parse_token(lexer, Token::AsKeyword)?;
1413        let to = Ident::parse(lexer)?;
1414        Ok(Self { from, to })
1415    }
1416}
1417
1418impl Peek for WorldIncludeItem<'_> {
1419    fn peek(lookahead: &mut Lookahead) -> bool {
1420        Ident::peek(lookahead)
1421    }
1422}
1423
1424#[cfg(test)]
1425mod test {
1426    use crate::ast::test::roundtrip;
1427
1428    #[test]
1429    fn resource_roundtrip() {
1430        roundtrip(
1431            r#"package foo:bar;
1432interface i { resource foo-bar {
1433    /** A constructor */
1434    constructor(foo: u8, bar: u8);
1435    /// A method
1436    foo: func() -> string;
1437    /// A method
1438    set-foo: func(foo: string);
1439    /// A static method
1440    id: static func() -> u32;
1441}}"#,
1442            r#"package foo:bar;
1443
1444interface i {
1445    resource foo-bar {
1446        /// A constructor
1447        constructor(foo: u8, bar: u8);
1448
1449        /// A method
1450        foo: func() -> string;
1451
1452        /// A method
1453        set-foo: func(foo: string);
1454
1455        /// A static method
1456        id: static func() -> u32;
1457    }
1458}
1459"#,
1460        )
1461        .unwrap();
1462    }
1463
1464    #[test]
1465    fn variant_roundtrip() {
1466        roundtrip(
1467            r#"package foo:bar;
1468variant foo {
1469    foo,
1470    bar(u32),
1471    baz(bar),
1472    qux(tuple<u8, u16, u32>)
1473}"#,
1474            r#"package foo:bar;
1475
1476variant foo {
1477    foo,
1478    bar(u32),
1479    baz(bar),
1480    qux(tuple<u8, u16, u32>),
1481}
1482"#,
1483        )
1484        .unwrap();
1485    }
1486
1487    #[test]
1488    fn record_roundtrip() {
1489        roundtrip(
1490            r#"package foo:bar;
1491record foo-bar2-baz {
1492    foo: foo,
1493    bar-qux: list<string>,
1494    // A comment
1495    jam: borrow<foo>,
1496}"#,
1497            r#"package foo:bar;
1498
1499record foo-bar2-baz {
1500    foo: foo,
1501    bar-qux: list<string>,
1502    jam: borrow<foo>,
1503}
1504"#,
1505        )
1506        .unwrap();
1507    }
1508
1509    #[test]
1510    fn flags_roundtrip() {
1511        roundtrip(
1512            r#"package foo:bar;
1513flags %flags {
1514    foo, bar, baz
1515}"#,
1516            r#"package foo:bar;
1517
1518flags %flags {
1519    foo,
1520    bar,
1521    baz,
1522}
1523"#,
1524        )
1525        .unwrap();
1526    }
1527
1528    #[test]
1529    fn enum_roundtrip() {
1530        roundtrip(
1531            r#"package foo:bar; enum foo {
1532    foo, bar, baz
1533}"#,
1534            r#"package foo:bar;
1535
1536enum foo {
1537    foo,
1538    bar,
1539    baz,
1540}
1541"#,
1542        )
1543        .unwrap();
1544    }
1545
1546    #[test]
1547    fn func_type_alias_roundtrip() {
1548        roundtrip(
1549            r#"package foo:bar; type x = func(a: /* comment */ string) -> string;"#,
1550            "package foo:bar;\n\ntype x = func(a: string) -> string;\n",
1551        )
1552        .unwrap();
1553    }
1554
1555    #[test]
1556    fn type_alias_roundtrip() {
1557        roundtrip(
1558            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>;"#,
1559            "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",
1560        )
1561        .unwrap();
1562    }
1563
1564    #[test]
1565    fn interface_roundtrip() {
1566        roundtrip(
1567            r#"package foo:bar;
1568
1569interface foo {
1570    /// Type t
1571    type t = list<string>;
1572
1573    /// Use x and y
1574    use foo.{ x, y, };
1575
1576    /// Function a
1577    a: func(a: string, b: string) -> string;
1578
1579    // not a doc comment
1580    type x = func() -> list<string>;
1581
1582    /// Function b
1583    b: x;
1584}
1585            "#,
1586            r#"package foo:bar;
1587
1588interface foo {
1589    /// Type t
1590    type t = list<string>;
1591
1592    /// Use x and y
1593    use foo.{ x, y };
1594
1595    /// Function a
1596    a: func(a: string, b: string) -> string;
1597
1598    type x = func() -> list<string>;
1599
1600    /// Function b
1601    b: x;
1602}
1603"#,
1604        )
1605        .unwrap();
1606    }
1607
1608    #[test]
1609    fn world_roundtrip() {
1610        roundtrip(
1611            r#"package foo:bar;
1612
1613world foo {
1614    /// Type t
1615    type t = list<string>;
1616
1617    // not a doc comment
1618    type x = func() -> list<string>;
1619
1620    use foo.{ y, };
1621
1622    /// Import with function type.
1623    import a: func(a: string, b: string) -> string;
1624
1625    /// Import with identifier.
1626    import b: x;
1627
1628    /// Import with inline interface.
1629    import c: interface {
1630        /// Function a
1631        a: func(a: string, b: string) -> string;
1632    };
1633
1634    /// Import with package path
1635    import foo:bar/baz@1.0.0;
1636
1637    /// Export with function type.
1638    export a: func(a: string, b: string) -> string;
1639
1640    /// Export with identifier.
1641    export b: x;
1642
1643    /// Export with inline interface.
1644    export c: interface {
1645        /// Function a
1646        a: func(a: string, b: string) -> string;
1647    };
1648
1649    /// Export with package path
1650    export foo:bar/baz@1.0.0;
1651
1652    /// Include world from package path with 2 renames.
1653    include foo:bar/baz with { a as a1, b as b1 };
1654
1655    /// Include world from package path with 1 rename.
1656    include foo:bar/baz with {foo as foo1};
1657
1658    /// Include world from package path (spacing).
1659    include foo:bar/baz with { foo as foo1 };
1660
1661    /// Include world from package path newline delimited renaming.
1662    include foo:bar/baz with {
1663        foo as foo1,
1664        bar as bar1
1665    };
1666
1667    /// Include local world.
1668    include foo-bar;
1669
1670    /// Include local world with renaming.
1671    include foo-bar with { foo as bar };
1672}"#,
1673            r#"package foo:bar;
1674
1675world foo {
1676    /// Type t
1677    type t = list<string>;
1678
1679    type x = func() -> list<string>;
1680
1681    use foo.{ y };
1682
1683    /// Import with function type.
1684    import a: func(a: string, b: string) -> string;
1685
1686    /// Import with identifier.
1687    import b: x;
1688
1689    /// Import with inline interface.
1690    import c: interface {
1691        /// Function a
1692        a: func(a: string, b: string) -> string;
1693    };
1694
1695    /// Import with package path
1696    import foo:bar/baz@1.0.0;
1697
1698    /// Export with function type.
1699    export a: func(a: string, b: string) -> string;
1700
1701    /// Export with identifier.
1702    export b: x;
1703
1704    /// Export with inline interface.
1705    export c: interface {
1706        /// Function a
1707        a: func(a: string, b: string) -> string;
1708    };
1709
1710    /// Export with package path
1711    export foo:bar/baz@1.0.0;
1712
1713    /// Include world from package path with 2 renames.
1714    include foo:bar/baz with {
1715        a as a1,
1716        b as b1,
1717    };
1718
1719    /// Include world from package path with 1 rename.
1720    include foo:bar/baz with {
1721        foo as foo1,
1722    };
1723
1724    /// Include world from package path (spacing).
1725    include foo:bar/baz with {
1726        foo as foo1,
1727    };
1728
1729    /// Include world from package path newline delimited renaming.
1730    include foo:bar/baz with {
1731        foo as foo1,
1732        bar as bar1,
1733    };
1734
1735    /// Include local world.
1736    include foo-bar;
1737
1738    /// Include local world with renaming.
1739    include foo-bar with {
1740        foo as bar,
1741    };
1742}
1743"#,
1744        )
1745        .unwrap();
1746    }
1747}