wast/component/
item_ref.rs1use crate::parser::{Cursor, Parse, Parser, Peek, Result};
2use crate::token::Index;
3
4fn peek<K: Peek>(cursor: Cursor) -> Result<bool> {
5 if !K::peek(cursor)? {
20 return Ok(false);
21 }
22
23 let cursor = match cursor.keyword()? {
25 Some((_, c)) => c,
26 _ => return Ok(false),
27 };
28
29 let cursor = match cursor.id()? {
31 Some((_, cursor)) => Some(cursor),
32 None => cursor.integer()?.map(|p| p.1),
33 };
34 Ok(match cursor {
35 Some(cursor) => cursor.rparen()?.is_some() || cursor.string()?.is_some(),
36 None => false,
37 })
38}
39
40#[derive(Clone, Debug)]
42pub struct CoreItemRef<'a, K> {
43 pub kind: K,
45 pub idx: Index<'a>,
47 pub export_name: Option<&'a str>,
49}
50
51impl<'a, K: Parse<'a>> Parse<'a> for CoreItemRef<'a, K> {
52 fn parse(parser: Parser<'a>) -> Result<Self> {
53 let kind = parser.parse::<K>()?;
57 let idx = parser.parse()?;
58 let export_name = parser.parse()?;
59 Ok(Self {
60 kind,
61 idx,
62 export_name,
63 })
64 }
65}
66
67impl<'a, K: Peek> Peek for CoreItemRef<'a, K> {
68 fn peek(cursor: Cursor<'_>) -> Result<bool> {
69 peek::<K>(cursor)
70 }
71
72 fn display() -> &'static str {
73 "a core item reference"
74 }
75}
76
77#[derive(Clone, Debug)]
79pub struct ItemRef<'a, K> {
80 pub kind: K,
82 pub idx: Index<'a>,
84 pub export_names: Vec<&'a str>,
86}
87
88impl<'a, K: Parse<'a>> Parse<'a> for ItemRef<'a, K> {
89 fn parse(parser: Parser<'a>) -> Result<Self> {
90 let kind = parser.parse::<K>()?;
91 let idx = parser.parse()?;
92 let mut export_names = Vec::new();
93 while !parser.is_empty() {
94 export_names.push(parser.parse()?);
95 }
96 Ok(Self {
97 kind,
98 idx,
99 export_names,
100 })
101 }
102}
103
104impl<'a, K: Peek> Peek for ItemRef<'a, K> {
105 fn peek(cursor: Cursor<'_>) -> Result<bool> {
106 peek::<K>(cursor)
107 }
108
109 fn display() -> &'static str {
110 "a component item reference"
111 }
112}
113
114#[derive(Clone, Debug)]
116pub struct IndexOrRef<'a, K>(pub ItemRef<'a, K>);
117
118impl<'a, K> Parse<'a> for IndexOrRef<'a, K>
119where
120 K: Parse<'a> + Default,
121{
122 fn parse(parser: Parser<'a>) -> Result<Self> {
123 if parser.peek::<Index<'_>>()? {
124 Ok(IndexOrRef(ItemRef {
125 kind: K::default(),
126 idx: parser.parse()?,
127 export_names: Vec::new(),
128 }))
129 } else {
130 Ok(IndexOrRef(parser.parens(|p| p.parse())?))
131 }
132 }
133}
134
135#[derive(Clone, Debug)]
137pub struct IndexOrCoreRef<'a, K>(pub CoreItemRef<'a, K>);
138
139impl<'a, K> Parse<'a> for IndexOrCoreRef<'a, K>
140where
141 K: Parse<'a> + Default,
142{
143 fn parse(parser: Parser<'a>) -> Result<Self> {
144 if parser.peek::<Index<'_>>()? {
145 Ok(IndexOrCoreRef(CoreItemRef {
146 kind: K::default(),
147 idx: parser.parse()?,
148 export_name: None,
149 }))
150 } else {
151 Ok(IndexOrCoreRef(parser.parens(|p| p.parse())?))
152 }
153 }
154}