Skip to main content

nice_plug_iced/application/
editor_state.rs

1use std::{
2    fmt::Debug,
3    ops::{Deref, DerefMut},
4    sync::{Arc, Mutex},
5};
6
7/// A special wrapper for state that persists between editor opens.
8pub struct EditorState<State: 'static + Send> {
9    shared: Arc<Mutex<Option<State>>>,
10    owned: Option<State>,
11}
12
13impl<State: 'static + Send> EditorState<State> {
14    pub(crate) fn from_shared(shared: &Arc<Mutex<Option<State>>>) -> Self {
15        let owned = shared.lock().unwrap().take().unwrap();
16        Self {
17            shared: Arc::clone(shared),
18            owned: Some(owned),
19        }
20    }
21
22    pub(crate) fn into_shared(mut self) -> Arc<Mutex<Option<State>>> {
23        if let Some(owned) = self.owned.take() {
24            *self.shared.lock().unwrap() = Some(owned);
25        }
26
27        Arc::clone(&self.shared)
28    }
29}
30
31impl<State: 'static + Send> AsRef<State> for EditorState<State> {
32    fn as_ref(&self) -> &State {
33        // Safety: The `from_shared` constructor ensures that this is always `Some`.
34        unsafe { self.owned.as_ref().unwrap_unchecked() }
35    }
36}
37
38impl<State: 'static + Send> AsMut<State> for EditorState<State> {
39    fn as_mut(&mut self) -> &mut State {
40        // Safety: The `from_shared` constructor ensures that this is always `Some`.
41        unsafe { self.owned.as_mut().unwrap_unchecked() }
42    }
43}
44
45impl<State: 'static + Send> Deref for EditorState<State> {
46    type Target = State;
47
48    fn deref(&self) -> &Self::Target {
49        self.as_ref()
50    }
51}
52
53impl<State: 'static + Send> DerefMut for EditorState<State> {
54    fn deref_mut(&mut self) -> &mut Self::Target {
55        self.as_mut()
56    }
57}
58
59impl<State: 'static + Send> Drop for EditorState<State> {
60    fn drop(&mut self) {
61        if let Some(owned) = self.owned.take()
62            && let Ok(mut shared) = self.shared.lock()
63        {
64            *shared = Some(owned);
65        }
66    }
67}
68
69impl<State: 'static + Send + Debug> Debug for EditorState<State> {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        self.owned.as_ref().unwrap().fmt(f)
72    }
73}