Add a type-level encoding of qualified paths
diff --git a/macro/src/lib.rs b/macro/src/lib.rs
index b56f58e..bc8d19b 100644
--- a/macro/src/lib.rs
+++ b/macro/src/lib.rs
@@ -11,10 +11,11 @@
mod expand;
mod syntax;
+mod type_id;
use crate::syntax::namespace::Namespace;
use proc_macro::TokenStream;
-use syn::{parse_macro_input, ItemMod};
+use syn::{parse_macro_input, ItemMod, LitStr};
/// `#[cxx::bridge] mod ffi { ... }`
///
@@ -44,3 +45,9 @@
.unwrap_or_else(|err| err.to_compile_error())
.into()
}
+
+#[proc_macro]
+pub fn type_id(input: TokenStream) -> TokenStream {
+ let arg = parse_macro_input!(input as LitStr);
+ type_id::expand(arg).into()
+}
diff --git a/macro/src/type_id.rs b/macro/src/type_id.rs
new file mode 100644
index 0000000..15a5833
--- /dev/null
+++ b/macro/src/type_id.rs
@@ -0,0 +1,29 @@
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+use syn::LitStr;
+
+// "folly::File" => `(f, o, l, l, y, (), F, i, l, e)`
+pub fn expand(arg: LitStr) -> TokenStream {
+ let mut ids = Vec::new();
+
+ for word in arg.value().split("::") {
+ if !ids.is_empty() {
+ ids.push(quote!(()));
+ }
+ for ch in word.chars() {
+ ids.push(match ch {
+ 'A'..='Z' | 'a'..='z' => {
+ let t = format_ident!("{}", ch);
+ quote!(::cxx::private::#t)
+ }
+ '0'..='9' | '_' => {
+ let t = format_ident!("_{}", ch);
+ quote!(::cxx::private::#t)
+ }
+ _ => quote!([(); #ch as _]),
+ });
+ }
+ }
+
+ quote! { (#(#ids,)*) }
+}
diff --git a/src/lib.rs b/src/lib.rs
index cc0dcf2..39b1ecc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -376,6 +376,7 @@
mod rust_str;
mod rust_string;
mod rust_vec;
+mod type_id;
mod unique_ptr;
mod unwind;
@@ -386,7 +387,7 @@
pub use crate::cxx_vector::CxxVector;
pub use crate::exception::Exception;
pub use crate::unique_ptr::UniquePtr;
-pub use cxxbridge_macro::bridge;
+pub use cxxbridge_macro::{bridge, type_id};
// Not public API.
#[doc(hidden)]
@@ -399,6 +400,7 @@
pub use crate::rust_str::RustStr;
pub use crate::rust_string::RustString;
pub use crate::rust_vec::RustVec;
+ pub use crate::type_id::*;
pub use crate::unique_ptr::UniquePtrTarget;
pub use crate::unwind::catch_unwind;
}
diff --git a/src/type_id.rs b/src/type_id.rs
new file mode 100644
index 0000000..68020ea
--- /dev/null
+++ b/src/type_id.rs
@@ -0,0 +1,16 @@
+#![allow(non_camel_case_types)]
+
+macro_rules! chars {
+ ($($ch:ident)*) => {
+ $(
+ pub enum $ch {}
+ )*
+ };
+}
+
+chars! {
+ _0 _1 _2 _3 _4 _5 _6 _7 _8 _9
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+ a b c d e f g h i j k l m n o p q r s t u v w x y z
+ __ // underscore
+}