1use core::fmt::Debug;
2use core::mem;
3
4#[derive(Clone, Debug)]
6pub enum Cached<T: Clone + Debug> {
7 Empty,
8 Unused(T),
9 Used(T),
10}
11
12impl<T: Clone + Debug> Cached<T> {
13 pub const fn get(&self) -> Option<&T> {
15 match self {
16 Self::Empty | Self::Unused(_) => None,
17 Self::Used(t) => Some(t),
18 }
19 }
20
21 pub fn get_mut(&mut self) -> Option<&mut T> {
23 match self {
24 Self::Empty | Self::Unused(_) => None,
25 Self::Used(t) => Some(t),
26 }
27 }
28
29 pub const fn is_unused(&self) -> bool {
31 match self {
32 Self::Empty | Self::Unused(_) => true,
33 Self::Used(_) => false,
34 }
35 }
36
37 pub const fn is_used(&self) -> bool {
39 match self {
40 Self::Empty | Self::Unused(_) => false,
41 Self::Used(_) => true,
42 }
43 }
44
45 pub const fn is_invalidated(&self) -> bool {
47 matches!(self, Self::Unused(_))
48 }
49
50 pub fn take_unused(&mut self) -> Option<T> {
52 if matches!(*self, Self::Unused(_)) {
53 let Self::Unused(val) = mem::replace(self, Self::Empty) else {
54 unreachable!()
55 };
56 Some(val)
57 } else {
58 None
59 }
60 }
61
62 pub fn take_used(&mut self) -> Option<T> {
64 if matches!(*self, Self::Used(_)) {
65 let Self::Used(val) = mem::replace(self, Self::Empty) else {
66 unreachable!()
67 };
68 Some(val)
69 } else {
70 None
71 }
72 }
73
74 #[allow(clippy::missing_panics_doc)]
76 pub fn set_unused(&mut self) {
77 if matches!(*self, Self::Used(_)) {
78 *self = Self::Unused(self.take_used().expect("cached value should be used"));
79 }
80 }
81
82 pub fn set_used(&mut self, val: T) {
84 *self = Self::Used(val);
85 }
86}