1- use std:: { any:: Any , ptr:: NonNull } ;
1+ use std:: { any:: Any , ops :: Deref , path :: Path , ptr:: NonNull } ;
22
33use rkyv:: {
44 de:: { ErasedPtr , Pooling , PoolingState } ,
@@ -10,13 +10,31 @@ use crate::error::{Error, Result};
1010const CONTEXT_ADDR : usize = 0 ;
1111unsafe fn default_drop ( _: ErasedPtr ) { }
1212
13+ pub trait CacheableContext : Any {
14+ fn project_root ( & self ) -> Option < & Path > ;
15+ }
16+
17+ // Implement for unit type for convenience in tests and simple cases
18+ impl CacheableContext for ( ) {
19+ fn project_root ( & self ) -> Option < & Path > {
20+ None
21+ }
22+ }
23+
1324/// A context wrapper that provides shared context methods
1425pub struct ContextGuard < ' a > {
15- context : & ' a dyn Any ,
26+ context : & ' a dyn CacheableContext ,
27+ }
28+
29+ impl < ' a > Deref for ContextGuard < ' a > {
30+ type Target = dyn CacheableContext ;
31+ fn deref ( & self ) -> & Self :: Target {
32+ self . context
33+ }
1634}
1735
1836impl < ' a > ContextGuard < ' a > {
19- pub fn new ( context : & ' a dyn Any ) -> Self {
37+ pub fn new ( context : & ' a dyn CacheableContext ) -> Self {
2038 Self { context }
2139 }
2240
@@ -25,11 +43,11 @@ impl<'a> ContextGuard<'a> {
2543 sharing. finish_sharing ( CONTEXT_ADDR , self as * const _ as usize )
2644 }
2745
28- pub fn sharing_context < S : Sharing < Error > + ?Sized > ( sharing : & ' a mut S ) -> Result < & ' a dyn Any > {
46+ pub fn sharing_guard < S : Sharing < Error > + ?Sized > ( sharing : & ' a mut S ) -> Result < & ' a Self > {
2947 match sharing. start_sharing ( CONTEXT_ADDR ) {
3048 SharingState :: Finished ( addr) => {
3149 let guard: & Self = unsafe { & * ( addr as * const Self ) } ;
32- Ok ( guard. context )
50+ Ok ( guard)
3351 }
3452 _ => Err ( Error :: NoContext ) ,
3553 }
@@ -43,13 +61,19 @@ impl<'a> ContextGuard<'a> {
4361 }
4462 }
4563
46- pub fn pooling_context < P : Pooling < Error > + ?Sized > ( pooling : & ' a mut P ) -> Result < & ' a dyn Any > {
64+ pub fn pooling_guard < P : Pooling < Error > + ?Sized > ( pooling : & ' a mut P ) -> Result < & ' a Self > {
4765 match pooling. start_pooling ( CONTEXT_ADDR ) {
4866 PoolingState :: Finished ( ptr) => {
4967 let guard: & Self = unsafe { & * ( ptr. data_address ( ) as * const Self ) } ;
50- Ok ( guard. context )
68+ Ok ( guard)
5169 }
5270 _ => Err ( Error :: NoContext ) ,
5371 }
5472 }
73+
74+ pub fn downcast_context < T : ' static > ( & ' a self ) -> Result < & ' a T > {
75+ ( self . context as & dyn Any )
76+ . downcast_ref ( )
77+ . ok_or ( Error :: NoContext )
78+ }
5579}
0 commit comments