blob: dc7c2950c43e85d34a8a025d0f7349949588334d [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};
4use syn::{braced, token, Attribute, Ident, Item, Token, Visibility};
5
6pub struct Module {
David Tolnay3c64a4e2020-08-29 14:07:38 -07007 pub namespace: Namespace,
David Tolnay05ef6ff2020-08-29 11:27:05 -07008 pub attrs: Vec<Attribute>,
9 pub vis: Visibility,
10 // TODO: unsafety
11 pub mod_token: Token![mod],
12 pub ident: Ident,
13 pub brace_token: token::Brace,
14 pub content: Vec<Item>,
15}
16
17impl Parse for Module {
18 fn parse(input: ParseStream) -> Result<Self> {
David Tolnay3c64a4e2020-08-29 14:07:38 -070019 let namespace = Namespace::none();
David Tolnay05ef6ff2020-08-29 11:27:05 -070020 let mut attrs = input.call(Attribute::parse_outer)?;
21 let vis: Visibility = input.parse()?;
22 let mod_token: Token![mod] = input.parse()?;
23 let ident: Ident = input.parse()?;
24
David Tolnay3c64a4e2020-08-29 14:07:38 -070025 let semi: Option<Token![;]> = input.parse()?;
26 if let Some(semi) = semi {
27 let span = quote!(#vis #mod_token #semi);
28 return Err(Error::new_spanned(
29 span,
David Tolnay05ef6ff2020-08-29 11:27:05 -070030 "#[cxx::bridge] module must have inline contents",
31 ))?;
32 }
33
34 let content;
35 let brace_token = braced!(content in input);
36 attrs.extend(content.call(Attribute::parse_inner)?);
37
38 let mut items = Vec::new();
39 while !content.is_empty() {
40 items.push(content.parse()?);
41 }
42
43 Ok(Module {
David Tolnay3c64a4e2020-08-29 14:07:38 -070044 namespace,
David Tolnay05ef6ff2020-08-29 11:27:05 -070045 attrs,
46 vis,
47 mod_token,
48 ident,
49 brace_token,
50 content: items,
51 })
52 }
53}