@@ -324,10 +324,11 @@ impl Context {
324324 /// assert_eq!(Context::current().get::<ValueA>(), None);
325325 /// ```
326326 pub fn attach ( self ) -> ContextGuard {
327- let cx_id = CURRENT_CONTEXT . with ( |cx| cx. borrow_mut ( ) . push ( self ) ) ;
327+ let cx_id = CURRENT_CONTEXT . with ( |cx| cx. borrow_mut ( ) . push ( self . clone ( ) ) ) ;
328328
329329 ContextGuard {
330330 cx_pos : cx_id,
331+ context : self ,
331332 _marker : PhantomData ,
332333 }
333334 }
@@ -456,10 +457,19 @@ impl fmt::Debug for Context {
456457pub struct ContextGuard {
457458 // The position of the context in the stack. This is used to pop the context.
458459 cx_pos : u16 ,
460+ // The current context.
461+ context : Context ,
459462 // Ensure this type is !Send as it relies on thread locals
460463 _marker : PhantomData < * const ( ) > ,
461464}
462465
466+ impl ContextGuard {
467+ /// Retrieve the Context
468+ pub fn context ( & self ) -> & Context {
469+ & self . context
470+ }
471+ }
472+
463473impl Drop for ContextGuard {
464474 fn drop ( & mut self ) {
465475 let id = self . cx_pos ;
@@ -997,6 +1007,33 @@ mod tests {
9971007 assert ! ( suppressed. is_telemetry_suppressed( ) ) ;
9981008 }
9991009
1010+ #[ test]
1011+ fn test_retrieve_context_from_guard ( ) {
1012+ let outer_guard = Context :: new ( )
1013+ . with_value ( ValueA ( 1 ) )
1014+ . with_value ( ValueB ( 2 ) )
1015+ . attach ( ) ;
1016+
1017+ assert_eq ! ( outer_guard. context( ) . get:: <ValueA >( ) , Some ( & ValueA ( 1 ) ) ) ;
1018+ assert_eq ! ( outer_guard. context( ) . get:: <ValueB >( ) , Some ( & ValueB ( 2 ) ) ) ;
1019+
1020+ {
1021+ let inner_guard = Context :: current_with_value ( ValueB ( 42 ) ) . attach ( ) ;
1022+ // ValueB is changed in inner guard's context
1023+ assert_eq ! ( inner_guard. context( ) . get( ) , Some ( & ValueA ( 1 ) ) ) ;
1024+ assert_eq ! ( inner_guard. context( ) . get( ) , Some ( & ValueB ( 42 ) ) ) ;
1025+
1026+ assert ! ( Context :: map_current( |cx| {
1027+ assert_eq!( cx. get( ) , Some ( & ValueA ( 1 ) ) ) ;
1028+ assert_eq!( cx. get( ) , Some ( & ValueB ( 42 ) ) ) ;
1029+ true
1030+ } ) ) ;
1031+
1032+ // Outer guard's context still has original ValueB
1033+ assert_eq ! ( outer_guard. context( ) . get:: <ValueB >( ) , Some ( & ValueB ( 2 ) ) ) ;
1034+ }
1035+ }
1036+
10001037 #[ test]
10011038 fn test_with_telemetry_suppressed ( ) {
10021039 // Start with a normal context
0 commit comments