blob: f22790035a04318d944b5f2a66879b657a02a8f5 [file] [log] [blame]
David Tolnay3c64a4e2020-08-29 14:07:38 -07001use crate::syntax::namespace::Namespace;
2use quote::quote;
David Tolnay05ef6ff2020-08-29 11:27:05 -07003use syn::parse::{Error, Parse, ParseStream, Result};
David Tolnay00a83852020-08-29 15:06:16 -07004use syn::{
5 braced, token, Attribute, Ident, Item as RustItem, ItemEnum, ItemForeignMod, ItemStruct,
6 ItemUse, Token, Visibility,
7};
David Tolnay05ef6ff2020-08-29 11:27:05 -07008
9pub struct Module {
David Tolnay3c64a4e2020-08-29 14:07:38 -070010 pub namespace: Namespace,
David Tolnay05ef6ff2020-08-29 11:27:05 -070011 pub attrs: Vec<Attribute>,
12 pub vis: Visibility,
David Tolnay633f5662020-08-29 14:47:45 -070013 pub unsafety: Option<Token![unsafe]>,
David Tolnay05ef6ff2020-08-29 11:27:05 -070014 pub mod_token: Token![mod],
15 pub ident: Ident,
16 pub brace_token: token::Brace,
17 pub content: Vec<Item>,
18}
19
David Tolnay00a83852020-08-29 15:06:16 -070020pub enum Item {
21 Struct(ItemStruct),
22 Enum(ItemEnum),
23 ForeignMod(ItemForeignMod),
24 Use(ItemUse),
25 Other(RustItem),
26}
27
David Tolnay05ef6ff2020-08-29 11:27:05 -070028impl Parse for Module {
29 fn parse(input: ParseStream) -> Result<Self> {
David Tolnay3c64a4e2020-08-29 14:07:38 -070030 let namespace = Namespace::none();
David Tolnay05ef6ff2020-08-29 11:27:05 -070031 let mut attrs = input.call(Attribute::parse_outer)?;
32 let vis: Visibility = input.parse()?;
David Tolnay633f5662020-08-29 14:47:45 -070033 let unsafety: Option<Token![unsafe]> = input.parse()?;
David Tolnay05ef6ff2020-08-29 11:27:05 -070034 let mod_token: Token![mod] = input.parse()?;
35 let ident: Ident = input.parse()?;
36
David Tolnay3c64a4e2020-08-29 14:07:38 -070037 let semi: Option<Token![;]> = input.parse()?;
38 if let Some(semi) = semi {
39 let span = quote!(#vis #mod_token #semi);
40 return Err(Error::new_spanned(
41 span,
David Tolnay05ef6ff2020-08-29 11:27:05 -070042 "#[cxx::bridge] module must have inline contents",
43 ))?;
44 }
45
46 let content;
47 let brace_token = braced!(content in input);
48 attrs.extend(content.call(Attribute::parse_inner)?);
49
50 let mut items = Vec::new();
51 while !content.is_empty() {
52 items.push(content.parse()?);
53 }
54
55 Ok(Module {
David Tolnay3c64a4e2020-08-29 14:07:38 -070056 namespace,
David Tolnay05ef6ff2020-08-29 11:27:05 -070057 attrs,
58 vis,
David Tolnay633f5662020-08-29 14:47:45 -070059 unsafety,
David Tolnay05ef6ff2020-08-29 11:27:05 -070060 mod_token,
61 ident,
62 brace_token,
63 content: items,
64 })
65 }
66}
David Tolnay00a83852020-08-29 15:06:16 -070067
68impl Parse for Item {
69 fn parse(input: ParseStream) -> Result<Self> {
70 let item = input.parse()?;
71 match item {
72 RustItem::Struct(item) => Ok(Item::Struct(item)),
73 RustItem::Enum(item) => Ok(Item::Enum(item)),
74 RustItem::ForeignMod(item) => Ok(Item::ForeignMod(item)),
75 RustItem::Use(item) => Ok(Item::Use(item)),
76 other => Ok(Item::Other(other)),
77 }
78 }
79}