// Copyright 2019-2024 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT use crate::{ ipc::{CommandArg, CommandItem, InvokeError}, Runtime, }; use state::TypeMap; /// A guard for a state value. /// /// See [`Manager::manage`](`crate::Manager::manage`) for usage examples. pub struct State<'r, T: Send + Sync + 'static>(&'r T); impl<'r, T: Send + Sync + 'static> State<'r, T> { /// Retrieve a borrow to the underlying value with a lifetime of `'r`. /// Using this method is typically unnecessary as `State` implements /// [`std::ops::Deref`] with a [`std::ops::Deref::Target`] of `T`. #[inline(always)] pub fn inner(&self) -> &'r T { self.0 } } impl std::ops::Deref for State<'_, T> { type Target = T; #[inline(always)] fn deref(&self) -> &T { self.0 } } impl Clone for State<'_, T> { fn clone(&self) -> Self { State(self.0) } } impl<'r, T: Send + Sync + std::fmt::Debug> std::fmt::Debug for State<'r, T> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("State").field(&self.0).finish() } } impl<'r, 'de: 'r, T: Send + Sync + 'static, R: Runtime> CommandArg<'de, R> for State<'r, T> { /// Grabs the [`State`] from the [`CommandItem`]. This will never fail. fn from_command(command: CommandItem<'de, R>) -> Result { Ok(command.message.state_ref().try_get().unwrap_or_else(|| { panic!( "state not managed for field `{}` on command `{}`. You must call `.manage()` before using this command", command.key, command.name ) })) } } /// The Tauri state manager. #[derive(Debug)] pub struct StateManager(pub(crate) TypeMap![Send + Sync]); impl StateManager { pub(crate) fn new() -> Self { Self(::new()) } pub(crate) fn set(&self, state: T) -> bool { self.0.set(state) } /// Gets the state associated with the specified type. pub fn get(&self) -> State<'_, T> { State( self .0 .try_get() .expect("state: get() called before set() for given type"), ) } /// Gets the state associated with the specified type. pub fn try_get(&self) -> Option> { self.0.try_get().map(State) } }