@@ -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