Skip to content

Commit 490a6b4

Browse files
authored
refactor(core): add setup() to the Assets trait (#9147)
* feat(core): allow swapping the assets implemenetation * refactor(core): add setup() to the Assets trait * code review
1 parent 85de230 commit 490a6b4

File tree

13 files changed

+101
-60
lines changed

13 files changed

+101
-60
lines changed

.changes/assets-setup.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch:feat
3+
---
4+
5+
The `Assets` trait now include a `setup` method that lets you run initialization code for your custom asset provider.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch:breaking
3+
---
4+
5+
The `Context` struct and the `Assets` trait now takes a `R: Runtime` generic.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch:breaking
3+
---
4+
5+
Removed `Context::assets_mut` and added `Context::set_assets`.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-utils": patch:breaking
3+
---
4+
5+
Removed the `assets::Assets` trait which is now part of the `tauri` crate.

core/tauri-codegen/src/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,10 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
345345
let info_plist = quote!(());
346346

347347
let pattern = match &options.pattern {
348-
PatternKind::Brownfield => quote!(#root::Pattern::Brownfield(std::marker::PhantomData)),
348+
PatternKind::Brownfield => quote!(#root::Pattern::Brownfield),
349349
#[cfg(not(feature = "isolation"))]
350350
PatternKind::Isolation { dir: _ } => {
351-
quote!(#root::Pattern::Brownfield(std::marker::PhantomData))
351+
quote!(#root::Pattern::Brownfield)
352352
}
353353
#[cfg(feature = "isolation")]
354354
PatternKind::Isolation { dir } => {

core/tauri-plugin/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ runtime = [ ]
3030
[dependencies]
3131
anyhow = { version = "1", optional = true }
3232
serde = { version = "1", optional = true }
33-
tauri-utils = { version = "2.0.0-beta.8", default-features = false, path = "../tauri-utils" }
33+
tauri-utils = { version = "2.0.0-beta.8", default-features = false, features = [ "build" ], path = "../tauri-utils" }
3434
serde_json = { version = "1", optional = true }
3535
glob = { version = "0.3", optional = true }
3636
toml = { version = "0.8", optional = true }

core/tauri-utils/src/assets.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -104,18 +104,6 @@ impl CspHash<'_> {
104104
}
105105
}
106106

107-
/// Represents a container of file assets that are retrievable during runtime.
108-
pub trait Assets: Send + Sync + 'static {
109-
/// Get the content of the passed [`AssetKey`].
110-
fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>>;
111-
112-
/// Iterator for the assets.
113-
fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_>;
114-
115-
/// Gets the hashes for the CSP tag of the HTML on the given path.
116-
fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_>;
117-
}
118-
119107
/// [`Assets`] implementation that only contains compile-time compressed and embedded assets.
120108
#[derive(Debug)]
121109
pub struct EmbeddedAssets {
@@ -139,11 +127,10 @@ impl EmbeddedAssets {
139127
html_hashes,
140128
}
141129
}
142-
}
143130

144-
impl Assets for EmbeddedAssets {
131+
/// Get an asset by key.
145132
#[cfg(feature = "compression")]
146-
fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>> {
133+
pub fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>> {
147134
self
148135
.assets
149136
.get(key.as_ref())
@@ -157,20 +144,23 @@ impl Assets for EmbeddedAssets {
157144
.map(Cow::Owned)
158145
}
159146

147+
/// Get an asset by key.
160148
#[cfg(not(feature = "compression"))]
161-
fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>> {
149+
pub fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>> {
162150
self
163151
.assets
164152
.get(key.as_ref())
165153
.copied()
166154
.map(|a| Cow::Owned(a.to_vec()))
167155
}
168156

169-
fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_> {
170-
Box::new(self.assets.into_iter())
157+
/// Iterate on the assets.
158+
pub fn iter(&self) -> Box<dyn Iterator<Item = (&str, &[u8])> + '_> {
159+
Box::new(self.assets.into_iter().map(|(k, b)| (*k, *b)))
171160
}
172161

173-
fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_> {
162+
/// CSP hashes for the given asset.
163+
pub fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_> {
174164
Box::new(
175165
self
176166
.global_hashes

core/tauri/src/app.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ impl<R: Runtime> AssetResolver<R> {
266266
}
267267

268268
/// Iterate on all assets.
269-
pub fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_> {
269+
pub fn iter(&self) -> Box<dyn Iterator<Item = (&str, &[u8])> + '_> {
270270
self.manager.assets.iter()
271271
}
272272
}
@@ -1581,7 +1581,7 @@ tauri::Builder::default()
15811581
feature = "tracing",
15821582
tracing::instrument(name = "app::build", skip_all)
15831583
)]
1584-
pub fn build(mut self, context: Context) -> crate::Result<App<R>> {
1584+
pub fn build(mut self, context: Context<R>) -> crate::Result<App<R>> {
15851585
#[cfg(target_os = "macos")]
15861586
if self.menu.is_none() && self.enable_macos_default_menu {
15871587
self.menu = Some(Box::new(|app_handle| {
@@ -1749,7 +1749,7 @@ tauri::Builder::default()
17491749
}
17501750

17511751
/// Runs the configured Tauri application.
1752-
pub fn run(self, context: Context) -> crate::Result<()> {
1752+
pub fn run(self, context: Context<R>) -> crate::Result<()> {
17531753
self.build(context)?.run(|_, _| {});
17541754
Ok(())
17551755
}
@@ -1824,6 +1824,8 @@ fn setup<R: Runtime>(app: &mut App<R>) -> crate::Result<()> {
18241824
.build_internal(&window_labels, &webview_labels)?;
18251825
}
18261826

1827+
app.manager.assets.setup(app);
1828+
18271829
if let Some(setup) = app.setup.take() {
18281830
(setup)(app).map_err(|e| crate::Error::Setup(e.into()))?;
18291831
}

core/tauri/src/lib.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,12 @@ pub type SyncTask = Box<dyn FnOnce() + Send>;
192192

193193
use serde::Serialize;
194194
use std::{
195+
borrow::Cow,
195196
collections::HashMap,
196197
fmt::{self, Debug},
197198
sync::MutexGuard,
198199
};
200+
use utils::assets::{AssetKey, CspHash, EmbeddedAssets};
199201

200202
#[cfg(feature = "wry")]
201203
#[cfg_attr(docsrs, doc(cfg(feature = "wry")))]
@@ -224,7 +226,6 @@ pub use {
224226
},
225227
self::state::{State, StateManager},
226228
self::utils::{
227-
assets::Assets,
228229
config::{Config, WebviewUrl},
229230
Env, PackageInfo, Theme,
230231
},
@@ -338,14 +339,47 @@ pub fn dev() -> bool {
338339
!cfg!(feature = "custom-protocol")
339340
}
340341

342+
/// Represents a container of file assets that are retrievable during runtime.
343+
pub trait Assets<R: Runtime>: Send + Sync + 'static {
344+
/// Initialize the asset provider.
345+
fn setup(&self, app: &App<R>) {
346+
let _ = app;
347+
}
348+
349+
/// Get the content of the passed [`AssetKey`].
350+
fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>>;
351+
352+
/// Iterator for the assets.
353+
fn iter(&self) -> Box<dyn Iterator<Item = (&str, &[u8])> + '_>;
354+
355+
/// Gets the hashes for the CSP tag of the HTML on the given path.
356+
fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_>;
357+
}
358+
359+
impl<R: Runtime> Assets<R> for EmbeddedAssets {
360+
fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>> {
361+
EmbeddedAssets::get(self, key)
362+
}
363+
364+
fn iter(&self) -> Box<dyn Iterator<Item = (&str, &[u8])> + '_> {
365+
EmbeddedAssets::iter(self)
366+
}
367+
368+
fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_> {
369+
EmbeddedAssets::csp_hashes(self, html_path)
370+
}
371+
}
372+
341373
/// User supplied data required inside of a Tauri application.
342374
///
343375
/// # Stability
344376
/// This is the output of the [`generate_context`] macro, and is not considered part of the stable API.
345377
/// Unless you know what you are doing and are prepared for this type to have breaking changes, do not create it yourself.
346-
pub struct Context {
378+
#[tauri_macros::default_runtime(Wry, wry)]
379+
pub struct Context<R: Runtime> {
347380
pub(crate) config: Config,
348-
pub(crate) assets: Box<dyn Assets>,
381+
/// Asset provider.
382+
pub assets: Box<dyn Assets<R>>,
349383
pub(crate) default_window_icon: Option<image::Image<'static>>,
350384
pub(crate) app_icon: Option<Vec<u8>>,
351385
#[cfg(all(desktop, feature = "tray-icon"))]
@@ -356,7 +390,7 @@ pub struct Context {
356390
pub(crate) runtime_authority: RuntimeAuthority,
357391
}
358392

359-
impl fmt::Debug for Context {
393+
impl<R: Runtime> fmt::Debug for Context<R> {
360394
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361395
let mut d = f.debug_struct("Context");
362396
d.field("config", &self.config)
@@ -372,7 +406,7 @@ impl fmt::Debug for Context {
372406
}
373407
}
374408

375-
impl Context {
409+
impl<R: Runtime> Context<R> {
376410
/// The config the application was prepared with.
377411
#[inline(always)]
378412
pub fn config(&self) -> &Config {
@@ -387,14 +421,14 @@ impl Context {
387421

388422
/// The assets to be served directly by Tauri.
389423
#[inline(always)]
390-
pub fn assets(&self) -> &dyn Assets {
424+
pub fn assets(&self) -> &dyn Assets<R> {
391425
self.assets.as_ref()
392426
}
393427

394-
/// A mutable reference to the assets to be served directly by Tauri.
428+
/// Replace the [`Assets`] implementation and returns the previous value so you can use it as a fallback if desired.
395429
#[inline(always)]
396-
pub fn assets_mut(&mut self) -> &mut Box<dyn Assets> {
397-
&mut self.assets
430+
pub fn set_assets(&mut self, assets: Box<dyn Assets<R>>) -> Box<dyn Assets<R>> {
431+
std::mem::replace(&mut self.assets, assets)
398432
}
399433

400434
/// The default window icon Tauri should use when creating windows.
@@ -459,7 +493,7 @@ impl Context {
459493
#[allow(clippy::too_many_arguments)]
460494
pub fn new(
461495
config: Config,
462-
assets: Box<dyn Assets>,
496+
assets: Box<dyn Assets<R>>,
463497
default_window_icon: Option<image::Image<'static>>,
464498
app_icon: Option<Vec<u8>>,
465499
package_info: PackageInfo,

core/tauri/src/manager/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use crate::{
2424
event::{assert_event_name_is_valid, Event, EventId, EventTarget, Listeners},
2525
ipc::{Invoke, InvokeHandler, InvokeResponder, RuntimeAuthority},
2626
plugin::PluginStore,
27-
utils::{assets::Assets, config::Config, PackageInfo},
28-
Context, Pattern, Runtime, StateManager, Window,
27+
utils::{config::Config, PackageInfo},
28+
Assets, Context, Pattern, Runtime, StateManager, Window,
2929
};
3030
use crate::{event::EmitArgs, resources::ResourceTable, Webview};
3131

@@ -48,7 +48,7 @@ struct CspHashStrings {
4848
#[allow(clippy::borrowed_box)]
4949
pub(crate) fn set_csp<R: Runtime>(
5050
asset: &mut String,
51-
assets: &impl std::borrow::Borrow<dyn Assets>,
51+
assets: &impl std::borrow::Borrow<dyn Assets<R>>,
5252
asset_path: &AssetKey,
5353
manager: &AppManager<R>,
5454
csp: Csp,
@@ -179,7 +179,7 @@ pub struct AppManager<R: Runtime> {
179179
pub listeners: Listeners,
180180
pub state: Arc<StateManager>,
181181
pub config: Config,
182-
pub assets: Box<dyn Assets>,
182+
pub assets: Box<dyn Assets<R>>,
183183

184184
pub app_icon: Option<Vec<u8>>,
185185

@@ -216,7 +216,7 @@ impl<R: Runtime> fmt::Debug for AppManager<R> {
216216
impl<R: Runtime> AppManager<R> {
217217
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
218218
pub(crate) fn with_handlers(
219-
#[allow(unused_mut)] mut context: Context,
219+
#[allow(unused_mut)] mut context: Context<R>,
220220
plugins: PluginStore<R>,
221221
invoke_handler: Box<InvokeHandler<R>>,
222222
on_page_load: Option<Arc<OnPageLoad<R>>>,

0 commit comments

Comments
 (0)