use crate::*;
use log::trace;
use runng_sys::*;
use std::{convert::TryFrom, convert::TryInto, ffi::CStr, marker, result};
pub trait NngStat {
unsafe fn nng_stat(&self) -> *mut nng_stat;
fn child(&self) -> Option<NngStatChild> {
unsafe {
let node = nng_stat_child(self.nng_stat());
NngStatChild::new(node)
}
}
}
#[derive(Debug)]
pub struct NngStatRoot {
node: *mut nng_stat,
}
impl NngStatRoot {
pub fn new() -> Result<NngStatRoot> {
unsafe {
let mut node: *mut nng_stat = std::ptr::null_mut();
let res = nng_stats_get(&mut node);
Error::zero_map(res, || NngStatRoot { node })
}
}
}
impl NngStat for NngStatRoot {
unsafe fn nng_stat(&self) -> *mut nng_stat {
self.node
}
}
impl Drop for NngStatRoot {
fn drop(&mut self) {
unsafe {
trace!("Drop NngStatRoot");
nng_stats_free(self.node)
}
}
}
#[derive(Debug)]
pub struct NngStatChild<'root> {
node: *mut nng_stat,
_phantom: marker::PhantomData<&'root nng_stat>,
}
impl<'root> NngStatChild<'root> {
pub fn new(node: *mut nng_stat) -> Option<NngStatChild<'root>> {
if node.is_null() {
None
} else {
Some(NngStatChild {
node,
_phantom: marker::PhantomData,
})
}
}
pub fn name(&self) -> result::Result<&str, std::str::Utf8Error> {
unsafe {
let ptr = nng_stat_name(self.nng_stat());
CStr::from_ptr(ptr).to_str()
}
}
pub fn desc(&self) -> result::Result<&str, std::str::Utf8Error> {
unsafe {
let ptr = nng_stat_desc(self.nng_stat());
CStr::from_ptr(ptr).to_str()
}
}
pub fn stat_type(&self) -> result::Result<nng_stat_type_enum, EnumFromIntError> {
unsafe {
let val = nng_stat_type(self.nng_stat());
val.try_into()
}
}
pub fn value(&self) -> u64 {
unsafe { nng_stat_value(self.nng_stat()) }
}
pub fn string(&self) -> Option<&str> {
unsafe {
let ptr = nng_stat_string(self.nng_stat());
if ptr.is_null() {
return None;
}
CStr::from_ptr(ptr).to_str().ok()
}
}
pub fn unit(&self) -> result::Result<nng_unit_enum, EnumFromIntError> {
unsafe {
let val = nng_stat_unit(self.nng_stat());
nng_unit_enum::try_from(val)
}
}
pub fn timestamp(&self) -> u64 {
unsafe { nng_stat_timestamp(self.nng_stat()) }
}
pub fn iter(&self) -> Iter {
unsafe {
let node = self.nng_stat();
Iter {
node: NngStatChild::new(node),
}
}
}
pub fn next(&self) -> Option<NngStatChild<'root>> {
unsafe {
let node = self.nng_stat();
let node = nng_stat_next(node);
NngStatChild::new(node)
}
}
}
impl<'root> NngStat for NngStatChild<'_> {
unsafe fn nng_stat(&self) -> *mut nng_stat {
self.node
}
}
#[derive(Debug)]
pub struct Iter<'root> {
node: Option<NngStatChild<'root>>,
}
impl<'root> Iterator for Iter<'root> {
type Item = NngStatChild<'root>;
fn next(&mut self) -> Option<Self::Item> {
let next = self.node.take();
if let Some(ref node) = next {
self.node = node.next();
}
next
}
}