diff --git a/.changes/android-package-underscores.md b/.changes/android-package-underscores.md new file mode 100644 index 000000000..a4f9cc99b --- /dev/null +++ b/.changes/android-package-underscores.md @@ -0,0 +1,6 @@ +--- +"tao-macros": patch +"tao": patch +--- + +Allow Android domain names to include `_1` as escaped `_` characters - required because `_` is the separator for domain parts. diff --git a/tao-macros/src/lib.rs b/tao-macros/src/lib.rs index b212e26d2..61b46a611 100644 --- a/tao-macros/src/lib.rs +++ b/tao-macros/src/lib.rs @@ -101,7 +101,7 @@ impl Parse for AndroidFnInput { /// 5. List of extra types your Rust function expects. Pass empty array if the function doesn't need any arugments. /// - If your function takes an arguments as reference with a lifetime tied to the [`JNIEnv`], it should use `'local` as the lifetime name as it is the /// lifetime name generated by the macro. -/// Note that all rust functions should expect the first two parameters to be [`JNIEnv`] and [`JClass`] so make sure they are imported into scope). +/// Note that all rust functions should expect the first two parameters to be [`JNIEnv`] and [`JClass`] so make sure they are imported into scope). /// 6. (Optional) Return type of your rust function. /// - If your function returns a reference with a lifetime tied to the [`JNIEnv`], it should use `'local` as the lifetime name as it is the /// lifetime name generated by the macro. @@ -202,7 +202,7 @@ pub fn android_fn(tokens: TokenStream) -> TokenStream { } = tokens; let domain = domain.to_string(); - let package = package.to_string().replace('_', "_1").replace('-', "_1"); + let package = package.to_string().replace('_', "_1"); let class = class.to_string(); let args = args .into_iter() @@ -273,6 +273,11 @@ impl Parse for GeneratePackageNameInput { /// 1. snake_case representation of the reversed domain of the app. /// 2. snake_case representation of the package name. /// +/// Note that `_` is the separator for the domain parts. +/// For instance the `com.tauri.app` identifier should be represented as +/// `generate_package_name!(com_tauri, app)`. +/// To escape the `_` character you can use `_1` which aligns with the default NDK implementation. +/// /// ## Example /// /// ``` @@ -295,8 +300,15 @@ pub fn generate_package_name(tokens: TokenStream) -> TokenStream { let tokens = parse_macro_input!(tokens as GeneratePackageNameInput); let GeneratePackageNameInput { domain, package } = tokens; - let domain = domain.to_string().replace('_', "/"); - let package = package.to_string().replace('-', "_"); + // note that this character is invalid in an identifier so it's safe to use as replacement + const TEMP_ESCAPE_UNDERSCORE_REPLACEMENT: &str = "<"; + + let domain = domain + .to_string() + .replace("_1", TEMP_ESCAPE_UNDERSCORE_REPLACEMENT) + .replace('_', "/") + .replace(TEMP_ESCAPE_UNDERSCORE_REPLACEMENT, "_"); + let package = package.to_string(); let path = format!("{}/{}", domain, package); let litstr = LitStr::new(&path, proc_macro2::Span::call_site());