1 use crate::syntax::symbol::Segment;
2 use crate::syntax::{Lifetimes, NamedType, Pair, Symbol};
3 use proc_macro2::{Ident, Span};
4 use std::fmt::{self, Display};
5 use std::iter;
6 use syn::ext::IdentExt;
7 use syn::parse::{Error, Parser, Result};
8 use syn::punctuated::Punctuated;
9 
10 #[derive(Clone)]
11 pub(crate) struct ForeignName {
12     text: String,
13 }
14 
15 impl Pair {
to_symbol(&self) -> Symbol16     pub(crate) fn to_symbol(&self) -> Symbol {
17         let segments = self
18             .namespace
19             .iter()
20             .map(|ident| ident as &dyn Segment)
21             .chain(iter::once(&self.cxx as &dyn Segment));
22         Symbol::from_idents(segments)
23     }
24 }
25 
26 impl NamedType {
new(rust: Ident) -> Self27     pub(crate) fn new(rust: Ident) -> Self {
28         let generics = Lifetimes {
29             lt_token: None,
30             lifetimes: Punctuated::new(),
31             gt_token: None,
32         };
33         NamedType { rust, generics }
34     }
35 }
36 
37 impl ForeignName {
parse(text: &str, span: Span) -> Result<Self>38     pub(crate) fn parse(text: &str, span: Span) -> Result<Self> {
39         // TODO: support C++ names containing whitespace (`unsigned int`) or
40         // non-alphanumeric characters (`operator++`).
41         match Ident::parse_any.parse_str(text) {
42             Ok(ident) => {
43                 let text = ident.to_string();
44                 Ok(ForeignName { text })
45             }
46             Err(err) => Err(Error::new(span, err)),
47         }
48     }
49 }
50 
51 impl Display for ForeignName {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result52     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
53         formatter.write_str(&self.text)
54     }
55 }
56 
57 impl PartialEq<str> for ForeignName {
eq(&self, rhs: &str) -> bool58     fn eq(&self, rhs: &str) -> bool {
59         self.text == rhs
60     }
61 }
62