1pub struct VacantEntry<'a, T> {
9 option: &'a mut Option<T>,
10}
11
12impl<'a, T> VacantEntry<'a, T> {
13 fn new(option: &'a mut Option<T>) -> Self {
14 assert!(option.is_none());
15 Self { option }
16 }
17
18 pub fn insert(self, value: T) -> &'a mut T {
20 self.option.insert(value)
21 }
22
23 pub fn insert_entry(self, value: T) -> OccupiedEntry<'a, T> {
25 let Self { option } = self;
26 *option = Some(value);
27 OccupiedEntry::new(option)
28 }
29}
30
31pub struct OccupiedEntry<'a, T> {
33 option: &'a mut Option<T>,
34}
35
36impl<'a, T> OccupiedEntry<'a, T> {
37 fn new(option: &'a mut Option<T>) -> Self {
38 assert!(option.is_some());
39 Self { option }
40 }
41
42 pub fn get(&self) -> &T {
44 self.option.as_ref().expect("OccupiedEntry is None?")
45 }
46
47 pub fn get_mut(&mut self) -> &mut T {
53 self.option.as_mut().expect("OccupiedEntry is None?")
54 }
55
56 pub fn insert(&mut self, value: T) -> T {
58 self.option.replace(value).expect("OccupiedEntry is None?")
59 }
60
61 pub fn into_mut(self) -> &'a mut T {
62 self.option.as_mut().expect("OccupiedEntry is None?")
63 }
64
65 pub fn remove(self) -> T {
72 self.option.take().expect("OccupiedEntry is None?")
73 }
74}
75
76pub enum Entry<'a, T> {
78 Vacant(VacantEntry<'a, T>),
80 Occupied(OccupiedEntry<'a, T>),
82}
83
84impl<'a, T> Entry<'a, T> {
85 fn into_option_mut(self) -> &'a mut Option<T> {
86 match self {
87 Entry::Vacant(VacantEntry { option }) => option,
88 Entry::Occupied(OccupiedEntry { option }) => option,
89 }
90 }
91
92 pub fn and_modify(self, f: impl FnOnce(&mut T)) -> Self {
94 let option = self.into_option_mut();
95 if let Some(value) = option {
96 f(value);
97 }
98 option.entry()
99 }
100
101 pub fn insert_entry(self, value: T) -> OccupiedEntry<'a, T> {
103 match self {
104 Entry::Occupied(mut entry) => {
105 entry.insert(value);
106 entry
107 }
108 Entry::Vacant(entry) => entry.insert_entry(value),
109 }
110 }
111
112 pub fn or_default(self) -> &'a mut T
115 where
116 T: Default,
117 {
118 self.into_option_mut().get_or_insert_default()
119 }
120
121 pub fn or_insert(self, default: T) -> &'a mut T {
124 match self {
125 Entry::Occupied(entry) => entry.into_mut(),
126 Entry::Vacant(entry) => entry.insert(default),
127 }
128 }
129
130 pub fn or_insert_with(self, default: impl FnOnce() -> T) -> &'a mut T {
133 match self {
134 Entry::Occupied(entry) => entry.into_mut(),
135 Entry::Vacant(entry) => entry.insert(default()),
136 }
137 }
138}
139
140mod private {
141 pub trait Sealed {}
142}
143
144pub trait OptionEntry: private::Sealed {
146 type T;
147 fn entry(&mut self) -> Entry<'_, Self::T>;
149}
150
151impl<T> private::Sealed for Option<T> {}
152
153impl<T> OptionEntry for Option<T> {
154 type T = T;
155
156 fn entry(&mut self) -> Entry<'_, Self::T> {
157 if self.is_none() {
158 Entry::Vacant(VacantEntry::new(self))
159 } else {
160 Entry::Occupied(OccupiedEntry::new(self))
161 }
162 }
163}