133d722a9Sopenharmony_ciuse crate::syntax::symbol::Segment; 233d722a9Sopenharmony_ciuse crate::syntax::{Lifetimes, NamedType, Pair, Symbol}; 333d722a9Sopenharmony_ciuse proc_macro2::{Ident, Span}; 433d722a9Sopenharmony_ciuse std::fmt::{self, Display}; 533d722a9Sopenharmony_ciuse std::iter; 633d722a9Sopenharmony_ciuse syn::ext::IdentExt; 733d722a9Sopenharmony_ciuse syn::parse::{Error, Parser, Result}; 833d722a9Sopenharmony_ciuse syn::punctuated::Punctuated; 933d722a9Sopenharmony_ci 1033d722a9Sopenharmony_ci#[derive(Clone)] 1133d722a9Sopenharmony_cipub struct ForeignName { 1233d722a9Sopenharmony_ci text: String, 1333d722a9Sopenharmony_ci} 1433d722a9Sopenharmony_ci 1533d722a9Sopenharmony_ciimpl Pair { 1633d722a9Sopenharmony_ci pub fn to_symbol(&self) -> Symbol { 1733d722a9Sopenharmony_ci let segments = self 1833d722a9Sopenharmony_ci .namespace 1933d722a9Sopenharmony_ci .iter() 2033d722a9Sopenharmony_ci .map(|ident| ident as &dyn Segment) 2133d722a9Sopenharmony_ci .chain(iter::once(&self.cxx as &dyn Segment)); 2233d722a9Sopenharmony_ci Symbol::from_idents(segments) 2333d722a9Sopenharmony_ci } 2433d722a9Sopenharmony_ci} 2533d722a9Sopenharmony_ci 2633d722a9Sopenharmony_ciimpl NamedType { 2733d722a9Sopenharmony_ci pub fn new(rust: Ident) -> Self { 2833d722a9Sopenharmony_ci let generics = Lifetimes { 2933d722a9Sopenharmony_ci lt_token: None, 3033d722a9Sopenharmony_ci lifetimes: Punctuated::new(), 3133d722a9Sopenharmony_ci gt_token: None, 3233d722a9Sopenharmony_ci }; 3333d722a9Sopenharmony_ci NamedType { rust, generics } 3433d722a9Sopenharmony_ci } 3533d722a9Sopenharmony_ci 3633d722a9Sopenharmony_ci pub fn span(&self) -> Span { 3733d722a9Sopenharmony_ci self.rust.span() 3833d722a9Sopenharmony_ci } 3933d722a9Sopenharmony_ci} 4033d722a9Sopenharmony_ci 4133d722a9Sopenharmony_ciimpl ForeignName { 4233d722a9Sopenharmony_ci pub fn parse(text: &str, span: Span) -> Result<Self> { 4333d722a9Sopenharmony_ci // TODO: support C++ names containing whitespace (`unsigned int`) or 4433d722a9Sopenharmony_ci // non-alphanumeric characters (`operator++`). 4533d722a9Sopenharmony_ci match Ident::parse_any.parse_str(text) { 4633d722a9Sopenharmony_ci Ok(ident) => { 4733d722a9Sopenharmony_ci let text = ident.to_string(); 4833d722a9Sopenharmony_ci Ok(ForeignName { text }) 4933d722a9Sopenharmony_ci } 5033d722a9Sopenharmony_ci Err(err) => Err(Error::new(span, err)), 5133d722a9Sopenharmony_ci } 5233d722a9Sopenharmony_ci } 5333d722a9Sopenharmony_ci} 5433d722a9Sopenharmony_ci 5533d722a9Sopenharmony_ciimpl Display for ForeignName { 5633d722a9Sopenharmony_ci fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 5733d722a9Sopenharmony_ci formatter.write_str(&self.text) 5833d722a9Sopenharmony_ci } 5933d722a9Sopenharmony_ci} 6033d722a9Sopenharmony_ci 6133d722a9Sopenharmony_ciimpl PartialEq<str> for ForeignName { 6233d722a9Sopenharmony_ci fn eq(&self, rhs: &str) -> bool { 6333d722a9Sopenharmony_ci self.text == rhs 6433d722a9Sopenharmony_ci } 6533d722a9Sopenharmony_ci} 66