#[cfg(feature = "tokio-trace")] use std::any::type_name; use std::future::Future; #[cfg(feature = "tokio-trace")] use std::panic::Location; use tauri::{async_runtime, async_runtime::JoinHandle}; pub struct AsyncHandler; impl AsyncHandler { // pub fn handle() -> async_runtime::RuntimeHandle { // async_runtime::handle() // } #[track_caller] pub fn spawn(f: F) -> JoinHandle<()> where F: FnOnce() -> Fut + Send + 'static, Fut: Future + Send + 'static, { #[cfg(feature = "tokio-trace")] Self::log_task_info(&f); async_runtime::spawn(f()) } #[track_caller] pub fn spawn_blocking(f: F) -> JoinHandle where F: FnOnce() -> T + Send + 'static, T: Send + 'static, { #[cfg(feature = "tokio-trace")] Self::log_task_info(&f); async_runtime::spawn_blocking(f) } #[allow(dead_code)] #[track_caller] pub fn block_on(fut: Fut) -> Fut::Output where Fut: Future + Send + 'static, { #[cfg(feature = "tokio-trace")] Self::log_task_info(&fut); async_runtime::block_on(fut) } #[cfg(feature = "tokio-trace")] #[track_caller] fn log_task_info(f: &F) where F: ?Sized, { const TRACE_SPECIAL_SIZE: [usize; 3] = [0, 4, 24]; let size = std::mem::size_of_val(f); if TRACE_SPECIAL_SIZE.contains(&size) { return; } let location = Location::caller(); let type_str = type_name::(); let size_str = format!("{} bytes", size); let loc_str = format!( "{}:{}:{}", location.file(), location.line(), location.column() ); println!( "┌────────────────────┬─────────────────────────────────────────────────────────────────────────────┐" ); println!("│ {:<18} │ {:<80} │", "Field", "Value"); println!( "├────────────────────┼─────────────────────────────────────────────────────────────────────────────┤" ); println!("│ {:<18} │ {:<80} │", "Type of task", type_str); println!("│ {:<18} │ {:<80} │", "Size of task", size_str); println!("│ {:<18} │ {:<80} │", "Called from", loc_str); println!( "└────────────────────┴─────────────────────────────────────────────────────────────────────────────┘" ); } }