blob: b2ae01390c4345e3e39010aef3f7c6789f62d8b6 [file] [log] [blame]
David Tolnayed6ba4a2021-01-01 14:59:40 -08001use crate::syntax::symbol::Segment;
David Tolnay77a5e752021-01-01 14:15:18 -08002use crate::syntax::{Lifetimes, NamedType, Pair, Symbol};
David Tolnay60e7aa62020-11-01 12:34:51 -08003use proc_macro2::{Ident, Span};
David Tolnayed6ba4a2021-01-01 14:59:40 -08004use std::fmt::{self, Display};
David Tolnay8faec772020-11-02 00:18:19 -08005use std::iter;
David Tolnayed6ba4a2021-01-01 14:59:40 -08006use syn::parse::Result;
David Tolnay4a79b7f2020-12-30 19:48:42 -08007use syn::punctuated::Punctuated;
David Tolnay60e7aa62020-11-01 12:34:51 -08008
David Tolnayed6ba4a2021-01-01 14:59:40 -08009#[derive(Clone)]
10pub struct ForeignName {
11 text: String,
12 span: Span,
13}
14
David Tolnay60e7aa62020-11-01 12:34:51 -080015impl Pair {
David Tolnay8faec772020-11-02 00:18:19 -080016 pub fn to_symbol(&self) -> Symbol {
David Tolnayed6ba4a2021-01-01 14:59:40 -080017 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)
David Tolnay8faec772020-11-02 00:18:19 -080023 }
24
25 pub fn to_fully_qualified(&self) -> String {
David Tolnaydee9fa32020-12-21 14:40:50 -080026 let mut fully_qualified = String::new();
David Tolnayed6ba4a2021-01-01 14:59:40 -080027 for segment in &self.namespace {
David Tolnaydee9fa32020-12-21 14:40:50 -080028 fully_qualified += "::";
29 fully_qualified += &segment.to_string();
30 }
David Tolnayed6ba4a2021-01-01 14:59:40 -080031 fully_qualified += "::";
32 fully_qualified += &self.cxx.to_string();
David Tolnaydee9fa32020-12-21 14:40:50 -080033 fully_qualified
David Tolnay8faec772020-11-02 00:18:19 -080034 }
David Tolnay60e7aa62020-11-01 12:34:51 -080035}
36
David Tolnay77a5e752021-01-01 14:15:18 -080037impl NamedType {
David Tolnay7cd9fec2020-12-21 15:03:18 -080038 pub fn new(rust: Ident) -> Self {
David Tolnay4a79b7f2020-12-30 19:48:42 -080039 let generics = Lifetimes {
40 lt_token: None,
41 lifetimes: Punctuated::new(),
42 gt_token: None,
43 };
David Tolnay77a5e752021-01-01 14:15:18 -080044 NamedType { rust, generics }
David Tolnay60e7aa62020-11-01 12:34:51 -080045 }
46
David Tolnay60e7aa62020-11-01 12:34:51 -080047 pub fn span(&self) -> Span {
48 self.rust.span()
49 }
David Tolnay60e7aa62020-11-01 12:34:51 -080050}
David Tolnayed6ba4a2021-01-01 14:59:40 -080051
52impl ForeignName {
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 let ident: Ident = syn::parse_str(text)?;
57 let text = ident.to_string();
58 Ok(ForeignName { text, span })
59 }
60}
61
62impl Display for ForeignName {
63 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
64 formatter.write_str(&self.text)
65 }
66}