1 use crate::syntax::qualified::QualifiedName; 2 use quote::IdentFragment; 3 use std::fmt::{self, Display}; 4 use std::iter::FromIterator; 5 use std::slice::Iter; 6 use syn::parse::{Error, Parse, ParseStream, Result}; 7 use syn::{Expr, Ident, Lit, Meta, Token}; 8 9 mod kw { 10 syn::custom_keyword!(namespace); 11 } 12 13 #[derive(Clone, Default)] 14 pub struct Namespace { 15 segments: Vec<Ident>, 16 } 17 18 impl Namespace { 19 pub const ROOT: Self = Namespace { 20 segments: Vec::new(), 21 }; 22 iter(&self) -> Iter<Ident>23 pub fn iter(&self) -> Iter<Ident> { 24 self.segments.iter() 25 } 26 parse_bridge_attr_namespace(input: ParseStream) -> Result<Self>27 pub fn parse_bridge_attr_namespace(input: ParseStream) -> Result<Self> { 28 if input.is_empty() { 29 return Ok(Namespace::ROOT); 30 } 31 32 input.parse::<kw::namespace>()?; 33 input.parse::<Token![=]>()?; 34 let namespace = input.parse::<Namespace>()?; 35 input.parse::<Option<Token![,]>>()?; 36 Ok(namespace) 37 } 38 parse_meta(meta: &Meta) -> Result<Self>39 pub fn parse_meta(meta: &Meta) -> Result<Self> { 40 if let Meta::NameValue(meta) = meta { 41 match &meta.value { 42 Expr::Lit(expr) => { 43 if let Lit::Str(lit) = &expr.lit { 44 let segments = QualifiedName::parse_quoted(lit)?.segments; 45 return Ok(Namespace { segments }); 46 } 47 } 48 Expr::Path(expr) 49 if expr.qself.is_none() 50 && expr 51 .path 52 .segments 53 .iter() 54 .all(|segment| segment.arguments.is_none()) => 55 { 56 let segments = expr 57 .path 58 .segments 59 .iter() 60 .map(|segment| segment.ident.clone()) 61 .collect(); 62 return Ok(Namespace { segments }); 63 } 64 _ => {} 65 } 66 } 67 Err(Error::new_spanned(meta, "unsupported namespace attribute")) 68 } 69 } 70 71 impl Default for &Namespace { default() -> Self72 fn default() -> Self { 73 const ROOT: &Namespace = &Namespace::ROOT; 74 ROOT 75 } 76 } 77 78 impl Parse for Namespace { parse(input: ParseStream) -> Result<Self>79 fn parse(input: ParseStream) -> Result<Self> { 80 let segments = QualifiedName::parse_quoted_or_unquoted(input)?.segments; 81 Ok(Namespace { segments }) 82 } 83 } 84 85 impl Display for Namespace { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 87 for segment in self { 88 write!(f, "{}$", segment)?; 89 } 90 Ok(()) 91 } 92 } 93 94 impl IdentFragment for Namespace { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 96 Display::fmt(self, f) 97 } 98 } 99 100 impl<'a> IntoIterator for &'a Namespace { 101 type Item = &'a Ident; 102 type IntoIter = Iter<'a, Ident>; into_iter(self) -> Self::IntoIter103 fn into_iter(self) -> Self::IntoIter { 104 self.iter() 105 } 106 } 107 108 impl<'a> FromIterator<&'a Ident> for Namespace { from_iter<I>(idents: I) -> Self where I: IntoIterator<Item = &'a Ident>,109 fn from_iter<I>(idents: I) -> Self 110 where 111 I: IntoIterator<Item = &'a Ident>, 112 { 113 let segments = idents.into_iter().cloned().collect(); 114 Namespace { segments } 115 } 116 } 117