mobile.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. use proc_macro::TokenStream;
  5. use proc_macro2::TokenStream as TokenStream2;
  6. use quote::{format_ident, quote};
  7. use std::env::var;
  8. use syn::{parse_macro_input, spanned::Spanned, ItemFn};
  9. fn get_env_var(name: &str, error: &mut Option<TokenStream2>, function: &ItemFn) -> TokenStream2 {
  10. match var(name) {
  11. Ok(value) => {
  12. let ident = format_ident!("{value}");
  13. quote!(#ident)
  14. }
  15. Err(_) => {
  16. error.replace(
  17. syn::Error::new(
  18. function.span(),
  19. format!("`{name}` env var not set, do you have a build script with tauri-build?",),
  20. )
  21. .into_compile_error(),
  22. );
  23. quote!()
  24. }
  25. }
  26. }
  27. pub fn entry_point(_attributes: TokenStream, item: TokenStream) -> TokenStream {
  28. let function = parse_macro_input!(item as ItemFn);
  29. let function_name = function.sig.ident.clone();
  30. let mut error = None;
  31. let domain = get_env_var("TAURI_ANDROID_PACKAGE_NAME_PREFIX", &mut error, &function);
  32. let app_name = get_env_var("TAURI_ANDROID_PACKAGE_NAME_APP_NAME", &mut error, &function);
  33. let (wrapper, wrapper_name) = if function.sig.asyncness.is_some() {
  34. let wrapper_name = syn::Ident::new(&format!("{function_name}_wrapper"), function_name.span());
  35. (
  36. quote! {
  37. #function
  38. fn #wrapper_name() {
  39. ::tauri::async_runtime::block_on(#function_name());
  40. }
  41. },
  42. wrapper_name,
  43. )
  44. } else {
  45. (
  46. quote! {
  47. #function
  48. },
  49. function_name,
  50. )
  51. };
  52. if let Some(e) = error {
  53. quote!(#e).into()
  54. } else {
  55. quote!(
  56. fn stop_unwind<F: FnOnce() -> T, T>(f: F) -> T {
  57. match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
  58. Ok(t) => t,
  59. Err(err) => {
  60. eprintln!("attempt to unwind out of `rust` with err: {:?}", err);
  61. std::process::abort()
  62. }
  63. }
  64. }
  65. #wrapper
  66. fn _start_app() {
  67. #[cfg(target_os = "ios")]
  68. ::tauri::log_stdout();
  69. #[cfg(target_os = "android")]
  70. {
  71. ::tauri::android_binding!(#domain, #app_name, _start_app, ::tauri::wry);
  72. }
  73. stop_unwind(#wrapper_name);
  74. }
  75. // be careful when renaming this, the `start_app` symbol is checked by the CLI
  76. #[cfg(not(target_os = "android"))]
  77. #[no_mangle]
  78. #[inline(never)]
  79. pub extern "C" fn start_app() {
  80. _start_app()
  81. }
  82. )
  83. .into()
  84. }
  85. }