diff --git a/Cargo.lock b/Cargo.lock index 8a69c3fad..e64685d9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6349,8 +6349,6 @@ name = "sage-apps" version = "0.1.0" dependencies = [ "anyhow", - "async-trait", - "erased-serde", "futures", "hex", "mime_guess", @@ -6504,7 +6502,6 @@ name = "sage-tauri" version = "0.12.10" dependencies = [ "anyhow", - "async-trait", "aws-lc-rs", "chia-wallet-sdk", "futures", diff --git a/crates/sage-apps/Cargo.toml b/crates/sage-apps/Cargo.toml index f896ccfbf..a16b9a7a7 100644 --- a/crates/sage-apps/Cargo.toml +++ b/crates/sage-apps/Cargo.toml @@ -28,8 +28,6 @@ tempfile = "3" zip = "8.5.1" mime_guess = "2" url = "2" -async-trait = "0.1.89" -erased-serde = "0.4.9" serde_path_to_error = "0.1.20" parking_lot = "0.12.5" futures = "0.3.32" diff --git a/crates/sage-apps/src/bridge/bridge_request.rs b/crates/sage-apps/src/bridge/bridge_request.rs index b3c42f4ca..619587d68 100644 --- a/crates/sage-apps/src/bridge/bridge_request.rs +++ b/crates/sage-apps/src/bridge/bridge_request.rs @@ -2,14 +2,15 @@ use tauri::{AppHandle, Manager, State, Webview}; use crate::{ AppState, AppsHostState, BridgeApprovalsChangedEvent, BridgeCapability, BridgeContext, - BridgeMethod, BridgeMethodCapability, BridgeOrigin, BridgeRegistry, BridgeRegistryKind, + BridgeMethodCapability, BridgeMethodEntry, BridgeOrigin, BridgeRegistry, BridgeRegistryKind, BridgeTools, ResolveBridgeApprovalArgs, RustBridgeApprovalRequest, RustBridgeInvokeResult, RustBridgeRequest, RustBridgeResponse, SharedSageApp, SystemBridgeCapability, - UserBridgeCapability, assert_bridge_origin, emit_bridge_response_to_app, - emit_system_runtime_event_to_listeners, ensure_app_is_enabled_for_scope, - ensure_approval_expiry_loop, get_pending_approval, get_system_capability_definition, - get_user_capability_definition, list_pending_approvals, remove_pending_approval, resolve_app, - start_bridge_approval_runtime, sync_bridge_approval_runtime, write_pending_approval, + UserBridgeCapability, UserBridgeMethodEntry, UserBridgeRegistry, assert_bridge_origin, + emit_bridge_response_to_app, emit_system_runtime_event_to_listeners, + ensure_app_is_enabled_for_scope, ensure_approval_expiry_loop, get_pending_approval, + get_system_capability_definition, get_user_capability_definition, list_pending_approvals, + remove_pending_approval, resolve_app, start_bridge_approval_runtime, + sync_bridge_approval_runtime, write_pending_approval, }; pub(crate) async fn process( @@ -103,15 +104,12 @@ pub(crate) async fn process_after_approval( assert_bridge_origin(app_handle, &app.with_app(SharedSageApp::webview_label)).await?; let invoke_result = if args.approved { - process_shared( - app_handle, - app_state, - &origin, - pending.registry_kind, - &pending.request, - true, - ) - .await? + if pending.registry_kind != BridgeRegistryKind::User { + return Err("only user bridge approvals can be resolved".to_string()); + } + + execute_approved_user_bridge_request(app_handle, app_state, &origin, &pending.request) + .await? } else { RustBridgeInvokeResult::error( &pending.request.id, @@ -125,6 +123,44 @@ pub(crate) async fn process_after_approval( Ok(()) } +async fn execute_approved_user_bridge_request( + app_handle: &AppHandle, + app_state: &State<'_, AppState>, + origin: &BridgeOrigin, + request: &RustBridgeRequest, +) -> Result { + let registry = UserBridgeRegistry::new(); + let app = &origin.app; + + if let Err(err) = ensure_app_is_enabled_for_scope(app_state, app).await { + return Ok(RustBridgeInvokeResult::error( + &request.id, + "app_not_enabled_for_scope", + err, + )); + } + + let method = match assert_user_method(®istry, request) { + Ok(method) => method, + Err(response) => return Ok(response.into()), + }; + + match method.capability() { + BridgeMethodCapability::Ungated => {} + BridgeMethodCapability::Required(capability) => { + if let Err(response) = verify_capability(&origin.app, request, capability) { + return Ok(response.into()); + } + } + } + + Ok( + execute_user_bridge_request(app_handle, app_state, origin, registry, request) + .await + .into(), + ) +} + async fn process_shared( app_handle: &AppHandle, app_state: &State<'_, AppState>, @@ -210,14 +246,37 @@ async fn execute_bridge_request( .await; match result { - Ok(value) => match erased_serde::serialize(&*value, serde_json::value::Serializer) { - Ok(value) => RustBridgeResponse::success(&request.id, &value), - Err(err) => RustBridgeResponse::error( - &request.id, - "internal_error", - format!("failed to encode {} result: {err}", method.name()), - ), - }, + Ok(value) => RustBridgeResponse::success(&request.id, &value), + Err(err) => RustBridgeResponse::error(&request.id, err.code, err.message), + } +} + +async fn execute_user_bridge_request( + app_handle: &AppHandle, + app_state: &State<'_, AppState>, + origin: &BridgeOrigin, + registry: UserBridgeRegistry, + request: &RustBridgeRequest, +) -> RustBridgeResponse { + let method = match assert_user_method(®istry, request) { + Ok(method) => method, + Err(response) => return response, + }; + + let result = method + .handle( + BridgeContext { app: &origin.app }, + BridgeTools { + app_handle, + app_state, + host_state: &app_handle.state::(), + }, + request, + ) + .await; + + match result { + Ok(value) => RustBridgeResponse::success(&request.id, &value), Err(err) => RustBridgeResponse::error(&request.id, err.code, err.message), } } @@ -345,7 +404,22 @@ fn verify_system_capability( fn assert_method<'a>( registry: &'a BridgeRegistry, request: &RustBridgeRequest, -) -> Result<&'a dyn BridgeMethod, RustBridgeResponse> { +) -> Result, RustBridgeResponse> { + let Some(method) = registry.get(&request.method) else { + return Err(RustBridgeResponse::error( + &request.id, + "method_not_found", + format!("Unknown bridge method: {}", request.method), + )); + }; + + Ok(method) +} + +fn assert_user_method<'a>( + registry: &'a UserBridgeRegistry, + request: &RustBridgeRequest, +) -> Result<&'a UserBridgeMethodEntry, RustBridgeResponse> { let Some(method) = registry.get(&request.method) else { return Err(RustBridgeResponse::error( &request.id, diff --git a/crates/sage-apps/src/bridge/methods/shared.rs b/crates/sage-apps/src/bridge/methods/shared.rs index 8851d1c6d..56d701cd9 100644 --- a/crates/sage-apps/src/bridge/methods/shared.rs +++ b/crates/sage-apps/src/bridge/methods/shared.rs @@ -1,13 +1,15 @@ -use async_trait::async_trait; +use std::future::Future; + +use serde::Serialize; use serde::de::DeserializeOwned; +use serde_json::Value; use crate::{ AppState, AppsHostState, BridgeCapability, RustBridgeApprovalRequest, RustBridgeRequest, SharedSageApp, SystemBridgeCapability, UserBridgeCapability, }; -#[async_trait] -pub(crate) trait BridgeMethod: Send + Sync { +pub(crate) trait BridgeMethodHandler: Send + Sync { fn name(&self) -> &'static str; fn capability(&self) -> BridgeMethodCapability; @@ -17,12 +19,12 @@ pub(crate) trait BridgeMethod: Send + Sync { request: &RustBridgeRequest, ) -> BridgeApprovalRequestResult; - async fn handle( + fn handle( &self, ctx: BridgeContext<'_>, tools: BridgeTools<'_>, request: &RustBridgeRequest, - ) -> BridgeHandleResult; + ) -> impl Future + Send; } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -69,8 +71,13 @@ impl BridgeMethodHandleError { } } -pub(crate) type BridgeHandleResult = - Result, BridgeMethodHandleError>; +pub(crate) type BridgeHandleResult = Result; + +pub(crate) fn bridge_result(value: impl Serialize) -> BridgeHandleResult { + serde_json::to_value(value).map_err(|err| { + BridgeMethodHandleError::internal_error(format!("failed to encode bridge result: {err}")) + }) +} impl BridgeMethodCapability { pub(super) fn ungated() -> Self { @@ -87,7 +94,7 @@ impl BridgeMethodCapability { } pub(crate) fn parse_required_params( - method: &impl BridgeMethod, + method: &impl BridgeMethodHandler, request: &RustBridgeRequest, ) -> Result where diff --git a/crates/sage-apps/src/bridge/methods/system/app_install/install_url.rs b/crates/sage-apps/src/bridge/methods/system/app_install/install_url.rs index 3b2d04da5..eff1ec518 100644 --- a/crates/sage-apps/src/bridge/methods/system/app_install/install_url.rs +++ b/crates/sage-apps/src/bridge/methods/system/app_install/install_url.rs @@ -1,15 +1,15 @@ use std::io; -use async_trait::async_trait; use serde::Deserialize; use specta::Type; use tauri::{AppHandle, Manager, State}; use crate::{ AppInstallInstallResult, AppState, AppsHostState, BridgeApprovalRequestResult, BridgeContext, - BridgeHandleResult, BridgeMethod, BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, - Result, RustBridgeRequest, SageAppUrl, SageAppWalletScope, SageGrantedPermissionsInput, - SystemBridgeCapability, UserSageAppView, install_app_from_source, parse_required_params, + BridgeHandleResult, BridgeMethodCapability, BridgeMethodHandleError, BridgeMethodHandler, + BridgeTools, Result, RustBridgeRequest, SageAppUrl, SageAppWalletScope, + SageGrantedPermissionsInput, SystemBridgeCapability, UserSageAppView, bridge_result, + install_app_from_source, parse_required_params, }; #[derive(Debug, Deserialize, Type)] @@ -23,8 +23,7 @@ pub struct AppInstallInstallUrlParams { #[derive(Debug, Clone, Copy)] pub(crate) struct AppInstallInstallUrl; -#[async_trait] -impl BridgeMethod for AppInstallInstallUrl { +impl BridgeMethodHandler for AppInstallInstallUrl { fn name(&self) -> &'static str { "appInstall.installUrl" } @@ -61,7 +60,7 @@ impl BridgeMethod for AppInstallInstallUrl { .await .map_err(|err| BridgeMethodHandleError::internal_error(err.to_string()))?; - Ok(Box::new(AppInstallInstallResult::new(app))) + bridge_result(AppInstallInstallResult::new(app)) } } diff --git a/crates/sage-apps/src/bridge/methods/system/app_install/install_zip.rs b/crates/sage-apps/src/bridge/methods/system/app_install/install_zip.rs index 5e21d67ea..cdfab7221 100644 --- a/crates/sage-apps/src/bridge/methods/system/app_install/install_zip.rs +++ b/crates/sage-apps/src/bridge/methods/system/app_install/install_zip.rs @@ -1,16 +1,15 @@ use std::{fs, io}; -use async_trait::async_trait; use serde::Deserialize; use specta::Type; use tauri::{AppHandle, Manager, State}; -use super::AppInstallInstallResult; use crate::{ - AppState, AppsHostState, BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, - BridgeMethod, BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, Result, - RustBridgeRequest, SageAppWalletScope, SageGrantedPermissionsInput, SystemBridgeCapability, - UserSageAppView, ZipInstallSource, apps_root, install_app_from_source, parse_required_params, + AppInstallInstallResult, AppState, AppsHostState, BridgeApprovalRequestResult, BridgeContext, + BridgeHandleResult, BridgeMethodCapability, BridgeMethodHandleError, BridgeMethodHandler, + BridgeTools, Result, RustBridgeRequest, SageAppWalletScope, SageGrantedPermissionsInput, + SystemBridgeCapability, UserSageAppView, ZipInstallSource, apps_root, bridge_result, + install_app_from_source, parse_required_params, }; #[derive(Debug, Deserialize, Type)] @@ -24,8 +23,7 @@ pub struct AppInstallInstallZipParams { #[derive(Debug, Clone, Copy)] pub(crate) struct AppInstallInstallZip; -#[async_trait] -impl BridgeMethod for AppInstallInstallZip { +impl BridgeMethodHandler for AppInstallInstallZip { fn name(&self) -> &'static str { "appInstall.installZip" } @@ -62,7 +60,7 @@ impl BridgeMethod for AppInstallInstallZip { .await .map_err(|err| BridgeMethodHandleError::internal_error(err.to_string()))?; - Ok(Box::new(AppInstallInstallResult::new(app))) + bridge_result(AppInstallInstallResult::new(app)) } } diff --git a/crates/sage-apps/src/bridge/methods/system/app_install/preview_url.rs b/crates/sage-apps/src/bridge/methods/system/app_install/preview_url.rs index fe9efae06..a96d40278 100644 --- a/crates/sage-apps/src/bridge/methods/system/app_install/preview_url.rs +++ b/crates/sage-apps/src/bridge/methods/system/app_install/preview_url.rs @@ -1,11 +1,11 @@ -use async_trait::async_trait; use serde::Deserialize; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, SageAppUrl, - SageAppUrlPreview, SystemBridgeCapability, fetch_url_manifest_preview, parse_required_params, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageAppUrl, + SageAppUrlPreview, SystemBridgeCapability, bridge_result, fetch_url_manifest_preview, + parse_required_params, }; #[derive(Debug, Deserialize, Type)] @@ -17,8 +17,7 @@ pub struct AppInstallPreviewUrlParams { #[derive(Debug, Clone, Copy)] pub(crate) struct AppInstallPreviewUrl; -#[async_trait] -impl BridgeMethod for AppInstallPreviewUrl { +impl BridgeMethodHandler for AppInstallPreviewUrl { fn name(&self) -> &'static str { "appInstall.previewUrl" } @@ -47,7 +46,7 @@ impl BridgeMethod for AppInstallPreviewUrl { .await .map_err(BridgeMethodHandleError::internal_error)?; - Ok(Box::new(preview)) + bridge_result(preview) } } diff --git a/crates/sage-apps/src/bridge/methods/system/app_install/preview_zip.rs b/crates/sage-apps/src/bridge/methods/system/app_install/preview_zip.rs index 0a606b629..730c08282 100644 --- a/crates/sage-apps/src/bridge/methods/system/app_install/preview_zip.rs +++ b/crates/sage-apps/src/bridge/methods/system/app_install/preview_zip.rs @@ -1,16 +1,15 @@ use std::fs; use std::path::Path; -use async_trait::async_trait; use serde::Deserialize; use specta::Type; use uuid::Uuid; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - SageAppPackageManifest, SystemBridgeCapability, detect_package_root, parse_required_params, - read_manifest, unzip_to_dir, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + SageAppPackageManifest, SystemBridgeCapability, bridge_result, detect_package_root, + parse_required_params, read_manifest, unzip_to_dir, }; #[derive(Debug, Deserialize, Type)] @@ -22,8 +21,7 @@ pub struct AppInstallPreviewZipParams { #[derive(Debug, Clone, Copy)] pub(crate) struct AppInstallPreviewZip; -#[async_trait] -impl BridgeMethod for AppInstallPreviewZip { +impl BridgeMethodHandler for AppInstallPreviewZip { fn name(&self) -> &'static str { "appInstall.previewZip" } @@ -51,7 +49,7 @@ impl BridgeMethod for AppInstallPreviewZip { let manifest = preview_manifest(¶ms.zip_path).map_err(BridgeMethodHandleError::internal_error)?; - Ok(Box::new(manifest)) + bridge_result(manifest) } } diff --git a/crates/sage-apps/src/bridge/methods/system/app_permissions/apply_permissions.rs b/crates/sage-apps/src/bridge/methods/system/app_permissions/apply_permissions.rs index ad0aa5b70..62d3faf7d 100644 --- a/crates/sage-apps/src/bridge/methods/system/app_permissions/apply_permissions.rs +++ b/crates/sage-apps/src/bridge/methods/system/app_permissions/apply_permissions.rs @@ -1,12 +1,11 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, SageApp, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageApp, SageAppWalletScope, SageGrantedPermissionsInput, SystemBridgeCapability, UserSageAppView, - parse_required_params, resolve_app, update_app_permissions_for_app, + bridge_result, parse_required_params, resolve_app, update_app_permissions_for_app, update_app_wallet_scope_for_app, }; @@ -27,8 +26,7 @@ pub struct AppPermissionsApplyPermissionsResult { #[derive(Debug, Clone, Copy)] pub(crate) struct AppPermissionsApplyPermissions; -#[async_trait] -impl BridgeMethod for AppPermissionsApplyPermissions { +impl BridgeMethodHandler for AppPermissionsApplyPermissions { fn name(&self) -> &'static str { "appPermissions.applyPermissions" } @@ -109,8 +107,6 @@ impl BridgeMethod for AppPermissionsApplyPermissions { )) })?; - Ok(Box::new(AppPermissionsApplyPermissionsResult { - app: app_view, - })) + bridge_result(AppPermissionsApplyPermissionsResult { app: app_view }) } } diff --git a/crates/sage-apps/src/bridge/methods/system/app_permissions/get_review_context.rs b/crates/sage-apps/src/bridge/methods/system/app_permissions/get_review_context.rs index 7ba712bce..d1caa694b 100644 --- a/crates/sage-apps/src/bridge/methods/system/app_permissions/get_review_context.rs +++ b/crates/sage-apps/src/bridge/methods/system/app_permissions/get_review_context.rs @@ -1,11 +1,10 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, SageApp, - SystemBridgeCapability, UserSageAppView, parse_required_params, resolve_app, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageApp, + SystemBridgeCapability, UserSageAppView, bridge_result, parse_required_params, resolve_app, }; #[derive(Debug, Clone, Deserialize, Serialize, Type)] @@ -23,8 +22,7 @@ pub struct AppPermissionsReviewContext { #[derive(Debug, Clone, Copy)] pub(crate) struct AppPermissionsGetReviewContext; -#[async_trait] -impl BridgeMethod for AppPermissionsGetReviewContext { +impl BridgeMethodHandler for AppPermissionsGetReviewContext { fn name(&self) -> &'static str { "appPermissions.getReviewContext" } @@ -72,6 +70,6 @@ impl BridgeMethod for AppPermissionsGetReviewContext { )) })?; - Ok(Box::new(AppPermissionsReviewContext { app })) + bridge_result(AppPermissionsReviewContext { app }) } } diff --git a/crates/sage-apps/src/bridge/methods/system/app_update/apply_update.rs b/crates/sage-apps/src/bridge/methods/system/app_update/apply_update.rs index ecc3cd44a..1b3249109 100644 --- a/crates/sage-apps/src/bridge/methods/system/app_update/apply_update.rs +++ b/crates/sage-apps/src/bridge/methods/system/app_update/apply_update.rs @@ -1,11 +1,10 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, SageAppView, - SageGrantedPermissionsInput, SystemBridgeCapability, apply_app_update_inner, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageAppView, + SageGrantedPermissionsInput, SystemBridgeCapability, apply_app_update_inner, bridge_result, parse_required_params, }; @@ -25,8 +24,7 @@ pub struct AppUpdateApplyUpdateResult { #[derive(Debug, Clone, Copy)] pub(crate) struct AppUpdateApplyUpdate; -#[async_trait] -impl BridgeMethod for AppUpdateApplyUpdate { +impl BridgeMethodHandler for AppUpdateApplyUpdate { fn name(&self) -> &'static str { "appUpdate.applyUpdate" } @@ -65,6 +63,6 @@ impl BridgeMethod for AppUpdateApplyUpdate { )) })?; - Ok(Box::new(AppUpdateApplyUpdateResult { app })) + bridge_result(AppUpdateApplyUpdateResult { app }) } } diff --git a/crates/sage-apps/src/bridge/methods/system/app_update/get_review_context.rs b/crates/sage-apps/src/bridge/methods/system/app_update/get_review_context.rs index b758249da..d08a69f4e 100644 --- a/crates/sage-apps/src/bridge/methods/system/app_update/get_review_context.rs +++ b/crates/sage-apps/src/bridge/methods/system/app_update/get_review_context.rs @@ -1,12 +1,11 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, SageApp, - SageAppUrlPreview, SystemBridgeCapability, UserSageAppView, check_app_update_inner, - parse_required_params, resolve_app, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageApp, + SageAppUrlPreview, SystemBridgeCapability, UserSageAppView, bridge_result, + check_app_update_inner, parse_required_params, resolve_app, }; #[derive(Debug, Clone, Deserialize, Serialize, Type)] @@ -27,8 +26,7 @@ pub struct AppUpdateReviewContext { #[derive(Debug, Clone, Copy)] pub(crate) struct AppUpdateGetReviewContext; -#[async_trait] -impl BridgeMethod for AppUpdateGetReviewContext { +impl BridgeMethodHandler for AppUpdateGetReviewContext { fn name(&self) -> &'static str { "appUpdate.getReviewContext" } @@ -85,6 +83,6 @@ impl BridgeMethod for AppUpdateGetReviewContext { )) })?; - Ok(Box::new(AppUpdateReviewContext { app, preview })) + bridge_result(AppUpdateReviewContext { app, preview }) } } diff --git a/crates/sage-apps/src/bridge/methods/system/bridge_approvals/list.rs b/crates/sage-apps/src/bridge/methods/system/bridge_approvals/list.rs index 03c7a6ab0..06f3b74f4 100644 --- a/crates/sage-apps/src/bridge/methods/system/bridge_approvals/list.rs +++ b/crates/sage-apps/src/bridge/methods/system/bridge_approvals/list.rs @@ -1,11 +1,10 @@ -use async_trait::async_trait; use serde::Serialize; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, PendingBridgeApproval, RustBridgeApprovalRequest, - RustBridgeRequest, SystemBridgeCapability, list_pending_approvals, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, PendingBridgeApproval, RustBridgeApprovalRequest, + RustBridgeRequest, SystemBridgeCapability, bridge_result, list_pending_approvals, }; #[derive(Debug, Clone, Copy)] @@ -21,8 +20,7 @@ pub(crate) struct PendingBridgeApprovalView { pub expires_at_ms: u64, } -#[async_trait] -impl BridgeMethod for BridgeApprovalsListPending { +impl BridgeMethodHandler for BridgeApprovalsListPending { fn name(&self) -> &'static str { "bridgeApprovals.listPending" } @@ -50,7 +48,7 @@ impl BridgeMethod for BridgeApprovalsListPending { .into_iter() .map(PendingBridgeApprovalView::from) .collect::>(); - Ok(Box::new(approvals)) + bridge_result(approvals) } } diff --git a/crates/sage-apps/src/bridge/methods/system/bridge_approvals/resolve.rs b/crates/sage-apps/src/bridge/methods/system/bridge_approvals/resolve.rs index b4fe8e491..6b0d9ae53 100644 --- a/crates/sage-apps/src/bridge/methods/system/bridge_approvals/resolve.rs +++ b/crates/sage-apps/src/bridge/methods/system/bridge_approvals/resolve.rs @@ -1,16 +1,14 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, ResolveBridgeApprovalArgs, - RustBridgeRequest, SystemBridgeCapability, parse_required_params, process_after_approval, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, ResolveBridgeApprovalArgs, + RustBridgeRequest, SystemBridgeCapability, bridge_result, parse_required_params, + process_after_approval, }; #[derive(Debug, Clone, Copy)] pub(crate) struct BridgeApprovalsResolve; -#[async_trait] -impl BridgeMethod for BridgeApprovalsResolve { +impl BridgeMethodHandler for BridgeApprovalsResolve { fn name(&self) -> &'static str { "bridgeApprovals.resolve" } @@ -39,6 +37,6 @@ impl BridgeMethod for BridgeApprovalsResolve { .await .map_err(BridgeMethodHandleError::internal_error)?; - Ok(Box::new(())) + bridge_result(()) } } diff --git a/crates/sage-apps/src/bridge/methods/system/capabilities/list_user_definitions.rs b/crates/sage-apps/src/bridge/methods/system/capabilities/list_user_definitions.rs index be5275114..166c02f73 100644 --- a/crates/sage-apps/src/bridge/methods/system/capabilities/list_user_definitions.rs +++ b/crates/sage-apps/src/bridge/methods/system/capabilities/list_user_definitions.rs @@ -1,16 +1,13 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, RustBridgeRequest, SageAppCapabilityDefinitionView, - SystemBridgeCapability, user_registry, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageAppCapabilityDefinitionView, + SystemBridgeCapability, bridge_result, user_registry, }; #[derive(Debug, Clone, Copy)] pub(crate) struct CapabilitiesListUserDefinitions; -#[async_trait] -impl BridgeMethod for CapabilitiesListUserDefinitions { +impl BridgeMethodHandler for CapabilitiesListUserDefinitions { fn name(&self) -> &'static str { "capabilities.listUserDefinitions" } @@ -38,6 +35,6 @@ impl BridgeMethod for CapabilitiesListUserDefinitions { .map(Into::into) .collect::>(); - Ok(Box::new(definitions)) + bridge_result(definitions) } } diff --git a/crates/sage-apps/src/bridge/methods/system/donation/get_details.rs b/crates/sage-apps/src/bridge/methods/system/donation/get_details.rs index 983b6d879..c6ebb7150 100644 --- a/crates/sage-apps/src/bridge/methods/system/donation/get_details.rs +++ b/crates/sage-apps/src/bridge/methods/system/donation/get_details.rs @@ -1,11 +1,10 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - SageAppIconView, SystemBridgeCapability, parse_required_params, resolve_app, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageAppIconView, + SystemBridgeCapability, bridge_result, parse_required_params, resolve_app, }; #[derive(Debug, Clone, Deserialize, Type)] @@ -28,8 +27,7 @@ pub struct DonationDetails { #[derive(Debug, Clone, Copy)] pub(crate) struct DonationGetDetails; -#[async_trait] -impl BridgeMethod for DonationGetDetails { +impl BridgeMethodHandler for DonationGetDetails { fn name(&self) -> &'static str { "donations.getDetails" } @@ -82,6 +80,6 @@ impl BridgeMethod for DonationGetDetails { }) .map_err(BridgeMethodHandleError::invalid_request)?; - Ok(Box::new(details)) + bridge_result(details) } } diff --git a/crates/sage-apps/src/bridge/methods/system/file_system/select_file.rs b/crates/sage-apps/src/bridge/methods/system/file_system/select_file.rs index 456f9b540..009fe7a3e 100644 --- a/crates/sage-apps/src/bridge/methods/system/file_system/select_file.rs +++ b/crates/sage-apps/src/bridge/methods/system/file_system/select_file.rs @@ -1,11 +1,10 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use tauri_plugin_dialog::DialogExt; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, RustBridgeRequest, SystemBridgeCapability, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, RustBridgeRequest, SystemBridgeCapability, bridge_result, parse_required_params, }; @@ -35,8 +34,7 @@ pub struct FileSystemSelectFileResult { #[derive(Debug, Clone, Copy)] pub(crate) struct FileSystemSelectFile; -#[async_trait] -impl BridgeMethod for FileSystemSelectFile { +impl BridgeMethodHandler for FileSystemSelectFile { fn name(&self) -> &'static str { "fileSystem.selectFile" } @@ -79,6 +77,6 @@ impl BridgeMethod for FileSystemSelectFile { let selected = dialog.blocking_pick_file().map(|path| path.to_string()); - Ok(Box::new(FileSystemSelectFileResult { path: selected })) + bridge_result(FileSystemSelectFileResult { path: selected }) } } diff --git a/crates/sage-apps/src/bridge/methods/system/runtime_manager/close_self.rs b/crates/sage-apps/src/bridge/methods/system/runtime_manager/close_self.rs index 790ead5e9..cd54ad210 100644 --- a/crates/sage-apps/src/bridge/methods/system/runtime_manager/close_self.rs +++ b/crates/sage-apps/src/bridge/methods/system/runtime_manager/close_self.rs @@ -1,16 +1,13 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, RustBridgeRequest, SystemBridgeCapability, - SystemKillRuntimeError, kill_runtime, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, RustBridgeRequest, SystemBridgeCapability, + SystemKillRuntimeError, bridge_result, kill_runtime, }; #[derive(Debug, Clone, Copy)] pub(crate) struct RuntimeManagerCloseSelf; -#[async_trait] -impl BridgeMethod for RuntimeManagerCloseSelf { +impl BridgeMethodHandler for RuntimeManagerCloseSelf { fn name(&self) -> &'static str { "runtimeManager.closeSelf" } @@ -38,7 +35,7 @@ impl BridgeMethod for RuntimeManagerCloseSelf { match kill_runtime(tools.app_handle, tools.host_state, &app_id, "self_close").await { Ok(()) | Err(SystemKillRuntimeError::NotFound | SystemKillRuntimeError::RuntimeSync(_)) => { - Ok(Box::new(())) + bridge_result(()) } } } diff --git a/crates/sage-apps/src/bridge/methods/system/runtime_manager/focus_runtime.rs b/crates/sage-apps/src/bridge/methods/system/runtime_manager/focus_runtime.rs index 694d451a9..497e93f71 100644 --- a/crates/sage-apps/src/bridge/methods/system/runtime_manager/focus_runtime.rs +++ b/crates/sage-apps/src/bridge/methods/system/runtime_manager/focus_runtime.rs @@ -1,17 +1,14 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RuntimeTargetParams, - RustBridgeRequest, SageAppRuntimeRecordView, SystemBridgeCapability, focus_taskbar_runtime, - parse_required_params, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RuntimeTargetParams, + RustBridgeRequest, SageAppRuntimeRecordView, SystemBridgeCapability, bridge_result, + focus_taskbar_runtime, parse_required_params, }; #[derive(Debug, Clone, Copy)] pub(crate) struct RuntimeManagerFocusTaskbarRuntime; -#[async_trait] -impl BridgeMethod for RuntimeManagerFocusTaskbarRuntime { +impl BridgeMethodHandler for RuntimeManagerFocusTaskbarRuntime { fn name(&self) -> &'static str { "runtimeManager.focusTaskbarRuntime" } @@ -42,6 +39,6 @@ impl BridgeMethod for RuntimeManagerFocusTaskbarRuntime { let runtime_view: SageAppRuntimeRecordView = runtime.into(); - Ok(Box::new(runtime_view)) + bridge_result(runtime_view) } } diff --git a/crates/sage-apps/src/bridge/methods/system/runtime_manager/get_active_taskbar_runtime.rs b/crates/sage-apps/src/bridge/methods/system/runtime_manager/get_active_taskbar_runtime.rs index 76fdac464..8e4ab0836 100644 --- a/crates/sage-apps/src/bridge/methods/system/runtime_manager/get_active_taskbar_runtime.rs +++ b/crates/sage-apps/src/bridge/methods/system/runtime_manager/get_active_taskbar_runtime.rs @@ -1,17 +1,14 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - SageAppRuntimeRecordView, SystemBridgeCapability, find_active_taskbar_runtime, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + SageAppRuntimeRecordView, SystemBridgeCapability, bridge_result, find_active_taskbar_runtime, find_runtime_by_runtime_id_optional, resolve_running_app, }; #[derive(Debug, Clone, Copy)] pub(crate) struct RuntimeManagerGetActiveTaskbarRuntime; -#[async_trait] -impl BridgeMethod for RuntimeManagerGetActiveTaskbarRuntime { +impl BridgeMethodHandler for RuntimeManagerGetActiveTaskbarRuntime { fn name(&self) -> &'static str { "runtimeManager.getActiveTaskbarRuntime" } @@ -51,7 +48,7 @@ impl BridgeMethod for RuntimeManagerGetActiveTaskbarRuntime { find_active_taskbar_runtime(tools.host_state, &host_window_label).await; let Some(active_taskbar_runtime) = active_taskbar_runtime else { - return Ok(Box::new(None::)); + return bridge_result(None::); }; let runtime: Option = find_runtime_by_runtime_id_optional( @@ -61,6 +58,6 @@ impl BridgeMethod for RuntimeManagerGetActiveTaskbarRuntime { .await .map(Into::into); - Ok(Box::new(runtime)) + bridge_result(runtime) } } diff --git a/crates/sage-apps/src/bridge/methods/system/runtime_manager/hide_runtime.rs b/crates/sage-apps/src/bridge/methods/system/runtime_manager/hide_runtime.rs index aec7b5858..cc8a11ebf 100644 --- a/crates/sage-apps/src/bridge/methods/system/runtime_manager/hide_runtime.rs +++ b/crates/sage-apps/src/bridge/methods/system/runtime_manager/hide_runtime.rs @@ -1,17 +1,14 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RuntimeTargetParams, - RustBridgeRequest, SageAppRuntimeRecordView, SystemBridgeCapability, hide_runtime, - parse_required_params, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RuntimeTargetParams, + RustBridgeRequest, SageAppRuntimeRecordView, SystemBridgeCapability, bridge_result, + hide_runtime, parse_required_params, }; #[derive(Debug, Clone, Copy)] pub(crate) struct RuntimeManagerHideRuntime; -#[async_trait] -impl BridgeMethod for RuntimeManagerHideRuntime { +impl BridgeMethodHandler for RuntimeManagerHideRuntime { fn name(&self) -> &'static str { "runtimeManager.hideRuntime" } @@ -41,6 +38,6 @@ impl BridgeMethod for RuntimeManagerHideRuntime { .map_err(BridgeMethodHandleError::internal_error)?; let runtime_view: SageAppRuntimeRecordView = runtime.into(); - Ok(Box::new(runtime_view)) + bridge_result(runtime_view) } } diff --git a/crates/sage-apps/src/bridge/methods/system/runtime_manager/hide_self.rs b/crates/sage-apps/src/bridge/methods/system/runtime_manager/hide_self.rs index ff27bd80f..e36e2e934 100644 --- a/crates/sage-apps/src/bridge/methods/system/runtime_manager/hide_self.rs +++ b/crates/sage-apps/src/bridge/methods/system/runtime_manager/hide_self.rs @@ -1,16 +1,13 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - SystemBridgeCapability, hide_runtime, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + SystemBridgeCapability, bridge_result, hide_runtime, }; #[derive(Debug, Clone, Copy)] pub(crate) struct RuntimeManagerHideSelf; -#[async_trait] -impl BridgeMethod for RuntimeManagerHideSelf { +impl BridgeMethodHandler for RuntimeManagerHideSelf { fn name(&self) -> &'static str { "runtimeManager.hideSelf" } @@ -37,6 +34,6 @@ impl BridgeMethod for RuntimeManagerHideSelf { .await .map_err(BridgeMethodHandleError::internal_error)?; - Ok(Box::new(())) + bridge_result(()) } } diff --git a/crates/sage-apps/src/bridge/methods/system/runtime_manager/kill_runtime.rs b/crates/sage-apps/src/bridge/methods/system/runtime_manager/kill_runtime.rs index 49e264600..bfcd084ec 100644 --- a/crates/sage-apps/src/bridge/methods/system/runtime_manager/kill_runtime.rs +++ b/crates/sage-apps/src/bridge/methods/system/runtime_manager/kill_runtime.rs @@ -1,10 +1,10 @@ -use async_trait::async_trait; use serde::Serialize; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, RuntimeTargetParams, RustBridgeRequest, - SystemBridgeCapability, SystemKillRuntimeError, kill_runtime, parse_required_params, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, RuntimeTargetParams, RustBridgeRequest, + SystemBridgeCapability, SystemKillRuntimeError, bridge_result, kill_runtime, + parse_required_params, }; #[derive(Debug, Clone, Copy)] @@ -21,8 +21,7 @@ impl RuntimeManagerKillRuntimeResponse { } } -#[async_trait] -impl BridgeMethod for RuntimeManagerKillRuntime { +impl BridgeMethodHandler for RuntimeManagerKillRuntime { fn name(&self) -> &'static str { "runtimeManager.killRuntime" } @@ -57,7 +56,7 @@ impl BridgeMethod for RuntimeManagerKillRuntime { { Ok(()) | Err(SystemKillRuntimeError::NotFound | SystemKillRuntimeError::RuntimeSync(_)) => { - Ok(Box::new(RuntimeManagerKillRuntimeResponse::ok())) + bridge_result(RuntimeManagerKillRuntimeResponse::ok()) } } } diff --git a/crates/sage-apps/src/bridge/methods/system/runtime_manager/list_runtimes.rs b/crates/sage-apps/src/bridge/methods/system/runtime_manager/list_runtimes.rs index 35578dc4a..8b804c7f5 100644 --- a/crates/sage-apps/src/bridge/methods/system/runtime_manager/list_runtimes.rs +++ b/crates/sage-apps/src/bridge/methods/system/runtime_manager/list_runtimes.rs @@ -1,16 +1,13 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - SageAppRuntimeRecordView, SystemBridgeCapability, list_runtimes, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + SageAppRuntimeRecordView, SystemBridgeCapability, bridge_result, list_runtimes, }; #[derive(Debug, Clone, Copy)] pub(crate) struct RuntimeManagerListRuntimes; -#[async_trait] -impl BridgeMethod for RuntimeManagerListRuntimes { +impl BridgeMethodHandler for RuntimeManagerListRuntimes { fn name(&self) -> &'static str { "runtimeManager.listRuntimes" } @@ -42,6 +39,6 @@ impl BridgeMethod for RuntimeManagerListRuntimes { .map(Into::into) .collect::>(); - Ok(Box::new(runtime_views)) + bridge_result(runtime_views) } } diff --git a/crates/sage-apps/src/bridge/methods/system/sandbox/get_state.rs b/crates/sage-apps/src/bridge/methods/system/sandbox/get_state.rs index bb5cc280a..106333180 100644 --- a/crates/sage-apps/src/bridge/methods/system/sandbox/get_state.rs +++ b/crates/sage-apps/src/bridge/methods/system/sandbox/get_state.rs @@ -1,16 +1,13 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, RustBridgeRequest, SystemBridgeCapability, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, RustBridgeRequest, SystemBridgeCapability, bridge_result, build_state_view, }; #[derive(Debug, Clone, Copy)] pub struct SandboxGetState; -#[async_trait] -impl BridgeMethod for SandboxGetState { +impl BridgeMethodHandler for SandboxGetState { fn name(&self) -> &'static str { "sandbox.getState" } @@ -35,6 +32,6 @@ impl BridgeMethod for SandboxGetState { ) -> BridgeHandleResult { let state = build_state_view(tools.host_state).await; - Ok(Box::new(state)) + bridge_result(state) } } diff --git a/crates/sage-apps/src/bridge/methods/system/sandbox/rerun_tests.rs b/crates/sage-apps/src/bridge/methods/system/sandbox/rerun_tests.rs index 70d005026..e4c15993c 100644 --- a/crates/sage-apps/src/bridge/methods/system/sandbox/rerun_tests.rs +++ b/crates/sage-apps/src/bridge/methods/system/sandbox/rerun_tests.rs @@ -1,16 +1,13 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - SystemBridgeCapability, begin_sandbox_run, sandbox_runner, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + SystemBridgeCapability, begin_sandbox_run, bridge_result, sandbox_runner, }; #[derive(Debug, Clone, Copy)] pub struct SandboxRerunTests; -#[async_trait] -impl BridgeMethod for SandboxRerunTests { +impl BridgeMethodHandler for SandboxRerunTests { fn name(&self) -> &'static str { "sandbox.rerunTests" } @@ -43,6 +40,6 @@ impl BridgeMethod for SandboxRerunTests { Box::pin(sandbox_runner(runner_app)).await; }); - Ok(Box::new(view)) + bridge_result(view) } } diff --git a/crates/sage-apps/src/bridge/methods/system/wallet/list_wallets.rs b/crates/sage-apps/src/bridge/methods/system/wallet/list_wallets.rs index 45b6626fb..1ea4d3fb4 100644 --- a/crates/sage-apps/src/bridge/methods/system/wallet/list_wallets.rs +++ b/crates/sage-apps/src/bridge/methods/system/wallet/list_wallets.rs @@ -1,12 +1,11 @@ -use async_trait::async_trait; use sage_api::GetKeys; use serde::Serialize; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - SystemBridgeCapability, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + SystemBridgeCapability, bridge_result, }; #[derive(Debug, Clone, Copy)] @@ -26,8 +25,7 @@ pub struct WalletListWalletsResult { pub wallets: Vec, } -#[async_trait] -impl BridgeMethod for WalletListWallets { +impl BridgeMethodHandler for WalletListWallets { fn name(&self) -> &'static str { "wallet.listWallets" } @@ -56,7 +54,7 @@ impl BridgeMethod for WalletListWallets { BridgeMethodHandleError::internal_error(format!("{} failed: {err}", self.name())) })?; - Ok(Box::new(WalletListWalletsResult { + bridge_result(WalletListWalletsResult { wallets: keys .keys .into_iter() @@ -66,6 +64,6 @@ impl BridgeMethod for WalletListWallets { emoji: key.emoji, }) .collect(), - })) + }) } } diff --git a/crates/sage-apps/src/bridge/methods/user/app/get_capabilities.rs b/crates/sage-apps/src/bridge/methods/user/app/get_capabilities.rs index 4a56ada19..f7abbf41f 100644 --- a/crates/sage-apps/src/bridge/methods/user/app/get_capabilities.rs +++ b/crates/sage-apps/src/bridge/methods/user/app/get_capabilities.rs @@ -1,16 +1,13 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, RustBridgeRequest, SageApp, SharedCapabilitiesExt, - UserBridgeCapability, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageApp, SharedCapabilitiesExt, + UserBridgeCapability, bridge_result, }; #[derive(Debug, Clone, Copy)] pub struct AppGetCapabilities; -#[async_trait] -impl BridgeMethod for AppGetCapabilities { +impl BridgeMethodHandler for AppGetCapabilities { fn name(&self) -> &'static str { "app.getCapabilities" } @@ -51,6 +48,6 @@ impl BridgeMethod for AppGetCapabilities { let shared_capabilities = effective_capabilities.shared(); - Ok(Box::new(shared_capabilities)) + bridge_result(shared_capabilities) } } diff --git a/crates/sage-apps/src/bridge/methods/user/app/get_info.rs b/crates/sage-apps/src/bridge/methods/user/app/get_info.rs index 47365ae1d..181955b95 100644 --- a/crates/sage-apps/src/bridge/methods/user/app/get_info.rs +++ b/crates/sage-apps/src/bridge/methods/user/app/get_info.rs @@ -1,11 +1,10 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, RustBridgeRequest, SageRequestedPermissions, - UserBridgeCapability, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, RustBridgeRequest, SageRequestedPermissions, + UserBridgeCapability, bridge_result, }; #[derive(Debug, Clone, Copy)] @@ -30,8 +29,7 @@ pub struct AppGetInfoResult { pub network: Vec, } -#[async_trait] -impl BridgeMethod for AppGetInfo { +impl BridgeMethodHandler for AppGetInfo { fn name(&self) -> &'static str { "app.getInfo" } @@ -79,6 +77,6 @@ impl BridgeMethod for AppGetInfo { } }); - Ok(Box::new(result)) + bridge_result(result) } } diff --git a/crates/sage-apps/src/bridge/methods/user/app/lifecycle.rs b/crates/sage-apps/src/bridge/methods/user/app/lifecycle.rs index 2a63548fc..0289249d9 100644 --- a/crates/sage-apps/src/bridge/methods/user/app/lifecycle.rs +++ b/crates/sage-apps/src/bridge/methods/user/app/lifecycle.rs @@ -1,9 +1,7 @@ -use async_trait::async_trait; - use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, ReadyToStopParams, RuntimeAckResult, RustBridgeRequest, - SetBeforeStopListenerParams, UserBridgeCapability, parse_required_params, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, ReadyToStopParams, RuntimeAckResult, RustBridgeRequest, + SetBeforeStopListenerParams, UserBridgeCapability, bridge_result, parse_required_params, }; #[derive(Debug, Clone, Copy)] @@ -12,8 +10,7 @@ pub struct AppLifecycleSetBeforeStopListener; #[derive(Debug, Clone, Copy)] pub struct AppLifecycleReadyToStop; -#[async_trait] -impl BridgeMethod for AppLifecycleSetBeforeStopListener { +impl BridgeMethodHandler for AppLifecycleSetBeforeStopListener { fn name(&self) -> &'static str { "app.lifecycle.setBeforeStopListener" } @@ -51,12 +48,11 @@ impl BridgeMethod for AppLifecycleSetBeforeStopListener { listeners.remove(&ctx.app.id()); } - Ok(Box::new(RuntimeAckResult { ok: true })) + bridge_result(RuntimeAckResult { ok: true }) } } -#[async_trait] -impl BridgeMethod for AppLifecycleReadyToStop { +impl BridgeMethodHandler for AppLifecycleReadyToStop { fn name(&self) -> &'static str { "app.lifecycle.readyToStop" } @@ -90,6 +86,6 @@ impl BridgeMethod for AppLifecycleReadyToStop { let _ = sender.send(()); } - Ok(Box::new(RuntimeAckResult { ok: true })) + bridge_result(RuntimeAckResult { ok: true }) } } diff --git a/crates/sage-apps/src/bridge/methods/user/app/request_capability_grant.rs b/crates/sage-apps/src/bridge/methods/user/app/request_capability_grant.rs index cf6e4e2c3..f4e7e1f9f 100644 --- a/crates/sage-apps/src/bridge/methods/user/app/request_capability_grant.rs +++ b/crates/sage-apps/src/bridge/methods/user/app/request_capability_grant.rs @@ -1,12 +1,12 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, GrantCapabilityOutcome, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, GrantCapabilityOutcome, RustBridgeApprovalBody, RustBridgeApprovalRequest, RustBridgeRequest, UserBridgeCapability, - get_user_capability_definition, grant_capability, parse_required_params, resolve_app_base_path, + bridge_result, get_user_capability_definition, grant_capability, parse_required_params, + resolve_app_base_path, }; #[derive(Debug, Clone, Copy)] @@ -43,8 +43,7 @@ fn ensure_capability_requestable_by_app( Ok(()) } -#[async_trait] -impl BridgeMethod for AppRequestCapabilityGrant { +impl BridgeMethodHandler for AppRequestCapabilityGrant { fn name(&self) -> &'static str { "app.requestCapabilityGrant" } @@ -123,7 +122,7 @@ impl BridgeMethod for AppRequestCapabilityGrant { } }; - Ok(Box::new(result)) + bridge_result(result) } } diff --git a/crates/sage-apps/src/bridge/methods/user/app/request_network_whitelist_grant.rs b/crates/sage-apps/src/bridge/methods/user/app/request_network_whitelist_grant.rs index ea3006e88..45846a90a 100644 --- a/crates/sage-apps/src/bridge/methods/user/app/request_network_whitelist_grant.rs +++ b/crates/sage-apps/src/bridge/methods/user/app/request_network_whitelist_grant.rs @@ -1,12 +1,11 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, GrantNetworkWhitelistOutcome, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, GrantNetworkWhitelistOutcome, RustBridgeApprovalBody, RustBridgeApprovalRequest, RustBridgeRequest, - SageNetworkWhitelistEntry, UserBridgeCapability, grant_network_whitelist_entry, + SageNetworkWhitelistEntry, UserBridgeCapability, bridge_result, grant_network_whitelist_entry, parse_required_params, resolve_app_base_path, }; @@ -38,8 +37,7 @@ pub struct RequestNetworkWhitelistGrantResult { pub full_granted_network_whitelist: Vec, } -#[async_trait] -impl BridgeMethod for AppRequestNetworkWhitelistGrant { +impl BridgeMethodHandler for AppRequestNetworkWhitelistGrant { fn name(&self) -> &'static str { "app.requestNetworkWhitelistGrant" } @@ -128,6 +126,6 @@ impl BridgeMethod for AppRequestNetworkWhitelistGrant { } }; - Ok(Box::new(result)) + bridge_result(result) } } diff --git a/crates/sage-apps/src/bridge/methods/user/bridge/ping.rs b/crates/sage-apps/src/bridge/methods/user/bridge/ping.rs index 5cc040f22..f526bbc73 100644 --- a/crates/sage-apps/src/bridge/methods/user/bridge/ping.rs +++ b/crates/sage-apps/src/bridge/methods/user/bridge/ping.rs @@ -1,10 +1,9 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeTools, RustBridgeRequest, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandler, BridgeTools, RustBridgeRequest, bridge_result, }; #[derive(Debug, Clone, Copy)] @@ -18,8 +17,7 @@ pub struct BridgePingResult { pub app_name: String, } -#[async_trait] -impl BridgeMethod for BridgePing { +impl BridgeMethodHandler for BridgePing { fn name(&self) -> &'static str { "bridge.ping" } @@ -42,10 +40,10 @@ impl BridgeMethod for BridgePing { _tools: BridgeTools<'_>, _request: &RustBridgeRequest, ) -> BridgeHandleResult { - Ok(Box::new(BridgePingResult { + bridge_result(BridgePingResult { ok: true, app_id: ctx.app.id(), app_name: ctx.app.name(), - })) + }) } } diff --git a/crates/sage-apps/src/bridge/methods/user/bridge/send.rs b/crates/sage-apps/src/bridge/methods/user/bridge/send.rs index 162e22ca3..fefb505e4 100644 --- a/crates/sage-apps/src/bridge/methods/user/bridge/send.rs +++ b/crates/sage-apps/src/bridge/methods/user/bridge/send.rs @@ -1,12 +1,11 @@ -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ BUILTIN_ORIGIN_CLEANUP_RUNTIME_ID, BridgeApprovalRequestResult, BridgeContext, - BridgeHandleResult, BridgeMethod, BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, - RustBridgeRequest, UserBridgeCapability, ingest_bridge_send_payload, - ingest_origin_cleanup_bridge_send_payload, parse_required_params, + BridgeHandleResult, BridgeMethodCapability, BridgeMethodHandleError, BridgeMethodHandler, + BridgeTools, RustBridgeRequest, UserBridgeCapability, bridge_result, + ingest_bridge_send_payload, ingest_origin_cleanup_bridge_send_payload, parse_required_params, }; #[derive(Debug, Clone, Copy)] @@ -32,8 +31,7 @@ enum BridgeSendContextKind { OriginCleanup, } -#[async_trait] -impl BridgeMethod for BridgeSend { +impl BridgeMethodHandler for BridgeSend { fn name(&self) -> &'static str { "bridge.send" } @@ -87,7 +85,7 @@ impl BridgeMethod for BridgeSend { } } - Ok(Box::new(BridgeSendResult { ok: true })) + bridge_result(BridgeSendResult { ok: true }) } } diff --git a/crates/sage-apps/src/bridge/methods/user/environment/get_network.rs b/crates/sage-apps/src/bridge/methods/user/environment/get_network.rs index ad28dfe6f..4cb908d41 100644 --- a/crates/sage-apps/src/bridge/methods/user/environment/get_network.rs +++ b/crates/sage-apps/src/bridge/methods/user/environment/get_network.rs @@ -1,12 +1,11 @@ -use async_trait::async_trait; use sage_api::{GetNetwork, NetworkKind}; use serde::Serialize; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - UserBridgeCapability, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + UserBridgeCapability, bridge_result, }; #[derive(Debug, Clone, Serialize, Type)] @@ -23,8 +22,7 @@ pub struct EnvironmentGetNetworkResult { #[derive(Debug, Clone, Copy)] pub struct EnvironmentGetNetwork; -#[async_trait] -impl BridgeMethod for EnvironmentGetNetwork { +impl BridgeMethodHandler for EnvironmentGetNetwork { fn name(&self) -> &'static str { "environment.getNetwork" } @@ -54,13 +52,13 @@ impl BridgeMethod for EnvironmentGetNetwork { .get_network(GetNetwork {}) .map_err(|err| BridgeMethodHandleError::internal_error(err.to_string()))?; - Ok(Box::new(EnvironmentGetNetworkResult { + bridge_result(EnvironmentGetNetworkResult { name: current.network.name.clone(), network_id: current.network.network_id(), kind: current.kind, ticker: current.network.ticker.clone(), prefix: current.network.prefix(), precision: current.network.precision, - })) + }) } } diff --git a/crates/sage-apps/src/bridge/methods/user/environment/theme/get_current.rs b/crates/sage-apps/src/bridge/methods/user/environment/theme/get_current.rs index 96d6a5bef..e186257c4 100644 --- a/crates/sage-apps/src/bridge/methods/user/environment/theme/get_current.rs +++ b/crates/sage-apps/src/bridge/methods/user/environment/theme/get_current.rs @@ -1,13 +1,12 @@ use std::collections::BTreeMap; -use async_trait::async_trait; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - UserBridgeCapability, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + UserBridgeCapability, bridge_result, }; #[derive(Debug, Clone, Serialize, Deserialize, Type)] @@ -34,8 +33,7 @@ pub struct EnvironmentThemeGetCurrentResult { #[derive(Debug, Clone, Copy)] pub struct EnvironmentThemeGetCurrent; -#[async_trait] -impl BridgeMethod for EnvironmentThemeGetCurrent { +impl BridgeMethodHandler for EnvironmentThemeGetCurrent { fn name(&self) -> &'static str { "environment.theme.getCurrent" } @@ -70,6 +68,6 @@ impl BridgeMethod for EnvironmentThemeGetCurrent { BridgeMethodHandleError::internal_error("current theme is not initialized") })?; - Ok(Box::new(EnvironmentThemeGetCurrentResult { theme })) + bridge_result(EnvironmentThemeGetCurrentResult { theme }) } } diff --git a/crates/sage-apps/src/bridge/methods/user/wallet/get_key.rs b/crates/sage-apps/src/bridge/methods/user/wallet/get_key.rs index 4e896e7fb..72052529b 100644 --- a/crates/sage-apps/src/bridge/methods/user/wallet/get_key.rs +++ b/crates/sage-apps/src/bridge/methods/user/wallet/get_key.rs @@ -1,17 +1,15 @@ -use async_trait::async_trait; use sage_api::GetKey; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - UserBridgeCapability, parse_required_params, require_scoped_fingerprint, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + UserBridgeCapability, bridge_result, parse_required_params, require_scoped_fingerprint, }; #[derive(Debug, Clone, Copy)] pub struct WalletGetKey; -#[async_trait] -impl BridgeMethod for WalletGetKey { +impl BridgeMethodHandler for WalletGetKey { fn name(&self) -> &'static str { "wallet.getKey" } @@ -51,6 +49,6 @@ impl BridgeMethod for WalletGetKey { )) })?; - Ok(Box::new(result)) + bridge_result(result) } } diff --git a/crates/sage-apps/src/bridge/methods/user/wallet/get_secret_key.rs b/crates/sage-apps/src/bridge/methods/user/wallet/get_secret_key.rs index bf04fa1e1..d10b165d0 100644 --- a/crates/sage-apps/src/bridge/methods/user/wallet/get_secret_key.rs +++ b/crates/sage-apps/src/bridge/methods/user/wallet/get_secret_key.rs @@ -1,18 +1,16 @@ -use async_trait::async_trait; use sage_api::GetSecretKey; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeApprovalBody, - RustBridgeApprovalRequest, RustBridgeRequest, UserBridgeCapability, parse_required_params, - require_scoped_fingerprint, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeApprovalBody, + RustBridgeApprovalRequest, RustBridgeRequest, UserBridgeCapability, bridge_result, + parse_required_params, require_scoped_fingerprint, }; #[derive(Debug, Clone, Copy)] pub struct WalletGetSecretKey; -#[async_trait] -impl BridgeMethod for WalletGetSecretKey { +impl BridgeMethodHandler for WalletGetSecretKey { fn name(&self) -> &'static str { "wallet.getSecretKey" } @@ -51,6 +49,6 @@ impl BridgeMethod for WalletGetSecretKey { BridgeMethodHandleError::internal_error(format!("{} failed: {err}", self.name())) })?; - Ok(Box::new(response)) + bridge_result(response) } } diff --git a/crates/sage-apps/src/bridge/methods/user/wallet/read_methods.rs b/crates/sage-apps/src/bridge/methods/user/wallet/read_methods.rs index 13c282b9a..e049f5e2b 100644 --- a/crates/sage-apps/src/bridge/methods/user/wallet/read_methods.rs +++ b/crates/sage-apps/src/bridge/methods/user/wallet/read_methods.rs @@ -1,4 +1,3 @@ -use async_trait::async_trait; use sage_api::{ CheckAddress, GetCoins, GetCoinsByIds, GetDerivations, GetPendingTransactions, GetSpendableCoinCount, GetSyncStatus, GetTransaction, GetTransactions, GetVersion, @@ -6,9 +5,9 @@ use sage_api::{ }; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeRequest, - UserBridgeCapability, parse_required_params, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeRequest, + UserBridgeCapability, bridge_result, parse_required_params, }; macro_rules! define_wallet_read_no_params_async_method { @@ -16,8 +15,7 @@ macro_rules! define_wallet_read_no_params_async_method { #[derive(Debug, Clone, Copy)] pub struct $struct_name; - #[async_trait] - impl BridgeMethod for $struct_name { + impl BridgeMethodHandler for $struct_name { fn name(&self) -> &'static str { $method_name } @@ -49,7 +47,7 @@ macro_rules! define_wallet_read_no_params_async_method { )) })?; - Ok(Box::new(result)) + bridge_result(result) } } }; @@ -60,8 +58,7 @@ macro_rules! define_wallet_read_no_params_sync_method { #[derive(Debug, Clone, Copy)] pub struct $struct_name; - #[async_trait] - impl BridgeMethod for $struct_name { + impl BridgeMethodHandler for $struct_name { fn name(&self) -> &'static str { $method_name } @@ -93,7 +90,7 @@ macro_rules! define_wallet_read_no_params_sync_method { )) })?; - Ok(Box::new(result)) + bridge_result(result) } } }; @@ -104,8 +101,7 @@ macro_rules! define_wallet_read_params_async_method { #[derive(Debug, Clone, Copy)] pub struct $struct_name; - #[async_trait] - impl BridgeMethod for $struct_name { + impl BridgeMethodHandler for $struct_name { fn name(&self) -> &'static str { $method_name } @@ -139,7 +135,7 @@ macro_rules! define_wallet_read_params_async_method { )) })?; - Ok(Box::new(result)) + bridge_result(result) } } }; diff --git a/crates/sage-apps/src/bridge/methods/user/wallet/send_xch.rs b/crates/sage-apps/src/bridge/methods/user/wallet/send_xch.rs index 1becd5ab4..9b678105e 100644 --- a/crates/sage-apps/src/bridge/methods/user/wallet/send_xch.rs +++ b/crates/sage-apps/src/bridge/methods/user/wallet/send_xch.rs @@ -1,12 +1,12 @@ -use async_trait::async_trait; use sage_api::SendXch; use serde::{Deserialize, Serialize}; use specta::Type; use crate::{ - BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethod, - BridgeMethodCapability, BridgeMethodHandleError, BridgeTools, RustBridgeApprovalBody, - RustBridgeApprovalRequest, RustBridgeRequest, UserBridgeCapability, parse_required_params, + BridgeApprovalRequestResult, BridgeContext, BridgeHandleResult, BridgeMethodCapability, + BridgeMethodHandleError, BridgeMethodHandler, BridgeTools, RustBridgeApprovalBody, + RustBridgeApprovalRequest, RustBridgeRequest, UserBridgeCapability, bridge_result, + parse_required_params, }; #[derive(Debug, Clone, Copy)] @@ -44,8 +44,7 @@ impl From for SendXch { } } -#[async_trait] -impl BridgeMethod for WalletSendXch { +impl BridgeMethodHandler for WalletSendXch { fn name(&self) -> &'static str { "wallet.sendXch" } @@ -92,6 +91,6 @@ impl BridgeMethod for WalletSendXch { BridgeMethodHandleError::internal_error(format!("{} failed: {err}", self.name())) })?; - Ok(Box::new(result)) + bridge_result(result) } } diff --git a/crates/sage-apps/src/bridge/registry.rs b/crates/sage-apps/src/bridge/registry.rs index 141bcce39..060c2d646 100644 --- a/crates/sage-apps/src/bridge/registry.rs +++ b/crates/sage-apps/src/bridge/registry.rs @@ -8,124 +8,319 @@ pub(crate) enum BridgeRegistryKind { System, } -pub(crate) struct BridgeRegistry { - methods: HashMap<&'static str, Box>, +pub(crate) enum BridgeRegistry { + User(UserBridgeRegistry), + System(SystemBridgeRegistry), +} + +pub(crate) struct UserBridgeRegistry { + methods: HashMap<&'static str, UserBridgeMethodEntry>, +} + +pub(crate) struct SystemBridgeRegistry { + methods: HashMap<&'static str, SystemBridgeMethodEntry>, +} + +#[derive(Clone, Copy)] +pub(crate) enum BridgeMethodEntry<'a> { + User(&'a UserBridgeMethodEntry), + System(&'a SystemBridgeMethodEntry), } impl BridgeRegistry { pub(crate) fn new(kind: BridgeRegistryKind) -> Self { match kind { - BridgeRegistryKind::User => Self { - methods: build_user_methods(), - }, - BridgeRegistryKind::System => Self { - methods: build_system_methods(), - }, + BridgeRegistryKind::User => Self::User(UserBridgeRegistry::new()), + BridgeRegistryKind::System => Self::System(SystemBridgeRegistry::new()), + } + } + + pub(crate) fn get(&self, method: &str) -> Option> { + match self { + Self::User(registry) => registry.get(method).map(BridgeMethodEntry::User), + Self::System(registry) => registry.get(method).map(BridgeMethodEntry::System), + } + } + + pub(crate) fn iter(&self) -> Vec<(&'static str, BridgeMethodEntry<'_>)> { + match self { + Self::User(registry) => registry.iter(), + Self::System(registry) => registry.iter(), } } +} + +impl std::fmt::Debug for BridgeRegistry { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let method_count = match self { + Self::User(registry) => registry.methods.len(), + Self::System(registry) => registry.methods.len(), + }; - pub(crate) fn get(&self, method: &str) -> Option<&dyn BridgeMethod> { - self.methods.get(method).map(AsRef::as_ref) + f.debug_struct("BridgeRegistry") + .field("method_count", &method_count) + .finish() } +} + +macro_rules! bridge_method_entry { + ($entry:ident { $($variant:ident($method:ty)),+ $(,)? }) => { + pub(crate) enum $entry { + $($variant($method),)+ + } + + impl $entry { + pub(crate) fn name(&self) -> &'static str { + match self { + $(Self::$variant(method) => method.name(),)+ + } + } + + pub(crate) fn capability(&self) -> BridgeMethodCapability { + match self { + $(Self::$variant(method) => method.capability(),)+ + } + } + + pub(crate) fn approval_request( + &self, + ctx: BridgeContext<'_>, + request: &RustBridgeRequest, + ) -> BridgeApprovalRequestResult { + match self { + $(Self::$variant(method) => method.approval_request(ctx, request),)+ + } + } + + pub(crate) fn handle( + &self, + ctx: BridgeContext<'_>, + tools: BridgeTools<'_>, + request: &RustBridgeRequest, + ) -> impl std::future::Future + Send { + async move { + match self { + $(Self::$variant(method) => method.handle(ctx, tools, request).await,)+ + } + } + } + } + + $( + impl From<$method> for $entry { + fn from(method: $method) -> Self { + Self::$variant(method) + } + } + )+ + }; +} + +bridge_method_entry! { UserBridgeMethodEntry { + BridgePingEntry(BridgePing), + BridgeSendEntry(BridgeSend), + AppGetInfoEntry(AppGetInfo), + AppGetCapabilitiesEntry(AppGetCapabilities), + AppRequestCapabilityGrantEntry(AppRequestCapabilityGrant), + AppRequestNetworkWhitelistGrantEntry(AppRequestNetworkWhitelistGrant), + AppLifecycleSetBeforeStopListenerEntry(AppLifecycleSetBeforeStopListener), + AppLifecycleReadyToStopEntry(AppLifecycleReadyToStop), + WalletGetKeyEntry(WalletGetKey), + WalletGetSecretKeyEntry(WalletGetSecretKey), + WalletSendXchEntry(WalletSendXch), + WalletGetSyncStatusEntry(WalletGetSyncStatus), + WalletGetVersionEntry(WalletGetVersion), + WalletGetPendingTransactionsEntry(WalletGetPendingTransactions), + WalletGetXchUsdPriceEntry(WalletGetXchUsdPrice), + WalletCheckAddressEntry(WalletCheckAddress), + WalletGetDerivationsEntry(WalletGetDerivations), + WalletGetSpendableCoinCountEntry(WalletGetSpendableCoinCount), + WalletGetCoinsByIdsEntry(WalletGetCoinsByIds), + WalletGetCoinsEntry(WalletGetCoins), + WalletGetTransactionEntry(WalletGetTransaction), + WalletGetTransactionsEntry(WalletGetTransactions), + EnvironmentThemeGetCurrentEntry(EnvironmentThemeGetCurrent), + EnvironmentGetNetworkEntry(EnvironmentGetNetwork), +} } + +bridge_method_entry! { SystemBridgeMethodEntry { + RuntimeManagerListRuntimesEntry(RuntimeManagerListRuntimes), + RuntimeManagerFocusTaskbarRuntimeEntry(RuntimeManagerFocusTaskbarRuntime), + RuntimeManagerHideRuntimeEntry(RuntimeManagerHideRuntime), + RuntimeManagerKillRuntimeEntry(RuntimeManagerKillRuntime), + RuntimeManagerHideSelfEntry(RuntimeManagerHideSelf), + RuntimeManagerCloseSelfEntry(RuntimeManagerCloseSelf), + RuntimeManagerGetActiveTaskbarRuntimeEntry(RuntimeManagerGetActiveTaskbarRuntime), + AppInstallPreviewUrlEntry(AppInstallPreviewUrl), + AppInstallPreviewZipEntry(AppInstallPreviewZip), + AppInstallInstallUrlEntry(AppInstallInstallUrl), + AppInstallInstallZipEntry(AppInstallInstallZip), + AppUpdateGetReviewContextEntry(AppUpdateGetReviewContext), + AppUpdateApplyUpdateEntry(AppUpdateApplyUpdate), + CapabilitiesListUserDefinitionsEntry(CapabilitiesListUserDefinitions), + AppPermissionsGetReviewContextEntry(AppPermissionsGetReviewContext), + AppPermissionsApplyPermissionsEntry(AppPermissionsApplyPermissions), + FileSystemSelectFileEntry(FileSystemSelectFile), + BridgeApprovalsListPendingEntry(BridgeApprovalsListPending), + BridgeApprovalsResolveEntry(BridgeApprovalsResolve), + DonationGetDetailsEntry(DonationGetDetails), + SandboxGetStateEntry(SandboxGetState), + SandboxRerunTestsEntry(SandboxRerunTests), + WalletListWalletsEntry(WalletListWallets), +} } + +impl UserBridgeRegistry { + pub(crate) fn new() -> Self { + let mut methods = HashMap::new(); + + // Bridge + insert_user_method(&mut methods, BridgePing); + insert_user_method(&mut methods, BridgeSend); - pub(crate) fn iter(&self) -> impl Iterator { + // App + insert_user_method(&mut methods, AppGetInfo); + insert_user_method(&mut methods, AppGetCapabilities); + insert_user_method(&mut methods, AppRequestCapabilityGrant); + insert_user_method(&mut methods, AppRequestNetworkWhitelistGrant); + insert_user_method(&mut methods, AppLifecycleSetBeforeStopListener); + insert_user_method(&mut methods, AppLifecycleReadyToStop); + + // Wallet keys / secrets + insert_user_method(&mut methods, WalletGetKey); + insert_user_method(&mut methods, WalletGetSecretKey); + + // Wallet XCH + insert_user_method(&mut methods, WalletSendXch); + + // Wallet read/query + insert_user_method(&mut methods, WalletGetSyncStatus); + insert_user_method(&mut methods, WalletGetVersion); + insert_user_method(&mut methods, WalletGetPendingTransactions); + insert_user_method(&mut methods, WalletGetXchUsdPrice); + insert_user_method(&mut methods, WalletCheckAddress); + insert_user_method(&mut methods, WalletGetDerivations); + insert_user_method(&mut methods, WalletGetSpendableCoinCount); + insert_user_method(&mut methods, WalletGetCoinsByIds); + insert_user_method(&mut methods, WalletGetCoins); + insert_user_method(&mut methods, WalletGetTransaction); + insert_user_method(&mut methods, WalletGetTransactions); + + // Environment + insert_user_method(&mut methods, EnvironmentThemeGetCurrent); + insert_user_method(&mut methods, EnvironmentGetNetwork); + + Self { methods } + } + + pub(crate) fn get(&self, method: &str) -> Option<&UserBridgeMethodEntry> { + self.methods.get(method) + } + + fn iter(&self) -> Vec<(&'static str, BridgeMethodEntry<'_>)> { self.methods .iter() - .map(|(name, method)| (*name, method.as_ref())) + .map(|(name, method)| (*name, BridgeMethodEntry::User(method))) + .collect() } } -fn build_user_methods() -> HashMap<&'static str, Box> { - let mut methods: HashMap<&'static str, Box> = HashMap::new(); - - // Bridge - insert_method(&mut methods, BridgePing); - insert_method(&mut methods, BridgeSend); - - // App - insert_method(&mut methods, AppGetInfo); - insert_method(&mut methods, AppGetCapabilities); - insert_method(&mut methods, AppRequestCapabilityGrant); - insert_method(&mut methods, AppRequestNetworkWhitelistGrant); - insert_method(&mut methods, AppLifecycleSetBeforeStopListener); - insert_method(&mut methods, AppLifecycleReadyToStop); - - // Wallet keys / secrets - insert_method(&mut methods, WalletGetKey); - insert_method(&mut methods, WalletGetSecretKey); - - // Wallet XCH - insert_method(&mut methods, WalletSendXch); - - // Wallet read/query - insert_method(&mut methods, WalletGetSyncStatus); - insert_method(&mut methods, WalletGetVersion); - insert_method(&mut methods, WalletGetPendingTransactions); - insert_method(&mut methods, WalletGetXchUsdPrice); - insert_method(&mut methods, WalletCheckAddress); - insert_method(&mut methods, WalletGetDerivations); - insert_method(&mut methods, WalletGetSpendableCoinCount); - insert_method(&mut methods, WalletGetCoinsByIds); - insert_method(&mut methods, WalletGetCoins); - insert_method(&mut methods, WalletGetTransaction); - insert_method(&mut methods, WalletGetTransactions); - - // Environment - insert_method(&mut methods, EnvironmentThemeGetCurrent); - insert_method(&mut methods, EnvironmentGetNetwork); - - methods -} +impl SystemBridgeRegistry { + fn new() -> Self { + let mut methods = HashMap::new(); -fn build_system_methods() -> HashMap<&'static str, Box> { - let mut methods: HashMap<&'static str, Box> = HashMap::new(); + insert_system_method(&mut methods, RuntimeManagerListRuntimes); + insert_system_method(&mut methods, RuntimeManagerFocusTaskbarRuntime); + insert_system_method(&mut methods, RuntimeManagerHideRuntime); + insert_system_method(&mut methods, RuntimeManagerKillRuntime); + insert_system_method(&mut methods, RuntimeManagerHideSelf); + insert_system_method(&mut methods, RuntimeManagerCloseSelf); + insert_system_method(&mut methods, RuntimeManagerGetActiveTaskbarRuntime); - insert_method(&mut methods, RuntimeManagerListRuntimes); - insert_method(&mut methods, RuntimeManagerFocusTaskbarRuntime); - insert_method(&mut methods, RuntimeManagerHideRuntime); - insert_method(&mut methods, RuntimeManagerKillRuntime); - insert_method(&mut methods, RuntimeManagerHideSelf); - insert_method(&mut methods, RuntimeManagerCloseSelf); - insert_method(&mut methods, RuntimeManagerGetActiveTaskbarRuntime); + insert_system_method(&mut methods, AppInstallPreviewUrl); + insert_system_method(&mut methods, AppInstallPreviewZip); + insert_system_method(&mut methods, AppInstallInstallUrl); + insert_system_method(&mut methods, AppInstallInstallZip); - insert_method(&mut methods, AppInstallPreviewUrl); - insert_method(&mut methods, AppInstallPreviewZip); - insert_method(&mut methods, AppInstallInstallUrl); - insert_method(&mut methods, AppInstallInstallZip); + insert_system_method(&mut methods, AppUpdateGetReviewContext); + insert_system_method(&mut methods, AppUpdateApplyUpdate); - insert_method(&mut methods, AppUpdateGetReviewContext); - insert_method(&mut methods, AppUpdateApplyUpdate); + insert_system_method(&mut methods, CapabilitiesListUserDefinitions); + insert_system_method(&mut methods, AppPermissionsGetReviewContext); + insert_system_method(&mut methods, AppPermissionsApplyPermissions); - insert_method(&mut methods, CapabilitiesListUserDefinitions); - insert_method(&mut methods, AppPermissionsGetReviewContext); - insert_method(&mut methods, AppPermissionsApplyPermissions); + insert_system_method(&mut methods, FileSystemSelectFile); - insert_method(&mut methods, FileSystemSelectFile); + insert_system_method(&mut methods, BridgeApprovalsListPending); + insert_system_method(&mut methods, BridgeApprovalsResolve); - insert_method(&mut methods, BridgeApprovalsListPending); - insert_method(&mut methods, BridgeApprovalsResolve); + insert_system_method(&mut methods, DonationGetDetails); - insert_method(&mut methods, DonationGetDetails); + insert_system_method(&mut methods, SandboxGetState); + insert_system_method(&mut methods, SandboxRerunTests); - insert_method(&mut methods, SandboxGetState); - insert_method(&mut methods, SandboxRerunTests); + insert_system_method(&mut methods, WalletListWallets); + + Self { methods } + } - insert_method(&mut methods, WalletListWallets); + fn get(&self, method: &str) -> Option<&SystemBridgeMethodEntry> { + self.methods.get(method) + } - methods + fn iter(&self) -> Vec<(&'static str, BridgeMethodEntry<'_>)> { + self.methods + .iter() + .map(|(name, method)| (*name, BridgeMethodEntry::System(method))) + .collect() + } } -impl std::fmt::Debug for BridgeRegistry { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("BridgeRegistry") - .field("method_count", &self.methods.len()) - .finish() +impl BridgeMethodEntry<'_> { + pub(crate) fn capability(&self) -> BridgeMethodCapability { + match self { + Self::User(method) => method.capability(), + Self::System(method) => method.capability(), + } + } + + pub(crate) fn approval_request( + &self, + ctx: BridgeContext<'_>, + request: &RustBridgeRequest, + ) -> BridgeApprovalRequestResult { + match self { + Self::User(method) => method.approval_request(ctx, request), + Self::System(method) => method.approval_request(ctx, request), + } } + + pub(crate) fn handle( + &self, + ctx: BridgeContext<'_>, + tools: BridgeTools<'_>, + request: &RustBridgeRequest, + ) -> impl std::future::Future + Send { + async move { + match self { + Self::User(method) => method.handle(ctx, tools, request).await, + Self::System(method) => method.handle(ctx, tools, request).await, + } + } + } +} + +fn insert_user_method(methods: &mut HashMap<&'static str, UserBridgeMethodEntry>, method: M) +where + M: BridgeMethodHandler + Into, +{ + let method: UserBridgeMethodEntry = method.into(); + methods.insert(method.name(), method); } -fn insert_method(methods: &mut HashMap<&'static str, Box>, method: M) +fn insert_system_method(methods: &mut HashMap<&'static str, SystemBridgeMethodEntry>, method: M) where - M: BridgeMethod + 'static, + M: BridgeMethodHandler + Into, { - methods.insert(method.name(), Box::new(method)); + let method: SystemBridgeMethodEntry = method.into(); + methods.insert(method.name(), method); } diff --git a/crates/sage-apps/src/build/docs.rs b/crates/sage-apps/src/build/docs.rs index 5cc67f768..6b352cc0a 100644 --- a/crates/sage-apps/src/build/docs.rs +++ b/crates/sage-apps/src/build/docs.rs @@ -159,7 +159,7 @@ pub(crate) fn bridge_methods_markdown(kind: BridgeRegistryKind) -> String { }; let registry = BridgeRegistry::new(kind); - let mut methods = registry.iter().collect::>(); + let mut methods = registry.iter(); methods.sort_by_key(|(name, _)| *name); let mut out = format!("# {title}\n\n"); diff --git a/crates/sage-apps/src/lifecycle/install.rs b/crates/sage-apps/src/lifecycle/install.rs index c0f794bf9..71e630a85 100644 --- a/crates/sage-apps/src/lifecycle/install.rs +++ b/crates/sage-apps/src/lifecycle/install.rs @@ -9,11 +9,11 @@ pub(crate) use zip::*; use std::{ fs, + future::Future, path::{Path, PathBuf}, }; use anyhow::Result as AnyResult; -use async_trait::async_trait; use tauri::{AppHandle, Manager, State}; use uuid::Uuid; @@ -24,11 +24,10 @@ use crate::{ fresh_snapshot_dir, write_snapshot_manifest, }; -#[async_trait] pub trait AppInstallSource { type PreparedArtifact: Send + Sync; - async fn prepare(&self) -> AnyResult; + fn prepare(&self) -> impl Future> + Send; fn manifest<'a>(&self, prepared: &'a Self::PreparedArtifact) -> &'a SageAppPackageManifest; @@ -41,11 +40,11 @@ pub trait AppInstallSource { prepared: &Self::PreparedArtifact, ) -> AnyResult<(String, PathBuf)>; - async fn create_snapshot( + fn create_snapshot( &self, snapshot_dir: &Path, prepared: &Self::PreparedArtifact, - ) -> AnyResult; + ) -> impl Future> + Send; } #[derive(Debug)] @@ -248,7 +247,6 @@ pub(crate) struct FakePreparedArtifact { manifest: SageAppPackageManifest, } -#[async_trait] #[cfg(test)] impl AppInstallSource for FakeInstallSource { type PreparedArtifact = FakePreparedArtifact; diff --git a/crates/sage-apps/src/lifecycle/install/url.rs b/crates/sage-apps/src/lifecycle/install/url.rs index de9764622..431a6c46b 100644 --- a/crates/sage-apps/src/lifecycle/install/url.rs +++ b/crates/sage-apps/src/lifecycle/install/url.rs @@ -1,12 +1,10 @@ use std::path::{Path, PathBuf}; use anyhow::Result as AnyResult; -use async_trait::async_trait; -use super::AppInstallSource; use crate::{ - SageAppPackageManifest, SageAppSnapshot, SageAppUrl, SageAppUrlPreview, UserSageAppSource, - bytes_sha256_hex, download_url_snapshot, fetch_url_manifest_preview, + AppInstallSource, SageAppPackageManifest, SageAppSnapshot, SageAppUrl, SageAppUrlPreview, + UserSageAppSource, bytes_sha256_hex, download_url_snapshot, fetch_url_manifest_preview, }; #[derive(Debug, Clone)] @@ -14,7 +12,6 @@ pub struct PreparedUrlInstall { pub preview: SageAppUrlPreview, } -#[async_trait] impl AppInstallSource for SageAppUrl { type PreparedArtifact = PreparedUrlInstall; diff --git a/crates/sage-apps/src/lifecycle/install/zip.rs b/crates/sage-apps/src/lifecycle/install/zip.rs index fa05149b0..c3f273d08 100644 --- a/crates/sage-apps/src/lifecycle/install/zip.rs +++ b/crates/sage-apps/src/lifecycle/install/zip.rs @@ -4,13 +4,11 @@ use std::{ }; use anyhow::Result as AnyResult; -use async_trait::async_trait; use uuid::Uuid; -use super::AppInstallSource; use crate::{ - SageAppPackageManifest, SageAppSnapshot, UserSageAppSource, detect_package_root, - prepare_zip_snapshot, read_manifest, slugify_app_name, unzip_to_dir, + AppInstallSource, SageAppPackageManifest, SageAppSnapshot, UserSageAppSource, + detect_package_root, prepare_zip_snapshot, read_manifest, slugify_app_name, unzip_to_dir, }; #[derive(Debug, Clone)] @@ -34,7 +32,6 @@ impl ZipInstallSource { } } -#[async_trait] impl AppInstallSource for ZipInstallSource { type PreparedArtifact = PreparedZipInstall; diff --git a/crates/sage-apps/src/lifecycle/mutation/manager.rs b/crates/sage-apps/src/lifecycle/mutation/manager.rs index 8ecf28fc0..3c0602fd7 100644 --- a/crates/sage-apps/src/lifecycle/mutation/manager.rs +++ b/crates/sage-apps/src/lifecycle/mutation/manager.rs @@ -1,5 +1,3 @@ -use std::pin::Pin; - use anyhow::Result; use tauri::{AppHandle, State}; @@ -45,10 +43,7 @@ impl<'a> AppMutationManager<'a> { pub(crate) async fn mutate_shared_app( &self, app: &SharedSageApp, - f: impl for<'m> FnOnce( - &'m mut AppMutationContext, - ) -> Pin> + Send + 'm>> - + Send, + f: impl for<'m> AsyncFnOnce(&'m mut AppMutationContext) -> Result + Send, ) -> Result where T: Send, diff --git a/crates/sage-apps/src/lifecycle/storage.rs b/crates/sage-apps/src/lifecycle/storage.rs index 5acd5cf91..a6e84ed88 100644 --- a/crates/sage-apps/src/lifecycle/storage.rs +++ b/crates/sage-apps/src/lifecycle/storage.rs @@ -256,25 +256,23 @@ pub(crate) async fn rotate_app_storage_and_origin( let manager = AppMutationManager::new(app_handle, apps_state); manager - .mutate_shared_app(app, |ctx| { - Box::pin(async move { - let origin_row_id = ctx - .tx() - .register_origin(&next_origin_id, next_storage.storage_id) - .await?; - - ctx.tx() - .update_app_assignment(&app_id, next_storage.storage_id, origin_row_id) - .await?; - - ctx.draft_mut().replace_storage_and_origin( - next_storage.storage.clone(), - next_origin_id, - false, - )?; - - Ok(()) - }) + .mutate_shared_app(app, async |ctx| { + let origin_row_id = ctx + .tx() + .register_origin(&next_origin_id, next_storage.storage_id) + .await?; + + ctx.tx() + .update_app_assignment(&app_id, next_storage.storage_id, origin_row_id) + .await?; + + ctx.draft_mut().replace_storage_and_origin( + next_storage.storage.clone(), + next_origin_id, + false, + )?; + + Ok(()) }) .await .map_err(|err| format!("failed to rotate app storage/origin: {err}")) diff --git a/crates/sage-apps/src/lifecycle/update/apply.rs b/crates/sage-apps/src/lifecycle/update/apply.rs index a1e6e97ea..2a192db1d 100644 --- a/crates/sage-apps/src/lifecycle/update/apply.rs +++ b/crates/sage-apps/src/lifecycle/update/apply.rs @@ -183,16 +183,14 @@ async fn execute_app_update( let manager = AppMutationManager::new(app_handle, &apps_state); manager - .mutate_shared_app(&app, move |ctx| { - Box::pin(async move { - ctx.draft_mut() - .app_mut() - .apply_update(&pending, granted_permissions, snapshot)?; + .mutate_shared_app(&app, async move |ctx| { + ctx.draft_mut() + .app_mut() + .apply_update(&pending, granted_permissions, snapshot)?; - ctx.draft_mut().app_mut().set_pending_update(None)?; + ctx.draft_mut().app_mut().set_pending_update(None)?; - Ok(()) - }) + Ok(()) }) .await .map_err(io::Error::other)?; diff --git a/crates/sage-apps/src/lifecycle/update/check.rs b/crates/sage-apps/src/lifecycle/update/check.rs index 8e4615835..0aa19140a 100644 --- a/crates/sage-apps/src/lifecycle/update/check.rs +++ b/crates/sage-apps/src/lifecycle/update/check.rs @@ -29,12 +29,10 @@ pub(crate) async fn check_app_update_inner( let preview = match preview_app_update(&resolved).await? { AppUpdatePreviewResult::None => { mutation_manager - .mutate_shared_app(&app, |ctx| { - Box::pin(async move { - ctx.draft_mut().app_mut().set_pending_update(None)?; + .mutate_shared_app(&app, async |ctx| { + ctx.draft_mut().app_mut().set_pending_update(None)?; - Ok(()) - }) + Ok(()) }) .await .map_err(io::Error::other)?; @@ -67,14 +65,12 @@ pub(crate) async fn check_app_update_inner( }; mutation_manager - .mutate_shared_app(&app, |ctx| { - Box::pin(async move { - ctx.draft_mut() - .app_mut() - .set_pending_update(pending_update)?; - - Ok(()) - }) + .mutate_shared_app(&app, async |ctx| { + ctx.draft_mut() + .app_mut() + .set_pending_update(pending_update)?; + + Ok(()) }) .await .map_err(io::Error::other)?; diff --git a/crates/sage-apps/src/lifecycle/update/permissions.rs b/crates/sage-apps/src/lifecycle/update/permissions.rs index ffb89b039..cd5045387 100644 --- a/crates/sage-apps/src/lifecycle/update/permissions.rs +++ b/crates/sage-apps/src/lifecycle/update/permissions.rs @@ -203,20 +203,18 @@ async fn mutate_granted_permissions( let manager = AppMutationManager::new(app_handle, apps_state); manager - .mutate_shared_app(app, move |ctx| { - Box::pin(async move { - let previous = ctx.draft().app().common().granted_permissions().clone(); + .mutate_shared_app(app, async move |ctx| { + let previous = ctx.draft().app().common().granted_permissions().clone(); - ctx.draft_mut() - .update_permissions(&granted_permissions) - .context("failed to update app permissions")?; + ctx.draft_mut() + .update_permissions(&granted_permissions) + .context("failed to update app permissions")?; - let new = ctx.draft().app().common().granted_permissions().clone(); + let new = ctx.draft().app().common().granted_permissions().clone(); - Ok(AppUpdateResult::new(GrantedPermissionsChange::diff( - &previous, &new, - ))) - }) + Ok(AppUpdateResult::new(GrantedPermissionsChange::diff( + &previous, &new, + ))) }) .await .map_err(anyhow::Error::msg) diff --git a/crates/sage-apps/src/lifecycle/update/scope.rs b/crates/sage-apps/src/lifecycle/update/scope.rs index f21913c3a..9e8f41319 100644 --- a/crates/sage-apps/src/lifecycle/update/scope.rs +++ b/crates/sage-apps/src/lifecycle/update/scope.rs @@ -11,15 +11,13 @@ pub async fn update_app_wallet_scope_for_app( let manager = AppMutationManager::new(app_handle, &apps_state); manager - .mutate_shared_app(app, move |ctx| { - Box::pin(async move { - ctx.draft_mut() - .app_mut() - .common_mut() - .update_wallet_scope(wallet_scope); + .mutate_shared_app(app, async move |ctx| { + ctx.draft_mut() + .app_mut() + .common_mut() + .update_wallet_scope(wallet_scope); - Ok(()) - }) + Ok(()) }) .await .map_err(anyhow::Error::msg)?; diff --git a/crates/sage-apps/src/runtime/start.rs b/crates/sage-apps/src/runtime/start.rs index 020bd2379..6e594965b 100644 --- a/crates/sage-apps/src/runtime/start.rs +++ b/crates/sage-apps/src/runtime/start.rs @@ -366,13 +366,11 @@ async fn mark_origin_may_contain_secrets_if_needed( let manager = AppMutationManager::new(app_handle, apps_state); manager - .mutate_shared_app(app, |ctx| { - Box::pin(async move { - ctx.draft_mut() - .mark_origin_webview_storage_may_contain_secrets()?; + .mutate_shared_app(app, async |ctx| { + ctx.draft_mut() + .mark_origin_webview_storage_may_contain_secrets()?; - Ok(()) - }) + Ok(()) }) .await .map_err(|err| format!("failed to mark origin as containing secrets: {err}")) diff --git a/crates/sage-apps/src/runtime/state/read.rs b/crates/sage-apps/src/runtime/state/read.rs index 4b33bdd14..ee2d1fd11 100644 --- a/crates/sage-apps/src/runtime/state/read.rs +++ b/crates/sage-apps/src/runtime/state/read.rs @@ -3,8 +3,7 @@ use std::fmt::Display; use tauri::State; -use super::types::SharedRuntime; -use crate::{AppPresentation, AppsHostState, SageAppRuntimeVisibility}; +use crate::{AppPresentation, AppsHostState, SageAppRuntimeVisibility, SharedRuntime}; pub enum GetRuntimeError { NotFound, diff --git a/crates/sage-apps/src/runtime/state/write.rs b/crates/sage-apps/src/runtime/state/write.rs index 636b9ee6a..b44df8aaa 100644 --- a/crates/sage-apps/src/runtime/state/write.rs +++ b/crates/sage-apps/src/runtime/state/write.rs @@ -1,7 +1,6 @@ use tauri::State; -use super::types::{SageAppRuntimeRecord, SharedRuntime}; -use crate::AppsHostState; +use crate::{AppsHostState, SageAppRuntimeRecord, SharedRuntime}; pub(crate) async fn write_runtime( apps_state: &State<'_, AppsHostState>, diff --git a/crates/sage-apps/src/sandbox.rs b/crates/sage-apps/src/sandbox.rs index f8bd230f4..160715d53 100644 --- a/crates/sage-apps/src/sandbox.rs +++ b/crates/sage-apps/src/sandbox.rs @@ -17,4 +17,6 @@ pub use runner::*; pub use store::*; pub use types::*; +pub(crate) use probes::*; +pub(crate) use runtime::*; pub(crate) use state_view::*; diff --git a/crates/sage-apps/src/sandbox/commands.rs b/crates/sage-apps/src/sandbox/commands.rs index 6551994b8..37e70461a 100644 --- a/crates/sage-apps/src/sandbox/commands.rs +++ b/crates/sage-apps/src/sandbox/commands.rs @@ -1,10 +1,9 @@ use tauri::{AppHandle, State, command}; -use super::gate::evaluate_app_launch_gate; -use super::runner::{begin_sandbox_run, sandbox_runner}; -use super::state_view::{build_effective_state, build_state_view}; -use super::types::{AppLaunchGateResult, SandboxStateView}; -use crate::{AppsHostState, resolve_app}; +use crate::{ + AppLaunchGateResult, AppsHostState, SandboxStateView, begin_sandbox_run, build_effective_state, + build_state_view, evaluate_app_launch_gate, resolve_app, sandbox_runner, +}; #[command] #[specta::specta] diff --git a/crates/sage-apps/src/sandbox/gate.rs b/crates/sage-apps/src/sandbox/gate.rs index a80ff18c1..86280d15a 100644 --- a/crates/sage-apps/src/sandbox/gate.rs +++ b/crates/sage-apps/src/sandbox/gate.rs @@ -1,5 +1,7 @@ -use super::{AppLaunchGateResult, SandboxCapability, SandboxCapabilityStatus, SandboxState}; -use crate::{SharedSageApp, UserBridgeCapability}; +use crate::{ + AppLaunchGateResult, SandboxCapability, SandboxCapabilityStatus, SandboxState, SharedSageApp, + UserBridgeCapability, +}; fn capability_status( state: &SandboxState, diff --git a/crates/sage-apps/src/sandbox/ingest.rs b/crates/sage-apps/src/sandbox/ingest.rs index 45e8d1347..0f692dbb7 100644 --- a/crates/sage-apps/src/sandbox/ingest.rs +++ b/crates/sage-apps/src/sandbox/ingest.rs @@ -1,12 +1,10 @@ use serde_json::Value; use tauri::State; -use super::store::{SandboxAppResult, replace_by_app_id}; -use super::types::{ - SandboxIsolationProbeResult, SandboxNetworkProbeResult, SandboxPersistenceReadProbeResult, - SandboxPersistenceWriteProbeResult, +use crate::{ + AppsHostState, SandboxAppResult, SandboxIsolationProbeResult, SandboxNetworkProbeResult, + SandboxPersistenceReadProbeResult, SandboxPersistenceWriteProbeResult, replace_by_app_id, }; -use crate::AppsHostState; pub async fn ingest_bridge_send_payload( app_id: &str, diff --git a/crates/sage-apps/src/sandbox/probes.rs b/crates/sage-apps/src/sandbox/probes.rs index cfb98975a..6e616532e 100644 --- a/crates/sage-apps/src/sandbox/probes.rs +++ b/crates/sage-apps/src/sandbox/probes.rs @@ -3,6 +3,7 @@ mod network; mod persistence; mod poll; -pub(super) use isolation::*; -pub(super) use network::*; -pub(super) use persistence::*; +pub(crate) use isolation::*; +pub(crate) use network::*; +pub(crate) use persistence::*; +pub(crate) use poll::*; diff --git a/crates/sage-apps/src/sandbox/probes/isolation.rs b/crates/sage-apps/src/sandbox/probes/isolation.rs index 33b63794d..e030576b8 100644 --- a/crates/sage-apps/src/sandbox/probes/isolation.rs +++ b/crates/sage-apps/src/sandbox/probes/isolation.rs @@ -1,12 +1,11 @@ use tauri::{AppHandle, State}; -use super::super::runtime::{start_test_app, stop_test_apps, unique_run_id}; -use super::poll::poll_isolation; use crate::{ AppsHostState, BUILTIN_STORAGE_ISOLATION_INCOGNITO_ID, BUILTIN_STORAGE_ISOLATION_PERSISTENT_ID, + poll_isolation, start_test_app, stop_test_apps, unique_run_id, }; -pub(in crate::sandbox) async fn run_isolation_test( +pub(crate) async fn run_isolation_test( app: &AppHandle, apps_state: &State<'_, AppsHostState>, ) -> Result<(bool, Option), String> { diff --git a/crates/sage-apps/src/sandbox/probes/network.rs b/crates/sage-apps/src/sandbox/probes/network.rs index c01045a3c..529147494 100644 --- a/crates/sage-apps/src/sandbox/probes/network.rs +++ b/crates/sage-apps/src/sandbox/probes/network.rs @@ -1,10 +1,11 @@ use tauri::{AppHandle, State}; -use super::super::runtime::{start_test_app, stop_test_apps, unique_run_id}; -use super::poll::poll_network; -use crate::{AppsHostState, BUILTIN_NETWORK_ALLOW_A_ID, BUILTIN_NETWORK_ALLOW_B_ID}; +use crate::{ + AppsHostState, BUILTIN_NETWORK_ALLOW_A_ID, BUILTIN_NETWORK_ALLOW_B_ID, poll_network, + start_test_app, stop_test_apps, unique_run_id, +}; -pub(in crate::sandbox) async fn run_network_test( +pub(crate) async fn run_network_test( app: &AppHandle, apps_state: &State<'_, AppsHostState>, ) -> Result<(bool, Option), String> { diff --git a/crates/sage-apps/src/sandbox/probes/persistence.rs b/crates/sage-apps/src/sandbox/probes/persistence.rs index f705ba288..547e7f1ea 100644 --- a/crates/sage-apps/src/sandbox/probes/persistence.rs +++ b/crates/sage-apps/src/sandbox/probes/persistence.rs @@ -1,10 +1,11 @@ use tauri::{AppHandle, State}; -use super::super::runtime::{start_test_app, stop_test_apps, unique_run_id}; -use super::poll::{poll_persistence_read, poll_persistence_write}; -use crate::{AppsHostState, BUILTIN_PERSISTENCE_INCOGNITO_ID, BUILTIN_PERSISTENCE_PERSISTENT_ID}; +use crate::{ + AppsHostState, BUILTIN_PERSISTENCE_INCOGNITO_ID, BUILTIN_PERSISTENCE_PERSISTENT_ID, + poll_persistence_read, poll_persistence_write, start_test_app, stop_test_apps, unique_run_id, +}; -pub(in crate::sandbox) async fn run_persistence_test( +pub(crate) async fn run_persistence_test( app: &AppHandle, apps_state: &State<'_, AppsHostState>, ) -> Result<((bool, Option), (bool, Option)), String> { diff --git a/crates/sage-apps/src/sandbox/probes/poll.rs b/crates/sage-apps/src/sandbox/probes/poll.rs index d67f740db..aa9f0d075 100644 --- a/crates/sage-apps/src/sandbox/probes/poll.rs +++ b/crates/sage-apps/src/sandbox/probes/poll.rs @@ -1,12 +1,10 @@ use tauri::State; use tokio::time::{Duration, sleep}; -use super::super::store::SandboxAppResult; -use super::super::types::{ - SandboxIsolationProbeResult, SandboxNetworkProbeResult, SandboxPersistenceReadProbeResult, - SandboxPersistenceWriteProbeResult, +use crate::{ + AppsHostState, SandboxAppResult, SandboxIsolationProbeResult, SandboxNetworkProbeResult, + SandboxPersistenceReadProbeResult, SandboxPersistenceWriteProbeResult, unix_timestamp_ms, }; -use crate::{AppsHostState, unix_timestamp_ms}; pub async fn poll_isolation( apps_state: &State<'_, AppsHostState>, diff --git a/crates/sage-apps/src/sandbox/runner.rs b/crates/sage-apps/src/sandbox/runner.rs index dbdaf28a7..b893b074d 100644 --- a/crates/sage-apps/src/sandbox/runner.rs +++ b/crates/sage-apps/src/sandbox/runner.rs @@ -1,12 +1,11 @@ use tauri::{AppHandle, Manager, State}; -use super::probes::{run_isolation_test, run_network_test, run_persistence_test}; -use super::state_view::{build_effective_state, build_state_view}; -use super::types::{ - SandboxCapability, SandboxCapabilityStatus, SandboxRunState, SandboxState, - build_running_sandbox_state, mark_cap, +use crate::{ + AppsHostState, SandboxCapability, SandboxCapabilityStatus, SandboxRunState, SandboxState, + build_effective_state, build_running_sandbox_state, build_state_view, + emit_sandbox_state_changed, mark_cap, run_isolation_test, run_network_test, + run_persistence_test, unix_timestamp_ms, }; -use crate::{AppsHostState, emit_sandbox_state_changed, unix_timestamp_ms}; pub async fn ensure_initial_sandbox_run(app: AppHandle) -> Result<(), String> { let apps_state = app.state::(); diff --git a/crates/sage-apps/src/sandbox/runtime.rs b/crates/sage-apps/src/sandbox/runtime.rs index aff2e5750..f30b8b9aa 100644 --- a/crates/sage-apps/src/sandbox/runtime.rs +++ b/crates/sage-apps/src/sandbox/runtime.rs @@ -33,7 +33,7 @@ pub(crate) async fn start_test_app( .await } -pub(super) fn unique_run_id(prefix: &str) -> String { +pub(crate) fn unique_run_id(prefix: &str) -> String { format!("{prefix}-{}", Uuid::new_v4()) } diff --git a/crates/sage-apps/src/sandbox/state_view.rs b/crates/sage-apps/src/sandbox/state_view.rs index b5e7886b3..10ee60abc 100644 --- a/crates/sage-apps/src/sandbox/state_view.rs +++ b/crates/sage-apps/src/sandbox/state_view.rs @@ -1,10 +1,9 @@ use tauri::State; -use super::types::{ - SandboxCapabilityResult, SandboxCapabilityStatus, SandboxRunState, SandboxState, +use crate::{ + AppsHostState, SandboxCapabilityResult, SandboxCapabilityStatus, SandboxRunState, SandboxState, SandboxStateView, }; -use crate::AppsHostState; fn effective_cap( baseline: &SandboxCapabilityResult, diff --git a/crates/sage-apps/src/sandbox/store.rs b/crates/sage-apps/src/sandbox/store.rs index 73192d270..b6a38593b 100644 --- a/crates/sage-apps/src/sandbox/store.rs +++ b/crates/sage-apps/src/sandbox/store.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use tokio::sync::Mutex; -use super::types::{ +use crate::{ SandboxIsolationProbeResult, SandboxNetworkProbeResult, SandboxPersistenceReadProbeResult, SandboxPersistenceWriteProbeResult, SandboxRunState, build_initial_sandbox_state, }; diff --git a/crates/sage-apps/src/types/permissions/granted.rs b/crates/sage-apps/src/types/permissions/granted.rs index f119b8950..2d02df1f8 100644 --- a/crates/sage-apps/src/types/permissions/granted.rs +++ b/crates/sage-apps/src/types/permissions/granted.rs @@ -3,9 +3,9 @@ use std::collections::{BTreeMap, BTreeSet}; use serde::{Deserialize, Deserializer, Serialize}; use specta::Type; -use super::{SageRequestedNetworkPermissions, SageRequestedPermissions}; use crate::{ - SageNetworkWhitelistEntry, SharedCapabilitiesExt, SystemBridgeCapability, UserBridgeCapability, + SageNetworkWhitelistEntry, SageRequestedNetworkPermissions, SageRequestedPermissions, + SharedCapabilitiesExt, SystemBridgeCapability, UserBridgeCapability, build_user_grantable_capability_set, get_user_capability_definition, validate_permissions_policy, }; diff --git a/crates/sage-apps/src/types/permissions/tests.rs b/crates/sage-apps/src/types/permissions/tests.rs index 7b4795657..e15f3fc33 100644 --- a/crates/sage-apps/src/types/permissions/tests.rs +++ b/crates/sage-apps/src/types/permissions/tests.rs @@ -1,7 +1,10 @@ use std::collections::{BTreeMap, BTreeSet}; -use super::*; -use crate::{SageNetworkWhitelistEntry, SageRequestedNetworkWhitelist, UserBridgeCapability}; +use crate::{ + SageGrantedPermissions, SageNetworkWhitelistEntry, SageRequestedCapabilities, + SageRequestedNetworkPermissions, SageRequestedNetworkWhitelist, SageRequestedPermissions, + UserBridgeCapability, +}; fn network_entry(scheme: &str, host: &str) -> SageNetworkWhitelistEntry { SageNetworkWhitelistEntry::new(scheme, host).unwrap() diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index b01effa27..6983d5202 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -48,7 +48,6 @@ futures = "0.3.32" uuid = { version = "1.19.0", features = ["v4"] } sha2 = "0.10.9" hex = { workspace = true } -async-trait = "0.1.89" [dev-dependencies] tempfile = "3"