From 0f9ae13c31811150d8bb7ad14127aa19c709ed49 Mon Sep 17 00:00:00 2001 From: tison Date: Thu, 9 Oct 2025 16:19:27 +0800 Subject: [PATCH] task: add `LocalKey::try_get` (#7666) Signed-off-by: tison --- tokio/src/task/task_local.rs | 10 ++++++++++ tokio/tests/task_local.rs | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/tokio/src/task/task_local.rs b/tokio/src/task/task_local.rs index cb9d22c61..d6e38f745 100644 --- a/tokio/src/task/task_local.rs +++ b/tokio/src/task/task_local.rs @@ -275,6 +275,16 @@ impl LocalKey { pub fn get(&'static self) -> T { self.with(|v| v.clone()) } + + /// Returns a copy of the task-local value + /// if the task-local value implements `Clone`. + /// + /// If the task-local with the associated key is not present, this + /// method will return an `AccessError`. For a panicking variant, + /// see `get`. + pub fn try_get(&'static self) -> Result { + self.try_with(|v| v.clone()) + } } impl fmt::Debug for LocalKey { diff --git a/tokio/tests/task_local.rs b/tokio/tests/task_local.rs index a4718dc45..be9de7241 100644 --- a/tokio/tests/task_local.rs +++ b/tokio/tests/task_local.rs @@ -145,3 +145,27 @@ async fn poll_after_take_value_should_fail() { // Poll the future after `take_value` has been called fut.await; } + +#[tokio::test] +async fn get_value() { + tokio::task_local! { + static KEY: u32 + } + + KEY.scope(1, async { + assert_eq!(KEY.get(), 1); + assert_eq!(KEY.try_get().unwrap(), 1); + }) + .await; + + let fut = KEY.scope(1, async { + let result = KEY.try_get(); + // The task local value no longer exists. + assert!(result.is_err()); + }); + let mut fut = Box::pin(fut); + fut.as_mut().take_value(); + + // Poll the future after `take_value` has been called + fut.await; +}