state.rs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. use crate::{
  5. ipc::{CommandArg, CommandItem, InvokeError},
  6. Runtime,
  7. };
  8. use state::TypeMap;
  9. /// A guard for a state value.
  10. ///
  11. /// See [`Manager::manage`](`crate::Manager::manage`) for usage examples.
  12. pub struct State<'r, T: Send + Sync + 'static>(&'r T);
  13. impl<'r, T: Send + Sync + 'static> State<'r, T> {
  14. /// Retrieve a borrow to the underlying value with a lifetime of `'r`.
  15. /// Using this method is typically unnecessary as `State` implements
  16. /// [`std::ops::Deref`] with a [`std::ops::Deref::Target`] of `T`.
  17. #[inline(always)]
  18. pub fn inner(&self) -> &'r T {
  19. self.0
  20. }
  21. }
  22. impl<T: Send + Sync + 'static> std::ops::Deref for State<'_, T> {
  23. type Target = T;
  24. #[inline(always)]
  25. fn deref(&self) -> &T {
  26. self.0
  27. }
  28. }
  29. impl<T: Send + Sync + 'static> Clone for State<'_, T> {
  30. fn clone(&self) -> Self {
  31. State(self.0)
  32. }
  33. }
  34. impl<'r, T: Send + Sync + std::fmt::Debug> std::fmt::Debug for State<'r, T> {
  35. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  36. f.debug_tuple("State").field(&self.0).finish()
  37. }
  38. }
  39. impl<'r, 'de: 'r, T: Send + Sync + 'static, R: Runtime> CommandArg<'de, R> for State<'r, T> {
  40. /// Grabs the [`State`] from the [`CommandItem`]. This will never fail.
  41. fn from_command(command: CommandItem<'de, R>) -> Result<Self, InvokeError> {
  42. Ok(command.message.state_ref().try_get().unwrap_or_else(|| {
  43. panic!(
  44. "state not managed for field `{}` on command `{}`. You must call `.manage()` before using this command",
  45. command.key, command.name
  46. )
  47. }))
  48. }
  49. }
  50. /// The Tauri state manager.
  51. #[derive(Debug)]
  52. pub struct StateManager(pub(crate) TypeMap![Send + Sync]);
  53. impl StateManager {
  54. pub(crate) fn new() -> Self {
  55. Self(<TypeMap![Send + Sync]>::new())
  56. }
  57. pub(crate) fn set<T: Send + Sync + 'static>(&self, state: T) -> bool {
  58. self.0.set(state)
  59. }
  60. /// Gets the state associated with the specified type.
  61. pub fn get<T: Send + Sync + 'static>(&self) -> State<'_, T> {
  62. State(
  63. self
  64. .0
  65. .try_get()
  66. .expect("state: get() called before set() for given type"),
  67. )
  68. }
  69. /// Gets the state associated with the specified type.
  70. pub fn try_get<T: Send + Sync + 'static>(&self) -> Option<State<'_, T>> {
  71. self.0.try_get().map(State)
  72. }
  73. }