wasefire_sync/
take.rs

1// Copyright 2023 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::Mutex;
16
17/// Convenient wrapper around `Mutex<Option<T>>`.
18pub struct TakeCell<T>(Mutex<Option<T>>);
19
20impl<T> TakeCell<T> {
21    /// Creates a new mutex-protected option.
22    pub const fn new(init: Option<T>) -> Self {
23        TakeCell(Mutex::new(init))
24    }
25
26    /// Takes the content of the option.
27    ///
28    /// # Panics
29    ///
30    /// Panics if the mutex is locked or the option is empty.
31    #[track_caller]
32    pub fn take(&self) -> T {
33        self.get().unwrap()
34    }
35
36    /// Takes the (possibly empty) content of the option.
37    ///
38    /// # Panics
39    ///
40    /// Panics if the mutex is locked.
41    #[track_caller]
42    pub fn get(&self) -> Option<T> {
43        self.0.lock().take()
44    }
45
46    /// Replaces the content of the option.
47    ///
48    /// # Panics
49    ///
50    /// Panics if the mutex is locked.
51    #[track_caller]
52    pub fn replace(&self, value: T) -> Option<T> {
53        self.0.lock().replace(value)
54    }
55
56    /// Sets the content of the option.
57    ///
58    /// # Panics
59    ///
60    /// Panics if the mutex is locked or the option is not empty.
61    #[track_caller]
62    pub fn put(&self, value: T) {
63        assert!(self.replace(value).is_none())
64    }
65
66    /// Executes a closure on the content of the option.
67    ///
68    /// # Panics
69    ///
70    /// Panics if the mutex is locked or the option is empty.
71    #[track_caller]
72    pub fn with<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
73        f(self.0.lock().as_mut().unwrap())
74    }
75}