1#![no_std]
8
9pub struct VacantEntry<'a, T> {
11 option: &'a mut Option<T>,
12}
13
14impl<'a, T> VacantEntry<'a, T> {
15 fn new(option: &'a mut Option<T>) -> Self {
16 assert!(option.is_none());
17 Self { option }
18 }
19
20 pub fn insert(self, value: T) -> &'a mut T {
22 self.option.insert(value)
23 }
24
25 pub fn insert_entry(self, value: T) -> OccupiedEntry<'a, T> {
27 let Self { option } = self;
28 *option = Some(value);
29 OccupiedEntry::new(option)
30 }
31}
32
33pub struct OccupiedEntry<'a, T> {
35 option: &'a mut Option<T>,
36}
37
38impl<'a, T> OccupiedEntry<'a, T> {
39 fn new(option: &'a mut Option<T>) -> Self {
40 assert!(option.is_some());
41 Self { option }
42 }
43
44 pub fn get(&self) -> &T {
46 self.option.as_ref().expect("OccupiedEntry is None?")
47 }
48
49 pub fn get_mut(&mut self) -> &mut T {
55 self.option.as_mut().expect("OccupiedEntry is None?")
56 }
57
58 pub fn insert(&mut self, value: T) -> T {
63 self.option.replace(value).expect("OccupiedEntry is None?")
64 }
65
66 pub fn into_mut(self) -> &'a mut T {
72 self.option.as_mut().expect("OccupiedEntry is None?")
73 }
74
75 pub fn remove(self) -> T {
82 self.option.take().expect("OccupiedEntry is None?")
83 }
84}
85
86pub enum Entry<'a, T> {
88 Vacant(VacantEntry<'a, T>),
90 Occupied(OccupiedEntry<'a, T>),
92}
93
94impl<'a, T> Entry<'a, T> {
95 fn into_option_mut(self) -> &'a mut Option<T> {
96 match self {
97 Entry::Vacant(VacantEntry { option }) => option,
98 Entry::Occupied(OccupiedEntry { option }) => option,
99 }
100 }
101
102 pub fn and_modify(self, f: impl FnOnce(&mut T)) -> Self {
104 let option = self.into_option_mut();
105 if let Some(value) = option {
106 f(value);
107 }
108 option.entry()
109 }
110
111 pub fn insert_entry(self, value: T) -> OccupiedEntry<'a, T> {
113 match self {
114 Entry::Occupied(mut entry) => {
115 entry.insert(value);
116 entry
117 }
118 Entry::Vacant(entry) => entry.insert_entry(value),
119 }
120 }
121
122 pub fn or_default(self) -> &'a mut T
125 where
126 T: Default,
127 {
128 self.into_option_mut().get_or_insert_default()
129 }
130
131 pub fn or_insert(self, default: T) -> &'a mut T {
134 match self {
135 Entry::Occupied(entry) => entry.into_mut(),
136 Entry::Vacant(entry) => entry.insert(default),
137 }
138 }
139
140 pub fn or_insert_with(self, default: impl FnOnce() -> T) -> &'a mut T {
143 match self {
144 Entry::Occupied(entry) => entry.into_mut(),
145 Entry::Vacant(entry) => entry.insert(default()),
146 }
147 }
148}
149
150mod private {
151 pub trait Sealed {}
152}
153
154pub trait OptionEntry: private::Sealed {
156 type T;
158 fn entry(&mut self) -> Entry<'_, Self::T>;
160}
161
162impl<T> private::Sealed for Option<T> {}
163
164impl<T> OptionEntry for Option<T> {
165 type T = T;
166
167 fn entry(&mut self) -> Entry<'_, Self::T> {
168 if self.is_none() {
169 Entry::Vacant(VacantEntry::new(self))
170 } else {
171 Entry::Occupied(OccupiedEntry::new(self))
172 }
173 }
174}