1+ use  std:: ops:: Deref ; 
2+ 
3+ use  once_cell:: sync:: OnceCell ; 
4+ 
15use  emacs_module:: emacs_value; 
26
37use  super :: * ; 
@@ -51,7 +55,7 @@ impl GlobalRef {
5155/// [`Env`]: struct.Env.html 
5256/// [`Value`]: struct.Value.html 
5357#[ inline]  
54-     pub  fn  within < ' e > ( & ' e  self ,  env :  & ' e  Env )  -> Value < ' e >  { 
58+     pub  fn  bind < ' e ,   ' g :   ' e > ( & ' g  self ,  env :  & ' e  Env )  -> Value < ' e >  { 
5559        unsafe  {  Value :: new ( self . raw ,  env)  } 
5660    } 
5761
@@ -75,7 +79,7 @@ impl<'e> FromLisp<'e> for GlobalRef {
7579impl < ' e >  IntoLisp < ' e >  for  & ' e  GlobalRef  { 
7680    #[ inline( always) ]  
7781    fn  into_lisp ( self ,  env :  & ' e  Env )  -> Result < Value < ' e > >  { 
78-         Ok ( self . within ( env) ) 
82+         Ok ( self . bind ( env) ) 
7983    } 
8084} 
8185
@@ -88,3 +92,42 @@ impl<'e> Value<'e> {
8892        GlobalRef :: new ( self ) 
8993    } 
9094} 
95+ 
96+ /// A [`GlobalRef`] that can be initialized once. This is useful for long-lived values that should 
97+ /// be initialized when the module is loaded, such as frequently-used symbols. 
98+ /// 
99+ /// [`GlobalRef`]: struct.GlobalRef.html 
100+ #[ derive( Debug ) ]  
101+ #[ repr( transparent) ]  
102+ pub  struct  OnceGlobalRef  { 
103+     inner :  OnceCell < GlobalRef > 
104+ } 
105+ 
106+ impl  OnceGlobalRef  { 
107+     pub ( crate )  const  fn  new ( )  -> Self  { 
108+         Self  {  inner :  OnceCell :: new ( )  } 
109+     } 
110+ 
111+     /// Initializes this global reference with the given function. 
112+ #[ doc( hidden) ]  
113+     pub  fn  init < F :  FnOnce ( & Env )  -> Result < Value > > ( & self ,  env :  & Env ,  f :  F )  -> Result < ( ) >  { 
114+         let  g = f ( env) ?. make_global_ref ( ) ; 
115+         self . inner . set ( g) . expect ( "Cannot initialize a global reference more than once" ) ; 
116+         Ok ( ( ) ) 
117+     } 
118+ 
119+     /// Points this global reference to an interned Lisp symbol with the given name. 
120+ #[ doc( hidden) ]  
121+     pub  fn  init_to_symbol ( & self ,  env :  & Env ,  name :  & str )  -> Result < ( ) >  { 
122+         self . init ( env,  |env| env. intern ( name) ) 
123+     } 
124+ } 
125+ 
126+ impl  Deref  for  OnceGlobalRef  { 
127+     type  Target  = GlobalRef ; 
128+ 
129+     #[ inline]  
130+     fn  deref ( & self )  -> & Self :: Target  { 
131+         self . inner . get ( ) . expect ( "Cannot access an uninitialized global reference" ) 
132+     } 
133+ } 
0 commit comments