summaryrefslogtreecommitdiffstats
path: root/third_party/rust/async-trait/src/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/async-trait/src/parse.rs')
-rw-r--r--third_party/rust/async-trait/src/parse.rs34
1 files changed, 34 insertions, 0 deletions
diff --git a/third_party/rust/async-trait/src/parse.rs b/third_party/rust/async-trait/src/parse.rs
new file mode 100644
index 0000000000..ebd253514f
--- /dev/null
+++ b/third_party/rust/async-trait/src/parse.rs
@@ -0,0 +1,34 @@
+use proc_macro2::Span;
+use syn::parse::{Error, Parse, ParseStream, Result};
+use syn::{Attribute, ItemImpl, ItemTrait, Token};
+
+pub enum Item {
+ Trait(ItemTrait),
+ Impl(ItemImpl),
+}
+
+impl Parse for Item {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mut lookahead = input.lookahead1();
+ if lookahead.peek(Token![unsafe]) {
+ let ahead = input.fork();
+ ahead.parse::<Token![unsafe]>()?;
+ lookahead = ahead.lookahead1();
+ }
+ if lookahead.peek(Token![pub]) || lookahead.peek(Token![trait]) {
+ let mut item: ItemTrait = input.parse()?;
+ item.attrs = attrs;
+ Ok(Item::Trait(item))
+ } else if lookahead.peek(Token![impl]) {
+ let mut item: ItemImpl = input.parse()?;
+ if item.trait_.is_none() {
+ return Err(Error::new(Span::call_site(), "expected a trait impl"));
+ }
+ item.attrs = attrs;
+ Ok(Item::Impl(item))
+ } else {
+ Err(lookahead.error())
+ }
+ }
+}