@@ -20,30 +20,49 @@ impl MiMalloc {
2020 ffi:: mi_usable_size ( ptr as * const c_void )
2121 }
2222
23- /// Call the given function with a string version of the JSON stats for the whole process
23+ /// Extract a string containing the JSON statistics for the whole process
2424 ///
2525 /// Allocates (using mimalloc itself) to store the JSON structure.
2626 #[ cfg( not( feature = "v2" ) ) ]
27- pub fn with_stats_json < F , O > ( f : F ) -> Result < O , & ' static str >
28- where
29- F : FnOnce ( & str ) -> O ,
30- {
27+ pub fn stats_json ( ) -> Result < StatsJson , & ' static str > {
3128 unsafe {
3229 let buf = ffi:: mi_stats_get_json ( 0 , core:: ptr:: null :: < c_char > ( ) as * mut _ ) ;
33- if buf. is_null ( ) {
34- return Err ( "failed to call mi_stats_get_json" ) ;
30+ if let Some ( inner) = core:: ptr:: NonNull :: new ( buf) {
31+ Ok ( StatsJson { inner } )
32+ } else {
33+ Err ( "failed to call mi_stats_get_json" )
3534 }
36- let cstr = CStr :: from_ptr ( buf) ;
37- let slice = cstr
38- . to_str ( )
39- . map_err ( |_| "mi_stats_get_json contained invalid UTF-8" ) ?;
40- let o = f ( slice) ;
41- ffi:: mi_free ( buf as _ ) ;
42- Ok ( o)
4335 }
4436 }
4537}
4638
39+ #[ cfg( not( feature = "v2" ) ) ]
40+ /// Wrapper around the output of `MiMalloc::stats_json()`
41+ ///
42+ /// Derefs to a CStr
43+ pub struct StatsJson {
44+ inner : core:: ptr:: NonNull < c_char > ,
45+ }
46+
47+ #[ cfg( not( feature = "v2" ) ) ]
48+ impl core:: ops:: Deref for StatsJson {
49+ type Target = CStr ;
50+
51+ fn deref ( & self ) -> & Self :: Target {
52+ unsafe {
53+ let cstr = CStr :: from_ptr ( self . inner . as_ptr ( ) ) ;
54+ & cstr
55+ }
56+ }
57+ }
58+
59+ #[ cfg( not( feature = "v2" ) ) ]
60+ impl Drop for StatsJson {
61+ fn drop ( & mut self ) {
62+ unsafe { ffi:: mi_free ( self . inner . as_ptr ( ) as _ ) }
63+ }
64+ }
65+
4766#[ cfg( test) ]
4867mod test {
4968 use super :: * ;
@@ -71,9 +90,10 @@ mod test {
7190
7291 #[ test]
7392 #[ cfg( not( feature = "v2" ) ) ]
74- fn test_with_stats_json ( ) {
75- let ( first_char, len) = MiMalloc :: with_stats_json ( |f| ( f. chars ( ) . next ( ) , f. len ( ) ) ) . unwrap ( ) ;
76- assert_eq ! ( first_char, Some ( '{' ) ) ;
77- assert ! ( len > 1 ) ;
93+ fn test_stats_json ( ) {
94+ let stats = MiMalloc :: stats_json ( ) . expect ( "should get stats" ) ;
95+ let slice = stats. to_str ( ) . expect ( "should be valid UTF-8" ) ;
96+ assert_eq ! ( slice. chars( ) . next( ) , Some ( '{' ) ) ;
97+ assert ! ( stats. count_bytes( ) > 1 ) ;
7898 }
7999}
0 commit comments