feat(core): add `Manager::unmanage` (#11071)

* feat(core): add `Manager::unmanage`

closes #10897

* remove state craet

* fix typo

* Update crates/tauri/src/lib.rs

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
Amr Bashir 2024-09-20 13:53:58 +03:00 committed by GitHub
parent b88e22a5fe
commit 0ddfc59d67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 124 additions and 186 deletions

View File

@ -0,0 +1,6 @@
---
"tauri": "patch:feat"
---
Add `Manager::unmanage` to remove previously managed state.

182
Cargo.lock generated
View File

@ -875,7 +875,7 @@ dependencies = [
"toml 0.8.19",
"ureq",
"which 6.0.3",
"windows 0.58.0",
"windows",
"x509-certificate",
]
@ -2068,8 +2068,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2"
dependencies = [
"bit-set",
"regex-automata 0.4.7",
"regex-syntax 0.8.4",
"regex-automata",
"regex-syntax",
]
[[package]]
@ -2496,19 +2496,6 @@ dependencies = [
"x11",
]
[[package]]
name = "generator"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
dependencies = [
"cc",
"libc",
"log",
"rustversion",
"windows 0.48.0",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@ -2664,8 +2651,8 @@ dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata 0.4.7",
"regex-syntax 0.8.4",
"regex-automata",
"regex-syntax",
]
[[package]]
@ -3111,7 +3098,7 @@ dependencies = [
"globset",
"log",
"memchr",
"regex-automata 0.4.7",
"regex-automata",
"same-file",
"walkdir",
"winapi-util",
@ -3858,21 +3845,6 @@ dependencies = [
"value-bag",
]
[[package]]
name = "loom"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
"serde",
"serde_json",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "loop9"
version = "0.1.5"
@ -3935,15 +3907,6 @@ dependencies = [
"tendril",
]
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "matches"
version = "0.1.10"
@ -4321,16 +4284,6 @@ dependencies = [
"notify",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]]
name = "num"
version = "0.4.3"
@ -4750,12 +4703,6 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "owo-colors"
version = "4.0.0"
@ -5507,7 +5454,7 @@ dependencies = [
"rand 0.8.5",
"rand_chacha 0.3.1",
"rand_xorshift",
"regex-syntax 0.8.4",
"regex-syntax",
"rusty-fork",
"tempfile",
"unarray",
@ -5841,17 +5788,8 @@ checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.7",
"regex-syntax 0.8.4",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax 0.6.29",
"regex-automata",
"regex-syntax",
]
[[package]]
@ -5862,15 +5800,9 @@ checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.4",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.4"
@ -6323,12 +6255,6 @@ dependencies = [
"syn 2.0.77",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -6703,15 +6629,6 @@ dependencies = [
"keccak",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "shared_child"
version = "1.0.1"
@ -6987,15 +6904,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "state"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8"
dependencies = [
"loom",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
@ -7274,7 +7182,7 @@ dependencies = [
"tao-macros",
"unicode-segmentation",
"url",
"windows 0.58.0",
"windows",
"windows-core 0.58.0",
"windows-version",
"x11-dl",
@ -7354,7 +7262,6 @@ dependencies = [
"serde_repr",
"serialize-to-javascript",
"specta",
"state",
"swift-rs",
"tauri",
"tauri-build",
@ -7372,7 +7279,7 @@ dependencies = [
"webkit2gtk",
"webview2-com",
"window-vibrancy",
"windows 0.58.0",
"windows",
]
[[package]]
@ -7701,7 +7608,7 @@ dependencies = [
"tauri-utils 2.0.0-rc.12",
"thiserror",
"url",
"windows 0.58.0",
"windows",
]
[[package]]
@ -7725,7 +7632,7 @@ dependencies = [
"url",
"webkit2gtk",
"webview2-com",
"windows 0.58.0",
"windows",
"wry",
]
@ -7949,16 +7856,6 @@ dependencies = [
"syn 2.0.77",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tiff"
version = "0.9.1"
@ -8274,36 +8171,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"regex",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
[[package]]
@ -8643,12 +8510,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "value-bag"
version = "1.9.0"
@ -8920,7 +8781,7 @@ checksum = "6f61ff3d9d0ee4efcb461b14eb3acfda2702d10dc329f339303fc3e57215ae2c"
dependencies = [
"webview2-com-macros",
"webview2-com-sys",
"windows 0.58.0",
"windows",
"windows-core 0.58.0",
"windows-implement",
"windows-interface",
@ -8944,7 +8805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3a3e2eeb58f82361c93f9777014668eb3d07e7d174ee4c819575a9208011886"
dependencies = [
"thiserror",
"windows 0.58.0",
"windows",
"windows-core 0.58.0",
]
@ -9022,15 +8883,6 @@ dependencies = [
"windows-version",
]
[[package]]
name = "windows"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows"
version = "0.58.0"
@ -9482,7 +9334,7 @@ dependencies = [
"webkit2gtk",
"webkit2gtk-sys",
"webview2-com",
"windows 0.58.0",
"windows",
"windows-core 0.58.0",
"windows-version",
"x11-dl",

View File

@ -65,7 +65,6 @@ tauri-utils = { version = "2.0.0-rc.12", features = [
tauri-runtime-wry = { version = "2.0.0-rc.13", path = "../tauri-runtime-wry", optional = true }
getrandom = "0.2"
serde_repr = "0.1"
state = "0.6"
http = "1.1"
dirs = "5"
percent-encoding = "2.3"

View File

@ -8,7 +8,6 @@ use std::sync::Arc;
use serde::de::DeserializeOwned;
use serde::Serialize;
use state::TypeMap;
use tauri_utils::acl::{
capability::{Capability, CapabilityFile, PermissionEntry},
@ -24,7 +23,7 @@ use tauri_utils::platform::Target;
use url::Url;
use crate::{ipc::InvokeError, sealed::ManagerBase, Runtime};
use crate::{AppHandle, Manager};
use crate::{AppHandle, Manager, StateManager};
use super::{CommandArg, CommandItem};
@ -232,7 +231,7 @@ impl RuntimeAuthority {
let command_cache = resolved_acl
.command_scope
.keys()
.map(|key| (*key, <TypeMap![Send + Sync]>::new()))
.map(|key| (*key, StateManager::new()))
.collect();
Self {
acl,
@ -242,7 +241,7 @@ impl RuntimeAuthority {
command_scope: resolved_acl.command_scope,
global_scope: resolved_acl.global_scope,
command_cache,
global_scope_cache: Default::default(),
global_scope_cache: StateManager::new(),
},
}
}
@ -297,7 +296,7 @@ impl RuntimeAuthority {
global_scope_entry.allow.extend(global_scope.allow);
global_scope_entry.deny.extend(global_scope.deny);
self.scope_manager.global_scope_cache = Default::default();
self.scope_manager.global_scope_cache = StateManager::new();
}
// denied commands
@ -708,8 +707,8 @@ impl<'a, R: Runtime, T: ScopeObject> CommandArg<'a, R> for GlobalScope<T> {
pub struct ScopeManager {
command_scope: BTreeMap<ScopeKey, ResolvedScope>,
global_scope: BTreeMap<String, ResolvedScope>,
command_cache: BTreeMap<ScopeKey, TypeMap![Send + Sync]>,
global_scope_cache: TypeMap![Send + Sync],
command_cache: BTreeMap<ScopeKey, StateManager>,
global_scope_cache: StateManager,
}
/// Marks a type as a scope object.
@ -737,7 +736,7 @@ impl ScopeManager {
key: &str,
) -> crate::Result<ScopeValue<T>> {
match self.global_scope_cache.try_get::<ScopeValue<T>>() {
Some(cached) => Ok(cached.clone()),
Some(cached) => Ok(cached.inner().clone()),
None => {
let mut allow = Vec::new();
let mut deny = Vec::new();
@ -774,7 +773,7 @@ impl ScopeManager {
) -> crate::Result<ScopeValue<T>> {
let cache = self.command_cache.get(key).unwrap();
match cache.try_get::<ScopeValue<T>>() {
Some(cached) => Ok(cached.clone()),
Some(cached) => Ok(cached.inner().clone()),
None => {
let resolved_scope = self
.command_scope

View File

@ -699,6 +699,14 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
self.manager().state().set(state)
}
/// Removes the state managed by the application for T. Returns `true` if it was actually removed
fn unmanage<T>(&self) -> bool
where
T: Send + Sync + 'static,
{
self.manager().state().unmanage::<T>()
}
/// Retrieves the managed state for the type `T`.
///
/// # Panics

View File

@ -2,11 +2,18 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use std::{
any::{Any, TypeId},
cell::UnsafeCell,
collections::HashMap,
hash::BuildHasherDefault,
sync::Mutex,
};
use crate::{
ipc::{CommandArg, CommandItem, InvokeError},
Runtime,
};
use state::TypeMap;
/// A guard for a state value.
///
@ -56,31 +63,98 @@ impl<'r, 'de: 'r, T: Send + Sync + 'static, R: Runtime> CommandArg<'de, R> for S
}
}
// Taken from: https://github.com/SergioBenitez/state/blob/556c1b94db8ce8427a0e72de7983ab5a9af4cc41/src/ident_hash.rs
// This is a _super_ stupid hash. It just uses its input as the hash value. This
// hash is meant to be used _only_ for "prehashed" values. In particular, we use
// this so that hashing a TypeId is essentially a noop. This is because TypeIds
// are already unique integers.
#[derive(Default)]
struct IdentHash(u64);
impl std::hash::Hasher for IdentHash {
fn finish(&self) -> u64 {
self.0
}
fn write(&mut self, bytes: &[u8]) {
for byte in bytes {
self.write_u8(*byte);
}
}
fn write_u8(&mut self, i: u8) {
self.0 = (self.0 << 8) | (i as u64);
}
fn write_u64(&mut self, i: u64) {
self.0 = i;
}
}
type TypeIdMap = HashMap<TypeId, Box<dyn Any>, BuildHasherDefault<IdentHash>>;
/// The Tauri state manager.
#[derive(Debug)]
pub struct StateManager(pub(crate) TypeMap![Send + Sync]);
pub struct StateManager {
map: Mutex<UnsafeCell<TypeIdMap>>,
}
// SAFETY: data is accessed behind a lock
unsafe impl Sync for StateManager {}
unsafe impl Send for StateManager {}
impl StateManager {
pub(crate) fn new() -> Self {
Self(<TypeMap![Send + Sync]>::new())
Self {
map: Default::default(),
}
}
fn with_map_ref<'a, F: FnOnce(&'a TypeIdMap) -> R, R>(&'a self, f: F) -> R {
let map = self.map.lock().unwrap();
let map = map.get();
// SAFETY: safe to access since we are holding a lock
f(unsafe { &*map })
}
fn with_map_mut<F: FnOnce(&mut TypeIdMap) -> R, R>(&self, f: F) -> R {
let mut map = self.map.lock().unwrap();
let map = map.get_mut();
f(map)
}
pub(crate) fn set<T: Send + Sync + 'static>(&self, state: T) -> bool {
self.0.set(state)
self.with_map_mut(|map| {
let type_id = TypeId::of::<T>();
let already_set = map.contains_key(&type_id);
if !already_set {
map.insert(type_id, Box::new(state) as Box<dyn Any>);
}
!already_set
})
}
pub(crate) fn unmanage<T: Send + Sync + 'static>(&self) -> bool {
self.with_map_mut(|map| {
let type_id = TypeId::of::<T>();
map.remove(&type_id).is_some()
})
}
/// Gets the state associated with the specified type.
pub fn get<T: Send + Sync + 'static>(&self) -> State<'_, T> {
State(
self
.0
.try_get()
.expect("state: get() called before set() for given type"),
)
self
.try_get()
.expect("state: get() when given type is not managed")
}
/// Gets the state associated with the specified type.
pub fn try_get<T: Send + Sync + 'static>(&self) -> Option<State<'_, T>> {
self.0.try_get().map(State)
self.with_map_ref(|map| {
map
.get(&TypeId::of::<T>())
.and_then(|ptr| ptr.downcast_ref::<T>())
.map(State)
})
}
}