1 //! Bindings for AStatsEvent NDK API. 2 use anyhow::Result; 3 use statssocket_bindgen::{ 4 AStatsEvent as AStatsEvent_raw, AStatsEvent_obtain, AStatsEvent_release, AStatsEvent_setAtomId, 5 AStatsEvent_write, AStatsEvent_writeBool, AStatsEvent_writeInt32, AStatsEvent_writeInt64, 6 AStatsEvent_writeString, 7 }; 8 use std::ptr::NonNull; 9 10 mod c_string; 11 use c_string::c_string; 12 13 /// Safe wrapper around raw `AStatsEvent`. 14 pub struct AStatsEvent { 15 event_raw: NonNull<AStatsEvent_raw>, 16 } 17 18 impl AStatsEvent { 19 /// Constructor for an `AStatsEvent` with the given `atom_id`. new(atom_id: u32) -> Self20 pub fn new(atom_id: u32) -> Self { 21 // SAFETY: trivially safe 22 let event_raw = unsafe { 23 let event = AStatsEvent_obtain(); 24 AStatsEvent_setAtomId(event, atom_id); 25 event 26 }; 27 Self { event_raw: NonNull::new(event_raw).unwrap() } 28 } 29 30 /// Writes a `bool` value to the `AStatsEvent`. write_bool(&mut self, value: bool)31 pub fn write_bool(&mut self, value: bool) { 32 // SAFETY: `&mut self` is an exclusive reference to a non-null `AStatsEvent_raw`. 33 unsafe { AStatsEvent_writeBool(self.as_ptr(), value) }; 34 } 35 36 /// Writes an `i32` value to the `AStatsEvent`. write_int32(&mut self, value: i32)37 pub fn write_int32(&mut self, value: i32) { 38 // SAFETY: `&mut self` is an exclusive reference to a non-null `AStatsEvent_raw`. 39 unsafe { AStatsEvent_writeInt32(self.as_ptr(), value) }; 40 } 41 42 /// Writes an `i64` value to the `AStatsEvent`. write_int64(&mut self, value: i64)43 pub fn write_int64(&mut self, value: i64) { 44 // SAFETY: `&mut self` is an exclusive reference to a non-null `AStatsEvent_raw`. 45 unsafe { AStatsEvent_writeInt64(self.as_ptr(), value) }; 46 } 47 48 /// Writes a `str` value to the `AStatsEvent`. write_string(&mut self, value: &str) -> Result<()>49 pub fn write_string(&mut self, value: &str) -> Result<()> { 50 let value = c_string(value)?; 51 // SAFETY: 52 // - `&mut self` is an exclusive reference to a non-null `AStatsEvent_raw`. 53 // - we've just created a valid &CStr from `value`. 54 unsafe { AStatsEvent_writeString(self.as_ptr(), value.as_ptr()) }; 55 Ok(()) 56 } 57 58 /// Write the event to statsd. write(mut self)59 pub fn write(mut self) { 60 // SAFETY: `self` is an owned reference to a non-null `AStatsEvent_raw`. 61 unsafe { AStatsEvent_write(self.as_ptr()) }; 62 } 63 as_ptr(&mut self) -> *mut AStatsEvent_raw64 fn as_ptr(&mut self) -> *mut AStatsEvent_raw { 65 self.event_raw.as_ptr() 66 } 67 } 68 69 impl Drop for AStatsEvent { drop(&mut self)70 fn drop(&mut self) { 71 // SAFETY: `&mut self` is an exclusive reference to a non-null `AStatsEvent_raw`. 72 unsafe { AStatsEvent_release(self.as_ptr()) }; 73 } 74 } 75