From d57d5f34616f05d5de5cbe0ecd7befbe7e49d77e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Vandra-Meyer?= Date: Fri, 31 Jan 2025 09:29:21 +0100 Subject: [PATCH 1/3] add get_or_insert and get_or_insert_with for Extensions --- actix-http/src/extensions.rs | 16 ++++++++++++++++ actix-web/CHANGES.md | 1 + 2 files changed, 17 insertions(+) diff --git a/actix-http/src/extensions.rs b/actix-http/src/extensions.rs index 2ed3973bfb7..b169c464d43 100644 --- a/actix-http/src/extensions.rs +++ b/actix-http/src/extensions.rs @@ -104,6 +104,22 @@ impl Extensions { .and_then(|boxed| boxed.downcast_mut()) } + pub fn get_or_insert(&mut self, value: T) -> &mut T { + self.map + .entry(TypeId::of::()) + .or_insert(Box::new(value)) + .downcast_mut() + .expect("extensions map to always contain value T") + } + + pub fn get_or_insert_with T>(&mut self, default: F) -> &mut T { + self.map + .entry(TypeId::of::()) + .or_insert_with(|| Box::new(default())) + .downcast_mut() + .expect("extensions map to always contain value T") + } + /// Remove an item from the map of a given type. /// /// If an item of this type was already stored, it will be returned. diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index cee14dc4b7e..eeb3bd47163 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -5,6 +5,7 @@ - On Windows, an error is now returned from `HttpServer::bind()` (or TLS variants) when binding to a socket that's already in use. - Update `brotli` dependency to `7`. - Minimum supported Rust version (MSRV) is now 1.75. +- Added `Extensions::get_or_insert` and `Extensions::get_or_insert_with` ## 4.9.0 From d508164f51713e48e6f6df2bf74e84e223757335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Vandra-Meyer?= Date: Fri, 31 Jan 2025 09:40:15 +0100 Subject: [PATCH 2/3] add docs --- actix-http/src/extensions.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/actix-http/src/extensions.rs b/actix-http/src/extensions.rs index b169c464d43..ea502e72750 100644 --- a/actix-http/src/extensions.rs +++ b/actix-http/src/extensions.rs @@ -104,6 +104,17 @@ impl Extensions { .and_then(|boxed| boxed.downcast_mut()) } + /// Get a mutable reference or insert an item of a given type. + /// + /// ``` + /// # use actix_http::Extensions; + /// let mut map = Extensions::new(); + /// assert_eq!(map.get::>(), None); + /// map.get_or_insert(Vec::::new()).push(1); + /// assert_eq!(map.get::>(), Some(vec![1])); + /// map.get_or_insert(Vec::::new()).push(2); + /// assert_eq!(map.get::>(), Some(vec![1,2])); + /// ``` pub fn get_or_insert(&mut self, value: T) -> &mut T { self.map .entry(TypeId::of::()) @@ -112,6 +123,17 @@ impl Extensions { .expect("extensions map to always contain value T") } + /// Get a mutable reference or insert an item of a given type calculated with the closure given. + /// + /// ``` + /// # use actix_http::Extensions; + /// let mut map = Extensions::new(); + /// assert_eq!(map.get::>(), None); + /// map.get_or_insert_with(Vec::::new).push(1); + /// assert_eq!(map.get::>(), Some(vec![1])); + /// map.get_or_insert_with(Vec::::new).push(2); + /// assert_eq!(map.get::>(), Some(vec![1,2])); + /// ``` pub fn get_or_insert_with T>(&mut self, default: F) -> &mut T { self.map .entry(TypeId::of::()) From 015c85545f2f7fbd825f6595e036ffbee0846c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Vandra-Meyer?= Date: Fri, 31 Jan 2025 10:09:45 +0100 Subject: [PATCH 3/3] fix doctest --- actix-http/src/extensions.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/actix-http/src/extensions.rs b/actix-http/src/extensions.rs index ea502e72750..7e44492c66a 100644 --- a/actix-http/src/extensions.rs +++ b/actix-http/src/extensions.rs @@ -107,13 +107,13 @@ impl Extensions { /// Get a mutable reference or insert an item of a given type. /// /// ``` - /// # use actix_http::Extensions; + /// use actix_http::Extensions; /// let mut map = Extensions::new(); /// assert_eq!(map.get::>(), None); /// map.get_or_insert(Vec::::new()).push(1); - /// assert_eq!(map.get::>(), Some(vec![1])); + /// assert_eq!(map.get::>(), Some(&vec![1])); /// map.get_or_insert(Vec::::new()).push(2); - /// assert_eq!(map.get::>(), Some(vec![1,2])); + /// assert_eq!(map.get::>(), Some(&vec![1,2])); /// ``` pub fn get_or_insert(&mut self, value: T) -> &mut T { self.map @@ -126,13 +126,13 @@ impl Extensions { /// Get a mutable reference or insert an item of a given type calculated with the closure given. /// /// ``` - /// # use actix_http::Extensions; + /// use actix_http::Extensions; /// let mut map = Extensions::new(); /// assert_eq!(map.get::>(), None); /// map.get_or_insert_with(Vec::::new).push(1); - /// assert_eq!(map.get::>(), Some(vec![1])); + /// assert_eq!(map.get::>(), Some(&vec![1])); /// map.get_or_insert_with(Vec::::new).push(2); - /// assert_eq!(map.get::>(), Some(vec![1,2])); + /// assert_eq!(map.get::>(), Some(&vec![1,2])); /// ``` pub fn get_or_insert_with T>(&mut self, default: F) -> &mut T { self.map