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,)*) }
+}