use std::sync::Arc; use tauri::{path::BaseDirectory, Manager}; use tauri::http::{ Request as TauriRequest, Response as TauriResponse, }; use axum::body::{ Body as AxumBody, to_bytes, }; use axum::extract::Request as AxumRequest; use tokio::sync::{Mutex, MutexGuard}; use tower::{Service, ServiceExt}; async fn process_tauri_request( request: TauriRequest>, mut router: MutexGuard<'_, axum::Router>, ) -> TauriResponse> { // Convert the Tauri request to an Axum request let (parts, body) = request.into_parts(); let body = AxumBody::from(body); let request = AxumRequest::from_parts(parts, body); // Process the request with the router let response = router .as_service() .ready().await .expect("Failed to get ready service") .call(request).await .expect("Failed to get response from router"); // Convert the Axum response to a Tauri response let (parts, body) = response.into_parts(); let body = to_bytes(body, usize::MAX).await .expect("Failed to convert body to bytes") .to_vec(); let response = TauriResponse::from_parts(parts, body); response } #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { let assets_path = app .path() .resolve("assets", BaseDirectory::Resource) .expect("Path should be resolvable"); // Adds the router to the application state // This makes it so we can retrieve it from any app instance (see bellow) let router = Arc::new(Mutex::new( app::get_router(assets_path.as_path()).clone(), )); app.manage(router); Ok(()) }) .register_asynchronous_uri_scheme_protocol( "axum", move |app, request, responder| { // Retrieve the router from the application state and clone it for the async block let router = Arc::clone(&app.state::>>()); // Spawn a new async task to process the request tauri::async_runtime::spawn(async move { let router = router.lock().await; let response = process_tauri_request(request, router).await; responder.respond(response); }); } ) .run(tauri::generate_context!()) .expect("error while running tauri application"); }