use crate::{GCAbiConversion, GCDatapointID};
use std::{
ffi::{CStr, CString, c_char},
fmt::Debug,
};
#[repr(transparent)]
pub struct GCDatapoint(gc_abi_sys::GCDatapoint);
impl GCDatapoint {
pub fn new(id: GCDatapointID, name: &str, description: &str, unit: &str) -> GCDatapoint {
GCDatapoint(gc_abi_sys::GCDatapoint {
id,
name: CString::new(name).unwrap().into_raw(),
description: CString::new(description).unwrap().into_raw(),
unit: CString::new(unit).unwrap().into_raw(),
})
}
#[inline]
pub fn get_c_name(&self) -> &CStr {
unsafe { CStr::from_ptr(self.0.name) }
}
#[inline]
pub fn get_c_description(&self) -> &CStr {
unsafe { CStr::from_ptr(self.0.description) }
}
#[inline]
pub fn get_c_unit(&self) -> &CStr {
unsafe { CStr::from_ptr(self.0.unit) }
}
#[inline]
pub fn get_name(&self) -> String {
self.get_c_name().to_string_lossy().into_owned()
}
#[inline]
pub fn get_description(&self) -> String {
self.get_c_description().to_string_lossy().into_owned()
}
#[inline]
pub fn get_unit(&self) -> String {
self.get_c_unit().to_string_lossy().into_owned()
}
#[inline]
pub fn get_id(&self) -> GCDatapointID {
self.0.id
}
}
impl Debug for GCDatapoint {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GCDatapoint")
.field("id", &self.get_id())
.field("name", &self.get_name())
.field("description", &self.get_description())
.field("unit", &self.get_unit())
.finish()
}
}
impl Drop for GCDatapoint {
fn drop(&mut self) {
unsafe {
drop(CString::from_raw(self.0.name as *mut c_char));
drop(CString::from_raw(self.0.description as *mut c_char));
drop(CString::from_raw(self.0.unit as *mut c_char));
}
}
}
unsafe impl GCAbiConversion for GCDatapoint {
type CType = gc_abi_sys::GCDatapoint;
fn from_c(c_type: Self::CType) -> Self {
GCDatapoint(c_type)
}
fn into_c(self) -> Self::CType {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_c_conversion() {
let c_datapoint = gc_abi_sys::GCDatapoint {
id: 0,
name: CString::new("test").unwrap().into_raw(),
description: CString::new("test").unwrap().into_raw(),
unit: CString::new("test").unwrap().into_raw(),
};
let datapoint: GCDatapoint = GCDatapoint::from_c(c_datapoint);
assert_eq!(datapoint.get_id(), 0);
assert_eq!(datapoint.get_c_name().to_str().unwrap(), "test");
assert_eq!(datapoint.get_c_description().to_str().unwrap(), "test");
assert_eq!(datapoint.get_c_unit().to_str().unwrap(), "test");
assert_eq!(datapoint.get_name(), "test");
assert_eq!(datapoint.get_description(), "test");
assert_eq!(datapoint.get_unit(), "test");
}
#[test]
fn test_data_point_create() {
let datapoint = GCDatapoint::new(0, "test", "test", "test");
assert_eq!(datapoint.get_id(), 0);
assert_eq!(datapoint.get_c_name().to_str().unwrap(), "test");
assert_eq!(datapoint.get_c_description().to_str().unwrap(), "test");
assert_eq!(datapoint.get_c_unit().to_str().unwrap(), "test");
assert_eq!(datapoint.get_name(), "test");
assert_eq!(datapoint.get_description(), "test");
assert_eq!(datapoint.get_unit(), "test");
}
}