Skip to content

Commit eff3e3a

Browse files
authored
Add get_or_insert methods to Extensions (#656)
1 parent 0d1f772 commit eff3e3a

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

src/extensions.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,62 @@ impl Extensions {
104104
.and_then(|boxed| (&mut **boxed).as_any_mut().downcast_mut())
105105
}
106106

107+
/// Get a mutable reference to a type, inserting `value` if not already present on this
108+
/// `Extensions`.
109+
///
110+
/// # Example
111+
///
112+
/// ```
113+
/// # use http::Extensions;
114+
/// let mut ext = Extensions::new();
115+
/// *ext.get_or_insert(1i32) += 2;
116+
///
117+
/// assert_eq!(*ext.get::<i32>().unwrap(), 3);
118+
/// ```
119+
pub fn get_or_insert<T: Clone + Send + Sync + 'static>(&mut self, value: T) -> &mut T {
120+
self.get_or_insert_with(|| value)
121+
}
122+
123+
/// Get a mutable reference to a type, inserting the value created by `f` if not already present
124+
/// on this `Extensions`.
125+
///
126+
/// # Example
127+
///
128+
/// ```
129+
/// # use http::Extensions;
130+
/// let mut ext = Extensions::new();
131+
/// *ext.get_or_insert_with(|| 1i32) += 2;
132+
///
133+
/// assert_eq!(*ext.get::<i32>().unwrap(), 3);
134+
/// ```
135+
pub fn get_or_insert_with<T: Clone + Send + Sync + 'static, F: FnOnce() -> T>(
136+
&mut self,
137+
f: F,
138+
) -> &mut T {
139+
let out = self
140+
.map
141+
.get_or_insert_with(|| Box::new(HashMap::default()))
142+
.entry(TypeId::of::<T>())
143+
.or_insert_with(|| Box::new(f()));
144+
(&mut **out).as_any_mut().downcast_mut().unwrap()
145+
}
146+
147+
/// Get a mutable reference to a type, inserting the type's default value if not already present
148+
/// on this `Extensions`.
149+
///
150+
/// # Example
151+
///
152+
/// ```
153+
/// # use http::Extensions;
154+
/// let mut ext = Extensions::new();
155+
/// *ext.get_or_insert_default::<i32>() += 2;
156+
///
157+
/// assert_eq!(*ext.get::<i32>().unwrap(), 2);
158+
/// ```
159+
pub fn get_or_insert_default<T: Default + Clone + Send + Sync + 'static>(&mut self) -> &mut T {
160+
self.get_or_insert_with(T::default)
161+
}
162+
107163
/// Remove a type from this `Extensions`.
108164
///
109165
/// If a extension of this type existed, it will be returned.

0 commit comments

Comments
 (0)