11use super :: {
22 display,
33 keywords:: {
4- self , Bool , Enum , Export , Flags , Float32 , Float64 , Func , Import , Interface , Record ,
5- Resource , Static , Use , Variant , World , S16 , S32 , S64 , S8 , U16 , U32 , U64 , U8 ,
4+ self , As , Bool , Enum , Export , Flags , Float32 , Float64 , Func , Import , Include , Interface ,
5+ Record , Resource , Static , Use , Variant , With , World , S16 , S32 , S64 , S8 , U16 , U32 , U64 , U8 ,
66 } ,
77 symbols:: {
88 Arrow , CloseAngle , CloseBrace , CloseParen , Colon , Dot , Equals , OpenAngle , OpenBrace ,
@@ -1247,6 +1247,8 @@ pub enum WorldItemKind<'a> {
12471247 Import ( WorldImportStatement < ' a > ) ,
12481248 /// The item is a world export statement.
12491249 Export ( WorldExportStatement < ' a > ) ,
1250+ /// The item is a world include statement.
1251+ Include ( WorldIncludeStatement < ' a > ) ,
12501252}
12511253
12521254impl AstDisplay for WorldItemKind < ' _ > {
@@ -1256,6 +1258,7 @@ impl AstDisplay for WorldItemKind<'_> {
12561258 Self :: Type ( ty) => ty. fmt ( f, indenter) ,
12571259 Self :: Import ( i) => i. fmt ( f, indenter) ,
12581260 Self :: Export ( e) => e. fmt ( f, indenter) ,
1261+ Self :: Include ( i) => i. fmt ( f, indenter) ,
12591262 }
12601263 }
12611264}
@@ -1412,6 +1415,108 @@ impl AstDisplay for InlineInterface<'_> {
14121415}
14131416
14141417display ! ( InlineInterface ) ;
1418+
1419+ /// Represents a world include statement in the AST.
1420+ #[ derive( Debug , Clone , FromPest ) ]
1421+ #[ pest_ast( rule( Rule :: WorldIncludeStatement ) ) ]
1422+ pub struct WorldIncludeStatement < ' a > {
1423+ /// The `include` keyword in the statement.
1424+ pub keyword : Include < ' a > ,
1425+ /// The reference to the world to include.
1426+ pub world : WorldRef < ' a > ,
1427+ /// The optional include-with clause.
1428+ pub with : std:: option:: Option < WorldIncludeWithClause < ' a > > ,
1429+ /// The semicolon of the include statement.
1430+ pub semicolon : Semicolon < ' a > ,
1431+ }
1432+
1433+ impl AstDisplay for WorldIncludeStatement < ' _ > {
1434+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > , indenter : & mut Indenter ) -> fmt:: Result {
1435+ write ! ( f, "{indenter}{keyword} " , keyword = self . keyword) ?;
1436+ self . world . fmt ( f, indenter) ?;
1437+ if let Some ( with) = & self . with {
1438+ with. fmt ( f, indenter) ?;
1439+ }
1440+ write ! ( f, "{semi}" , semi = self . semicolon)
1441+ }
1442+ }
1443+
1444+ display ! ( WorldIncludeStatement ) ;
1445+
1446+ /// Represents a reference to a world in the AST (local or foreign).
1447+ #[ derive( Debug , Clone , FromPest ) ]
1448+ #[ pest_ast( rule( Rule :: WorldRef ) ) ]
1449+ pub enum WorldRef < ' a > {
1450+ /// The reference is by identifier.
1451+ Ident ( Ident < ' a > ) ,
1452+ /// The reference is by package path.
1453+ Path ( PackagePath < ' a > ) ,
1454+ }
1455+
1456+ impl AstDisplay for WorldRef < ' _ > {
1457+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > , indenter : & mut Indenter ) -> fmt:: Result {
1458+ match self {
1459+ Self :: Ident ( id) => id. fmt ( f, indenter) ,
1460+ Self :: Path ( path) => path. fmt ( f, indenter) ,
1461+ }
1462+ }
1463+ }
1464+
1465+ display ! ( WorldRef ) ;
1466+
1467+ /// Represents the `with` clause of the `include` statement.
1468+ #[ derive( Debug , Clone , FromPest ) ]
1469+ #[ pest_ast( rule( Rule :: WorldIncludeWithClause ) ) ]
1470+ pub struct WorldIncludeWithClause < ' a > {
1471+ /// The `with` keyword in the clause.
1472+ pub keyword : With < ' a > ,
1473+ /// The opening brace of the body.
1474+ pub open : OpenBrace < ' a > ,
1475+ /// The list of names to be included.
1476+ pub names : Vec < WorldIncludeItem < ' a > > ,
1477+ /// The closing brace of the body.
1478+ pub close : CloseBrace < ' a > ,
1479+ }
1480+
1481+ impl AstDisplay for WorldIncludeWithClause < ' _ > {
1482+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > , indenter : & mut Indenter ) -> fmt:: Result {
1483+ write ! ( f, " {keyword} " , keyword = self . keyword) ?;
1484+ writeln ! ( f, "{open}" , open = self . open) ?;
1485+ indenter. indent ( ) ;
1486+ for name in & self . names {
1487+ write ! ( f, "{indenter}" ) ?;
1488+ name. fmt ( f, indenter) ?;
1489+ writeln ! ( f, "," ) ?;
1490+ }
1491+ indenter. dedent ( ) ;
1492+ write ! ( f, "{indenter}{close}" , close = self . close)
1493+ }
1494+ }
1495+
1496+ display ! ( WorldIncludeWithClause ) ;
1497+
1498+ /// Represents a renaming of an included name.
1499+ #[ derive( Debug , Clone , FromPest ) ]
1500+ #[ pest_ast( rule( Rule :: WorldIncludeItem ) ) ]
1501+ pub struct WorldIncludeItem < ' a > {
1502+ /// The source name include from a world.
1503+ pub name : Ident < ' a > ,
1504+ /// The `as` keyword.
1505+ pub keyword : As < ' a > ,
1506+ /// The new name given to the included name.
1507+ pub other : Ident < ' a > ,
1508+ }
1509+
1510+ impl AstDisplay for WorldIncludeItem < ' _ > {
1511+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > , indenter : & mut Indenter ) -> fmt:: Result {
1512+ self . name . fmt ( f, indenter) ?;
1513+ write ! ( f, " {keyword} " , keyword = self . keyword) ?;
1514+ self . other . fmt ( f, indenter)
1515+ }
1516+ }
1517+
1518+ display ! ( WorldIncludeItem ) ;
1519+
14151520#[ cfg( test) ]
14161521mod test {
14171522 use super :: * ;
@@ -1610,6 +1715,30 @@ mod test {
16101715
16111716 /// Export with package path
16121717 export foo:bar/baz@1.0.0;
1718+
1719+ /// Include world from package path with 2 renames.
1720+ include foo:bar/baz with { a as a1, b as b1 };
1721+
1722+ /// Include world from package path with 1 rename.
1723+ include foo:bar/baz with {foo as foo1};
1724+
1725+ /// Include world from package path (spacing).
1726+ include foo:bar/baz with { foo as foo1 };
1727+
1728+ /// Include world from package path newline delimited renaming.
1729+ include foo:bar/baz with {
1730+ foo as foo1,
1731+ bar as bar1
1732+ };
1733+
1734+ /// Include local world.
1735+ include foo-bar;
1736+
1737+ /// Include local world with renaming.
1738+ include foo-bar with { foo as bar };
1739+ };
1740+
1741+ include myworld;
16131742}
16141743 "# ,
16151744 r#"world foo {
@@ -1649,6 +1778,36 @@ mod test {
16491778
16501779 /// Export with package path
16511780 export foo:bar/baz@1.0.0;
1781+
1782+ /// Include world from package path with 2 renames.
1783+ include foo:bar/baz with {
1784+ a as a1,
1785+ b as b1,
1786+ };
1787+
1788+ /// Include world from package path with 1 rename.
1789+ include foo:bar/baz with {
1790+ foo as foo1,
1791+ };
1792+
1793+ /// Include world from package path (spacing).
1794+ include foo:bar/baz with {
1795+ foo as foo1,
1796+ };
1797+
1798+ /// Include world from package path newline delimited renaming.
1799+ include foo:bar/baz with {
1800+ foo as foo1,
1801+ bar as bar1,
1802+ };
1803+
1804+ /// Include local world.
1805+ include foo-bar;
1806+
1807+ /// Include local world with renaming.
1808+ include foo-bar with {
1809+ foo as bar,
1810+ };
16521811}"# ,
16531812 )
16541813 . unwrap ( ) ;
0 commit comments