router: parse an optional visibility
The 'pub' in `pub static ROUTER: ...` Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
841799d882
commit
11b09e578c
@ -3,11 +3,51 @@ use std::collections::HashMap;
|
||||
use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
|
||||
|
||||
use failure::{bail, Error};
|
||||
use quote::quote;
|
||||
use syn::{Expr, Lit};
|
||||
|
||||
pub type RawTokenIter = proc_macro2::token_stream::IntoIter;
|
||||
pub type TokenIter = std::iter::Peekable<RawTokenIter>;
|
||||
|
||||
pub fn optional_visibility(tokens: &mut TokenIter) -> Result<syn::Visibility, Error> {
|
||||
// peek:
|
||||
if let Some(TokenTree::Ident(ident)) = tokens.peek() {
|
||||
if ident.to_string() != "pub" {
|
||||
return Ok(syn::Visibility::Inherited);
|
||||
}
|
||||
} else {
|
||||
return Ok(syn::Visibility::Inherited);
|
||||
}
|
||||
|
||||
// consume:
|
||||
let ident = match tokens.next().unwrap() {
|
||||
TokenTree::Ident(ident) => ident,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
// peek:
|
||||
let restriction = match tokens.peek() {
|
||||
Some(TokenTree::Group(_)) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let visibility = if restriction {
|
||||
// consume:
|
||||
match tokens.next().unwrap() {
|
||||
TokenTree::Group(g) => {
|
||||
quote! { #ident #g }
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else {
|
||||
quote! { #ident }
|
||||
};
|
||||
|
||||
use syn::parse::Parser;
|
||||
let parser = <syn::Visibility as syn::parse::Parse>::parse;
|
||||
return Ok(parser.parse2(visibility)?);
|
||||
}
|
||||
|
||||
pub fn match_keyword(tokens: &mut TokenIter, keyword: &'static str) -> Result<(), Error> {
|
||||
if let Some(tt) = tokens.next() {
|
||||
if let TokenTree::Ident(ident) = tt {
|
||||
|
@ -18,6 +18,8 @@ pub fn router_macro(input: TokenStream) -> Result<TokenStream, Error> {
|
||||
break;
|
||||
}
|
||||
|
||||
let public = optional_visibility(&mut input)?;
|
||||
|
||||
match_keyword(&mut input, "static")?;
|
||||
let router_name = need_ident(&mut input)?;
|
||||
|
||||
@ -31,7 +33,7 @@ pub fn router_macro(input: TokenStream) -> Result<TokenStream, Error> {
|
||||
let content = need_group(&mut input, Delimiter::Brace)?;
|
||||
|
||||
let router = parse_router(content.stream().into_iter().peekable())?;
|
||||
let router = router.into_token_stream(&body_type, Some(router_name));
|
||||
let router = router.into_token_stream(&body_type, Some((router_name, public)));
|
||||
|
||||
//eprintln!("{}", router.to_string());
|
||||
|
||||
@ -175,7 +177,11 @@ impl Router {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn into_token_stream(self, body_type: &Ident, name: Option<Ident>) -> TokenStream {
|
||||
fn into_token_stream(
|
||||
self,
|
||||
body_type: &Ident,
|
||||
name: Option<(Ident, syn::Visibility)>,
|
||||
) -> TokenStream {
|
||||
use std::iter::FromIterator;
|
||||
|
||||
let mut out = quote_spanned! {
|
||||
@ -225,14 +231,14 @@ impl Router {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(name) = name {
|
||||
if let Some((name, vis)) = name {
|
||||
let type_name = Ident::new(&format!("{}_TYPE", name.to_string()), name.span());
|
||||
let var_name = name;
|
||||
let router_expression = TokenStream::from_iter(out);
|
||||
|
||||
quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct #type_name(
|
||||
#vis struct #type_name(
|
||||
std::cell::Cell<Option<::proxmox::api::Router<#body_type>>>,
|
||||
std::sync::Once,
|
||||
);
|
||||
@ -248,7 +254,7 @@ impl Router {
|
||||
}
|
||||
}
|
||||
}
|
||||
static #var_name : #type_name = #type_name(
|
||||
#vis static #var_name : #type_name = #type_name(
|
||||
std::cell::Cell::new(None),
|
||||
std::sync::Once::new(),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user