diff --git a/.changes/codegen-set-assets.md b/.changes/codegen-set-assets.md new file mode 100644 index 000000000..efa70d526 --- /dev/null +++ b/.changes/codegen-set-assets.md @@ -0,0 +1,6 @@ +--- +"tauri-macros": patch:feat +"tauri-codegen": patch:feat +--- + +The `Context` codegen now accepts a `assets` input to define a custom `tauri::Assets` implementation. diff --git a/.changes/context-assets-unbox.md b/.changes/context-assets-unbox.md new file mode 100644 index 000000000..85bc756cb --- /dev/null +++ b/.changes/context-assets-unbox.md @@ -0,0 +1,5 @@ +--- +"tauri": patch:breaking +--- + +`Context::assets` now returns `&dyn Assets` instead of `Box<&dyn Assets>`. diff --git a/.changes/context-remove-assets-generics.md b/.changes/context-remove-assets-generics.md new file mode 100644 index 000000000..3fc550477 --- /dev/null +++ b/.changes/context-remove-assets-generics.md @@ -0,0 +1,5 @@ +--- +"tauri": patch:breaking +--- + +The `Context` type no longer uses the `` generic so the assets implementation can be swapped with `Context::assets_mut`. diff --git a/core/tauri-build/src/codegen/context.rs b/core/tauri-build/src/codegen/context.rs index 01ed33612..0bd8dbcf5 100644 --- a/core/tauri-build/src/codegen/context.rs +++ b/core/tauri-build/src/codegen/context.rs @@ -128,6 +128,7 @@ impl CodegenContext { // outside the tauri crate, making the ::tauri root valid. root: quote::quote!(::tauri), capabilities: self.capabilities, + assets: None, })?; // get the full output file path diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index dc48e4ee4..97182e2fe 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -12,6 +12,7 @@ use proc_macro2::TokenStream; use quote::quote; use sha2::{Digest, Sha256}; +use syn::Expr; use tauri_utils::acl::capability::{Capability, CapabilityFile}; use tauri_utils::acl::manifest::Manifest; use tauri_utils::acl::resolved::Resolved; @@ -36,6 +37,8 @@ pub struct ContextData { pub root: TokenStream, /// Additional capabilities to include. pub capabilities: Option>, + /// The custom assets implementation + pub assets: Option, } fn inject_script_hashes(document: &NodeRef, key: &AssetKey, csp_hashes: &mut CspHashes) { @@ -132,6 +135,7 @@ pub fn context_codegen(data: ContextData) -> Result Result match url { FrontendDist::Url(_url) => Default::default(), FrontendDist::Directory(path) => { @@ -190,7 +197,8 @@ pub fn context_codegen(data: ContextData) -> Result unimplemented!(), }, None => Default::default(), - } + }; + quote!(#assets) }; let out_dir = { diff --git a/core/tauri-macros/src/context.rs b/core/tauri-macros/src/context.rs index 0166d0d0a..9b166919b 100644 --- a/core/tauri-macros/src/context.rs +++ b/core/tauri-macros/src/context.rs @@ -17,6 +17,7 @@ pub(crate) struct ContextItems { config_file: PathBuf, root: syn::Path, capabilities: Option>, + assets: Option, } impl Parse for ContextItems { @@ -29,6 +30,7 @@ impl Parse for ContextItems { let mut root = None; let mut capabilities = None; + let mut assets = None; let config_file = input.parse::().ok().map(|raw| { let _ = input.parse::(); let path = PathBuf::from(raw.value()); @@ -57,32 +59,44 @@ impl Parse for ContextItems { root.replace(p); } Meta::NameValue(v) => { - if *v.path.require_ident()? == "capabilities" { - if let Expr::Array(array) = v.value { - capabilities.replace( - array - .elems - .into_iter() - .map(|e| { - if let Expr::Lit(ExprLit { - attrs: _, - lit: Lit::Str(s), - }) = e - { - Ok(s.value().into()) - } else { - Err(syn::Error::new( - input.span(), - "unexpected expression for capability", - )) - } - }) - .collect::, syn::Error>>()?, - ); - } else { + let ident = v.path.require_ident()?; + match ident.to_string().as_str() { + "capabilities" => { + if let Expr::Array(array) = v.value { + capabilities.replace( + array + .elems + .into_iter() + .map(|e| { + if let Expr::Lit(ExprLit { + attrs: _, + lit: Lit::Str(s), + }) = e + { + Ok(s.value().into()) + } else { + Err(syn::Error::new( + input.span(), + "unexpected expression for capability", + )) + } + }) + .collect::, syn::Error>>()?, + ); + } else { + return Err(syn::Error::new( + input.span(), + "unexpected value for capabilities", + )); + } + } + "assets" => { + assets.replace(v.value); + } + name => { return Err(syn::Error::new( input.span(), - "unexpected value for capabilities", + format!("unknown attribute {name}"), )); } } @@ -113,6 +127,7 @@ impl Parse for ContextItems { } }), capabilities, + assets, }) } } @@ -126,6 +141,7 @@ pub(crate) fn generate_context(context: ContextItems) -> TokenStream { config_parent, root: context.root.to_token_stream(), capabilities: context.capabilities, + assets: context.assets, }) .and_then(|data| context_codegen(data).map_err(|e| e.to_string())); diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index ba748f193..82c7cb350 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -19,7 +19,7 @@ use crate::{ }, sealed::{ManagerBase, RuntimeOrDispatch}, utils::config::Config, - utils::{assets::Assets, Env}, + utils::Env, webview::PageLoadPayload, Context, DeviceEventFilter, EventLoopMessage, Manager, Monitor, Runtime, Scopes, StateManager, Theme, Webview, WebviewWindowBuilder, Window, @@ -1581,7 +1581,7 @@ tauri::Builder::default() feature = "tracing", tracing::instrument(name = "app::build", skip_all) )] - pub fn build(mut self, context: Context) -> crate::Result> { + pub fn build(mut self, context: Context) -> crate::Result> { #[cfg(target_os = "macos")] if self.menu.is_none() && self.enable_macos_default_menu { self.menu = Some(Box::new(|app_handle| { @@ -1749,7 +1749,7 @@ tauri::Builder::default() } /// Runs the configured Tauri application. - pub fn run(self, context: Context) -> crate::Result<()> { + pub fn run(self, context: Context) -> crate::Result<()> { self.build(context)?.run(|_, _| {}); Ok(()) } diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index 0857f030e..4d86a963f 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -343,9 +343,9 @@ pub fn dev() -> bool { /// # Stability /// This is the output of the [`generate_context`] macro, and is not considered part of the stable API. /// Unless you know what you are doing and are prepared for this type to have breaking changes, do not create it yourself. -pub struct Context { +pub struct Context { pub(crate) config: Config, - pub(crate) assets: Box, + pub(crate) assets: Box, pub(crate) default_window_icon: Option>, pub(crate) app_icon: Option>, #[cfg(all(desktop, feature = "tray-icon"))] @@ -356,7 +356,7 @@ pub struct Context { pub(crate) runtime_authority: RuntimeAuthority, } -impl fmt::Debug for Context { +impl fmt::Debug for Context { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_struct("Context"); d.field("config", &self.config) @@ -372,7 +372,7 @@ impl fmt::Debug for Context { } } -impl Context { +impl Context { /// The config the application was prepared with. #[inline(always)] pub fn config(&self) -> &Config { @@ -387,13 +387,13 @@ impl Context { /// The assets to be served directly by Tauri. #[inline(always)] - pub fn assets(&self) -> &A { - &self.assets + pub fn assets(&self) -> &dyn Assets { + self.assets.as_ref() } /// A mutable reference to the assets to be served directly by Tauri. #[inline(always)] - pub fn assets_mut(&mut self) -> &mut A { + pub fn assets_mut(&mut self) -> &mut Box { &mut self.assets } @@ -459,7 +459,7 @@ impl Context { #[allow(clippy::too_many_arguments)] pub fn new( config: Config, - assets: Box, + assets: Box, default_window_icon: Option>, app_icon: Option>, package_info: PackageInfo, diff --git a/core/tauri/src/manager/mod.rs b/core/tauri/src/manager/mod.rs index fa70ccd06..8f2fb515d 100644 --- a/core/tauri/src/manager/mod.rs +++ b/core/tauri/src/manager/mod.rs @@ -216,7 +216,7 @@ impl fmt::Debug for AppManager { impl AppManager { #[allow(clippy::too_many_arguments, clippy::type_complexity)] pub(crate) fn with_handlers( - #[allow(unused_mut)] mut context: Context, + #[allow(unused_mut)] mut context: Context, plugins: PluginStore, invoke_handler: Box>, on_page_load: Option>>, diff --git a/core/tauri/src/test/mod.rs b/core/tauri/src/test/mod.rs index 507b18a06..bb09df1e8 100644 --- a/core/tauri/src/test/mod.rs +++ b/core/tauri/src/test/mod.rs @@ -94,7 +94,7 @@ pub fn noop_assets() -> NoopAsset { } /// Creates a new [`crate::Context`] for testing. -pub fn mock_context(assets: A) -> crate::Context { +pub fn mock_context(assets: A) -> crate::Context { Context { config: Config { schema: None, diff --git a/examples/splashscreen/main.rs b/examples/splashscreen/main.rs index 04ab2c518..a161ef345 100644 --- a/examples/splashscreen/main.rs +++ b/examples/splashscreen/main.rs @@ -78,7 +78,7 @@ mod ui { } } -fn context() -> tauri::Context { +fn context() -> tauri::Context { tauri::generate_context!("../../examples/splashscreen/tauri.conf.json") }