1- use std:: ffi:: CString ;
2- use std:: ptr:: NonNull ;
1+ use std:: ffi:: { CStr , CString } ;
2+ use std:: ptr:: { self , NonNull } ;
33
44use crate :: Context ;
55use crate :: { raw, ValkeyString } ;
@@ -16,6 +16,27 @@ impl Drop for ServerInfo {
1616}
1717
1818impl ServerInfo {
19+ /// Creates a new `ServerInfo` without requiring a context.
20+ ///
21+ /// The underlying Module API permits a NULL context for both
22+ /// `GetServerInfo` and `FreeServerInfo`.
23+ #[ must_use]
24+ pub fn new ( section : & str ) -> Self {
25+ let section = CString :: new ( section) . unwrap ( ) ;
26+ let inner = unsafe {
27+ raw:: RedisModule_GetServerInfo . unwrap ( ) ( ptr:: null_mut ( ) , section. as_ptr ( ) )
28+ } ;
29+ Self {
30+ ctx : ptr:: null_mut ( ) ,
31+ inner,
32+ }
33+ }
34+
35+ /// Returns a field value as a `ValkeyString`.
36+ ///
37+ /// This works both with and without a context. When no context is
38+ /// available, the returned `ValkeyString` will not be registered with the
39+ /// auto memory mechanism, but Rust's `Drop` ensures proper cleanup.
1940 pub fn field ( & self , field : & str ) -> Option < ValkeyString > {
2041 let field = CString :: new ( field) . unwrap ( ) ;
2142 let value = unsafe {
@@ -27,6 +48,76 @@ impl ServerInfo {
2748 Some ( ValkeyString :: new ( NonNull :: new ( self . ctx ) , value) )
2849 }
2950 }
51+
52+ /// Returns a field value as a `&str`. Does not require a context.
53+ ///
54+ /// The returned string borrows from the `ServerInfo` data and is valid
55+ /// for the lifetime of this `ServerInfo`.
56+ pub fn field_c ( & self , field : & str ) -> Option < & str > {
57+ let field = CString :: new ( field) . unwrap ( ) ;
58+ let value = unsafe {
59+ raw:: RedisModule_ServerInfoGetFieldC . unwrap ( ) ( self . inner , field. as_ptr ( ) )
60+ } ;
61+ if value. is_null ( ) {
62+ None
63+ } else {
64+ unsafe { CStr :: from_ptr ( value) } . to_str ( ) . ok ( )
65+ }
66+ }
67+
68+ /// Returns a field value as a signed integer. Does not require a context.
69+ pub fn field_signed ( & self , field : & str ) -> Option < i64 > {
70+ let field = CString :: new ( field) . unwrap ( ) ;
71+ let mut err: std:: os:: raw:: c_int = 0 ;
72+ let value = unsafe {
73+ raw:: RedisModule_ServerInfoGetFieldSigned . unwrap ( ) (
74+ self . inner ,
75+ field. as_ptr ( ) ,
76+ & mut err,
77+ )
78+ } ;
79+ if err != 0 {
80+ None
81+ } else {
82+ Some ( value)
83+ }
84+ }
85+
86+ /// Returns a field value as an unsigned integer. Does not require a context.
87+ pub fn field_unsigned ( & self , field : & str ) -> Option < u64 > {
88+ let field = CString :: new ( field) . unwrap ( ) ;
89+ let mut err: std:: os:: raw:: c_int = 0 ;
90+ let value = unsafe {
91+ raw:: RedisModule_ServerInfoGetFieldUnsigned . unwrap ( ) (
92+ self . inner ,
93+ field. as_ptr ( ) ,
94+ & mut err,
95+ )
96+ } ;
97+ if err != 0 {
98+ None
99+ } else {
100+ Some ( value)
101+ }
102+ }
103+
104+ /// Returns a field value as a double. Does not require a context.
105+ pub fn field_double ( & self , field : & str ) -> Option < f64 > {
106+ let field = CString :: new ( field) . unwrap ( ) ;
107+ let mut err: std:: os:: raw:: c_int = 0 ;
108+ let value = unsafe {
109+ raw:: RedisModule_ServerInfoGetFieldDouble . unwrap ( ) (
110+ self . inner ,
111+ field. as_ptr ( ) ,
112+ & mut err,
113+ )
114+ } ;
115+ if err != 0 {
116+ None
117+ } else {
118+ Some ( value)
119+ }
120+ }
30121}
31122
32123impl Context {
0 commit comments