Add ForeignName wrapper around non-Rust names
diff --git a/syntax/names.rs b/syntax/names.rs
index c4cbcff..b2ae013 100644
--- a/syntax/names.rs
+++ b/syntax/names.rs
@@ -1,25 +1,37 @@
+use crate::syntax::symbol::Segment;
use crate::syntax::{Lifetimes, NamedType, Pair, Symbol};
use proc_macro2::{Ident, Span};
+use std::fmt::{self, Display};
use std::iter;
+use syn::parse::Result;
use syn::punctuated::Punctuated;
+#[derive(Clone)]
+pub struct ForeignName {
+ text: String,
+ span: Span,
+}
+
impl Pair {
pub fn to_symbol(&self) -> Symbol {
- Symbol::from_idents(self.iter_all_segments())
+ let segments = self
+ .namespace
+ .iter()
+ .map(|ident| ident as &dyn Segment)
+ .chain(iter::once(&self.cxx as &dyn Segment));
+ Symbol::from_idents(segments)
}
pub fn to_fully_qualified(&self) -> String {
let mut fully_qualified = String::new();
- for segment in self.iter_all_segments() {
+ for segment in &self.namespace {
fully_qualified += "::";
fully_qualified += &segment.to_string();
}
+ fully_qualified += "::";
+ fully_qualified += &self.cxx.to_string();
fully_qualified
}
-
- fn iter_all_segments(&self) -> impl Iterator<Item = &Ident> {
- self.namespace.iter().chain(iter::once(&self.cxx))
- }
}
impl NamedType {
@@ -36,3 +48,19 @@
self.rust.span()
}
}
+
+impl ForeignName {
+ pub fn parse(text: &str, span: Span) -> Result<Self> {
+ // TODO: support C++ names containing whitespace (`unsigned int`) or
+ // non-alphanumeric characters (`operator++`).
+ let ident: Ident = syn::parse_str(text)?;
+ let text = ident.to_string();
+ Ok(ForeignName { text, span })
+ }
+}
+
+impl Display for ForeignName {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(&self.text)
+ }
+}