Allow namespace override.
This change allows a
#[namespace (namespace = A::B)]
attribute for each item in a cxx::bridge.
We now have a fair number of different types of name floating
around:
* C++ identifiers
* C++ fully-qualified names
* Rust identifiers
* Rust fully-qualified names (future, when we support sub-modules)
* Items with both a Rust and C++ name (a 'Pair')
* Types with only a known Rust name, which can be resolved to a
C++ name.
This change attempts to put some sensible names for all these
things in syntax/mod.rs, and so that would be a good place to start
review.
At the moment, the Namespace (included in each CppName)
is ruthlessly cloned all over the place. As a given namespace is
likely to be applicable to many types and functions, it may
save significant memory in future to use Rc<> here. But let's not
optimise too early.
diff --git a/syntax/mod.rs b/syntax/mod.rs
index c8dea67..bb9566d 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -21,7 +21,9 @@
pub mod types;
use self::discriminant::Discriminant;
+use self::namespace::Namespace;
use self::parse::kw;
+use self::symbol::Symbol;
use proc_macro2::{Ident, Span};
use syn::punctuated::Punctuated;
use syn::token::{Brace, Bracket, Paren};
@@ -33,6 +35,29 @@
pub use self::parse::parse_items;
pub use self::types::Types;
+/// A Rust identifier will forver == a proc_macro2::Ident,
+/// but for completeness here's a type alias.
+pub type RsIdent = Ident;
+
+/// At the moment, a Rust name is simply a proc_macro2::Ident.
+/// In the future, it may become namespaced based on a mod path.
+pub type RsName = RsIdent;
+
+/// At the moment, a C++ identifier is also a proc_macro2::Ident.
+/// In the future, we may wish to make a newtype wrapper here
+/// to avoid confusion between C++ and Rust identifiers.
+pub type CppIdent = Ident;
+
+#[derive(Clone)]
+/// A C++ identifier in a particular namespace.
+/// It is intentional that this does not impl Display,
+/// because we want to force users actively to decide whether to output
+/// it as a qualified name or as an unqualfiied name.
+pub struct CppName {
+ pub ns: Namespace,
+ pub ident: CppIdent,
+}
+
pub enum Api {
Include(String),
Struct(Struct),
@@ -48,7 +73,7 @@
pub struct ExternType {
pub doc: Doc,
pub type_token: Token![type],
- pub ident: Ident,
+ pub ident: Pair,
pub semi_token: Token![;],
pub trusted: bool,
}
@@ -57,7 +82,7 @@
pub doc: Doc,
pub derives: Vec<Derive>,
pub struct_token: Token![struct],
- pub ident: Ident,
+ pub ident: Pair,
pub brace_token: Brace,
pub fields: Vec<Var>,
}
@@ -65,15 +90,18 @@
pub struct Enum {
pub doc: Doc,
pub enum_token: Token![enum],
- pub ident: Ident,
+ pub ident: Pair,
pub brace_token: Brace,
pub variants: Vec<Variant>,
pub repr: Atom,
}
+/// A type with a defined Rust name and a fully resolved,
+/// qualified, namespaced, C++ name.
+#[derive(Clone)]
pub struct Pair {
- pub cxx: Ident,
- pub rust: Ident,
+ pub cxx: CppName,
+ pub rust: RsName,
}
pub struct ExternFn {
@@ -87,7 +115,7 @@
pub struct TypeAlias {
pub doc: Doc,
pub type_token: Token![type],
- pub ident: Ident,
+ pub ident: Pair,
pub eq_token: Token![=],
pub ty: RustType,
pub semi_token: Token![;],
@@ -112,7 +140,7 @@
#[derive(Eq, PartialEq, Hash)]
pub struct Var {
- pub ident: Ident,
+ pub ident: RsIdent, // fields and variables are not namespaced
pub ty: Type,
}
@@ -121,18 +149,18 @@
pub lifetime: Option<Lifetime>,
pub mutability: Option<Token![mut]>,
pub var: Token![self],
- pub ty: Ident,
+ pub ty: ResolvableName,
pub shorthand: bool,
}
pub struct Variant {
- pub ident: Ident,
+ pub ident: RsIdent,
pub discriminant: Discriminant,
pub expr: Option<Expr>,
}
pub enum Type {
- Ident(Ident),
+ Ident(ResolvableName),
RustBox(Box<Ty1>),
RustVec(Box<Ty1>),
UniquePtr(Box<Ty1>),
@@ -146,7 +174,7 @@
}
pub struct Ty1 {
- pub name: Ident,
+ pub name: ResolvableName,
pub langle: Token![<],
pub inner: Type,
pub rangle: Token![>],
@@ -169,3 +197,10 @@
Cxx,
Rust,
}
+
+/// Wrapper for a type which needs to be resolved
+/// before it can be printed in C++.
+#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
+pub struct ResolvableName {
+ pub rust: RsName,
+}