@@ -2,12 +2,20 @@ use core::ptr::NonNull;
22
33use crate :: ffi:: { ngx_core_conf_t, ngx_module_t} ;
44
5- /// Utility trait for types containing core module main configuration.
5+ /// Raw access to core module main configuration slots.
6+ ///
7+ /// This trait is implemented for NGINX-owned types such as `ngx_cycle_t` and `ngx_conf_t`
8+ /// that carry configuration context pointers. It exposes the low-level lookup step that
9+ /// retrieves a module's main configuration as an untyped pointer.
10+ ///
11+ /// Most callers should not use this trait directly. Prefer `CoreModuleMainConf` to obtain a
12+ /// typed reference for a specific core module.
613pub trait CoreModuleConfExt {
7- /// Get a non-null reference to the main configuration structure for a core module.
14+ /// Get a non-null pointer to a core module's main configuration .
815 ///
916 /// # Safety
1017 /// Caller must ensure that type `T` matches the configuration type for the specified module.
18+ /// Supplying the wrong type will produce an invalid typed pointer.
1119 #[ inline]
1220 unsafe fn core_main_conf_unchecked < T > ( & self , _module : & ngx_module_t ) -> Option < NonNull < T > > {
1321 None
@@ -30,45 +38,54 @@ impl CoreModuleConfExt for crate::ffi::ngx_conf_t {
3038 }
3139}
3240
33- /// Get a typed reference to the main configuration structure for a core module.
34- pub fn core_main_conf < T > ( o : & impl CoreModuleConfExt , module : & ngx_module_t ) -> Option < & ' static T > {
35- unsafe { Some ( o. core_main_conf_unchecked ( module) ?. as_ref ( ) ) }
36- }
41+ /// Typed access to a core module's main configuration.
42+ ///
43+ /// Implement this trait for a concrete core-style module to associate it with its main
44+ /// configuration type and global `ngx_module_t`. The provided default methods build on top of
45+ /// `CoreModuleConfExt` to turn the raw configuration slot lookup into typed references.
46+ ///
47+ /// # Safety
48+ /// Caller must ensure that type `CoreModuleMainConf::MainConf` matches the configuration type
49+ /// for the specified module.
50+ pub unsafe trait CoreModuleMainConf {
51+ /// Concrete type of this module's main configuration.
52+ type MainConf ;
53+
54+ /// Returns the global `ngx_module_t` describing this module.
55+ fn module ( ) -> & ' static ngx_module_t ;
56+
57+ /// Get a typed shared reference to this module's main configuration.
58+ fn main_conf ( o : & impl CoreModuleConfExt ) -> Option < & ' static Self :: MainConf > {
59+ unsafe { Some ( o. core_main_conf_unchecked ( Self :: module ( ) ) ?. as_ref ( ) ) }
60+ }
3761
38- /// Get a typed mutable reference to the main configuration structure for a core module.
39- pub fn core_main_conf_mut < T > (
40- o : & impl CoreModuleConfExt ,
41- module : & ngx_module_t ,
42- ) -> Option < & ' static mut T > {
43- unsafe { Some ( o. core_main_conf_unchecked ( module) ?. as_mut ( ) ) }
62+ /// Get a typed mutable reference to this module's main configuration.
63+ fn main_conf_mut ( o : & impl CoreModuleConfExt ) -> Option < & ' static mut Self :: MainConf > {
64+ unsafe { Some ( o. core_main_conf_unchecked ( Self :: module ( ) ) ?. as_mut ( ) ) }
65+ }
4466}
4567
4668/// Auxiliary structure to access `ngx_core_module` configuration.
4769pub struct NgxCoreModule ;
4870
49- impl NgxCoreModule {
50- /// Returns a reference to the global `ngx_core_module`.
51- pub fn module ( ) -> & ' static ngx_module_t {
52- unsafe { & * core:: ptr:: addr_of!( nginx_sys:: ngx_core_module) }
53- }
54-
55- /// Get a typed reference to `ngx_core_module` main configuration.
56- pub fn main_conf ( o : & impl CoreModuleConfExt ) -> Option < & ' static ngx_core_conf_t > {
57- core_main_conf ( o, Self :: module ( ) )
58- }
71+ unsafe impl CoreModuleMainConf for NgxCoreModule {
72+ type MainConf = ngx_core_conf_t ;
5973
60- /// Get a typed mutable reference to `ngx_core_module` main configuration.
61- pub fn main_conf_mut ( o : & impl CoreModuleConfExt ) -> Option < & ' static mut ngx_core_conf_t > {
62- core_main_conf_mut ( o, Self :: module ( ) )
74+ fn module ( ) -> & ' static ngx_module_t {
75+ unsafe { & * core:: ptr:: addr_of!( nginx_sys:: ngx_core_module) }
6376 }
6477}
6578
6679#[ cfg( test) ]
6780mod tests {
81+ extern crate alloc;
82+ extern crate std;
83+
84+ use alloc:: boxed:: Box ;
6885 use core:: ffi:: c_void;
6986 use core:: mem:: MaybeUninit ;
7087
71- use super :: { CoreModuleConfExt , core_main_conf , core_main_conf_mut } ;
88+ use super :: { CoreModuleConfExt , CoreModuleMainConf } ;
7289 use crate :: ffi:: { ngx_conf_t, ngx_cycle_t, ngx_module_t} ;
7390
7491 type CoreConfSlot = * mut * mut * mut c_void ;
@@ -109,14 +126,44 @@ mod tests {
109126
110127 let module = module_with_index ( 0 ) ;
111128
112- let got = core_main_conf :: < u32 > ( & conf , & module) . copied ( ) ;
129+ let got = unsafe { conf . core_main_conf_unchecked :: < u32 > ( & module) . map ( |v| * v . as_ref ( ) ) } ;
113130 assert_eq ! ( got, Some ( 42 ) ) ;
114131
115- let got_mut = core_main_conf_mut :: < u32 > ( & conf, & module) ;
132+ let got_mut =
133+ unsafe { conf. core_main_conf_unchecked :: < u32 > ( & module) . map ( |mut v| v. as_mut ( ) ) } ;
116134 assert ! ( got_mut. is_some( ) ) ;
117135 if let Some ( v) = got_mut {
118136 * v = 99 ;
119137 }
120138 assert_eq ! ( value, 99 ) ;
121139 }
140+
141+ struct TestCoreModule ;
142+
143+ unsafe impl CoreModuleMainConf for TestCoreModule {
144+ type MainConf = u32 ;
145+
146+ fn module ( ) -> & ' static ngx_module_t {
147+ Box :: leak ( Box :: new ( module_with_index ( 0 ) ) )
148+ }
149+ }
150+
151+ #[ test]
152+ fn main_conf_trait_accessors_return_typed_references ( ) {
153+ let mut value: u32 = 42 ;
154+ let mut slots: [ CoreConfSlot ; 1 ] = [ ( & raw mut value) . cast ( ) ] ;
155+
156+ let mut cycle: ngx_cycle_t = unsafe { MaybeUninit :: zeroed ( ) . assume_init ( ) } ;
157+ cycle. conf_ctx = slots. as_mut_ptr ( ) ;
158+
159+ let mut conf: ngx_conf_t = unsafe { MaybeUninit :: zeroed ( ) . assume_init ( ) } ;
160+ conf. cycle = & raw mut cycle;
161+
162+ assert_eq ! ( TestCoreModule :: main_conf( & conf) . copied( ) , Some ( 42 ) ) ;
163+
164+ if let Some ( v) = TestCoreModule :: main_conf_mut ( & conf) {
165+ * v = 99 ;
166+ }
167+ assert_eq ! ( value, 99 ) ;
168+ }
122169}
0 commit comments