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::parse::{Error, Result};
7 use syn::punctuated::Punctuated;
8 
9 #[derive(Clone)]
10 pub struct ForeignName {
11     text: String,
12     span: Span,
13 }
14 
15 impl Pair {
to_symbol(&self) -> Symbol16     pub 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 
to_fully_qualified(&self) -> String25     pub fn to_fully_qualified(&self) -> String {
26         let mut fully_qualified = String::new();
27         for segment in &self.namespace {
28             fully_qualified += "::";
29             fully_qualified += &segment.to_string();
30         }
31         fully_qualified += "::";
32         fully_qualified += &self.cxx.to_string();
33         fully_qualified
34     }
35 }
36 
37 impl NamedType {
new(rust: Ident) -> Self38     pub fn new(rust: Ident) -> Self {
39         let generics = Lifetimes {
40             lt_token: None,
41             lifetimes: Punctuated::new(),
42             gt_token: None,
43         };
44         NamedType { rust, generics }
45     }
46 
span(&self) -> Span47     pub fn span(&self) -> Span {
48         self.rust.span()
49     }
50 }
51 
52 impl ForeignName {
parse(text: &str, span: Span) -> Result<Self>53     pub fn parse(text: &str, span: Span) -> Result<Self> {
54         // TODO: support C++ names containing whitespace (`unsigned int`) or
55         // non-alphanumeric characters (`operator++`).
56         match syn::parse_str::<Ident>(text) {
57             Ok(ident) => {
58                 let text = ident.to_string();
59                 Ok(ForeignName { text, span })
60             }
61             Err(err) => Err(Error::new(span, err)),
62         }
63     }
64 }
65 
66 impl Display for ForeignName {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result67     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
68         formatter.write_str(&self.text)
69     }
70 }
71