Unify Namespace parsing code

This commit is contained in:
David Tolnay 2020-04-19 20:56:09 -07:00
parent 0841930d34
commit b6cf314a45
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
4 changed files with 42 additions and 59 deletions

View File

@ -8,13 +8,12 @@ mod write;
use self::error::format_err;
use crate::syntax::namespace::Namespace;
use crate::syntax::{self, check, ident, Types};
use crate::syntax::{self, check, Types};
use quote::quote;
use std::fs;
use std::io;
use std::path::Path;
use syn::parse::ParseStream;
use syn::{Attribute, File, Item, Token};
use syn::{Attribute, File, Item};
use thiserror::Error;
pub(super) type Result<T, E = Error> = std::result::Result<T, E>;
@ -86,8 +85,7 @@ fn find_bridge_mod(syntax: File) -> Result<Input> {
)));
}
};
let namespace_segments = parse_args(attr)?;
let namespace = Namespace::new(namespace_segments);
let namespace = parse_args(attr)?;
return Ok(Input { namespace, module });
}
}
@ -96,24 +94,10 @@ fn find_bridge_mod(syntax: File) -> Result<Input> {
Err(Error::NoBridgeMod)
}
fn parse_args(attr: &Attribute) -> syn::Result<Vec<String>> {
fn parse_args(attr: &Attribute) -> syn::Result<Namespace> {
if attr.tokens.is_empty() {
return Ok(Vec::new());
Ok(Namespace::none())
} else {
attr.parse_args()
}
attr.parse_args_with(|input: ParseStream| {
mod kw {
syn::custom_keyword!(namespace);
}
input.parse::<kw::namespace>()?;
input.parse::<Token![=]>()?;
let path = syn::Path::parse_mod_style(input)?;
input.parse::<Option<Token![,]>>()?;
path.segments
.into_iter()
.map(|seg| {
ident::check(&seg.ident)?;
Ok(seg.ident.to_string())
})
.collect()
})
}

View File

@ -10,7 +10,6 @@
extern crate proc_macro;
mod expand;
mod namespace;
mod syntax;
use crate::syntax::namespace::Namespace;

View File

@ -1,33 +0,0 @@
use crate::syntax::ident;
use crate::syntax::namespace::Namespace;
use quote::IdentFragment;
use std::fmt::{self, Display};
use syn::parse::{Parse, ParseStream, Result};
use syn::{Path, Token};
mod kw {
syn::custom_keyword!(namespace);
}
impl Parse for Namespace {
fn parse(input: ParseStream) -> Result<Self> {
let mut segments = Vec::new();
if !input.is_empty() {
input.parse::<kw::namespace>()?;
input.parse::<Token![=]>()?;
let path = input.call(Path::parse_mod_style)?;
for segment in path.segments {
ident::check(&segment.ident)?;
segments.push(segment.ident.to_string());
}
input.parse::<Option<Token![,]>>()?;
}
Ok(Namespace::new(segments))
}
}
impl IdentFragment for Namespace {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}

View File

@ -1,5 +1,13 @@
use crate::syntax::ident;
use quote::IdentFragment;
use std::fmt::{self, Display};
use std::slice::Iter;
use syn::parse::{Parse, ParseStream, Result};
use syn::{Path, Token};
mod kw {
syn::custom_keyword!(namespace);
}
#[derive(Clone)]
pub struct Namespace {
@ -7,8 +15,10 @@ pub struct Namespace {
}
impl Namespace {
pub fn new(segments: Vec<String>) -> Self {
Namespace { segments }
pub fn none() -> Self {
Namespace {
segments: Vec::new(),
}
}
pub fn iter(&self) -> Iter<String> {
@ -16,6 +26,23 @@ impl Namespace {
}
}
impl Parse for Namespace {
fn parse(input: ParseStream) -> Result<Self> {
let mut segments = Vec::new();
if !input.is_empty() {
input.parse::<kw::namespace>()?;
input.parse::<Token![=]>()?;
let path = input.call(Path::parse_mod_style)?;
for segment in path.segments {
ident::check(&segment.ident)?;
segments.push(segment.ident.to_string());
}
input.parse::<Option<Token![,]>>()?;
}
Ok(Namespace { segments })
}
}
impl Display for Namespace {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for segment in self {
@ -26,6 +53,12 @@ impl Display for Namespace {
}
}
impl IdentFragment for Namespace {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}
impl<'a> IntoIterator for &'a Namespace {
type Item = &'a String;
type IntoIter = Iter<'a, String>;