collectd_plugin/api/
oconfig.rs1use crate::bindings::{
2 oconfig_item_t, oconfig_value_s__bindgen_ty_1, oconfig_value_t, OCONFIG_TYPE_BOOLEAN,
3 OCONFIG_TYPE_NUMBER, OCONFIG_TYPE_STRING,
4};
5use crate::errors::ConfigError;
6use std::ffi::CStr;
7use std::slice;
8
9#[derive(Debug, PartialEq, Clone)]
11pub enum ConfigValue<'a> {
12 Number(f64),
14
15 Boolean(bool),
17
18 String(&'a str),
20}
21
22#[derive(Debug, PartialEq, Clone)]
24pub struct ConfigItem<'a> {
25 pub key: &'a str,
27
28 pub values: Vec<ConfigValue<'a>>,
30
31 pub children: Vec<ConfigItem<'a>>,
33}
34
35impl ConfigValue<'_> {
36 pub unsafe fn from(value: &oconfig_value_t) -> Result<ConfigValue<'_>, ConfigError> {
40 match value.value {
41 oconfig_value_s__bindgen_ty_1 { string }
42 if value.type_ == OCONFIG_TYPE_STRING as i32 =>
43 {
44 Ok(ConfigValue::String(
45 CStr::from_ptr(string)
46 .to_str()
47 .map_err(ConfigError::StringDecode)?,
48 ))
49 }
50 oconfig_value_s__bindgen_ty_1 { number }
51 if value.type_ == OCONFIG_TYPE_NUMBER as i32 =>
52 {
53 Ok(ConfigValue::Number(number))
54 }
55 oconfig_value_s__bindgen_ty_1 { boolean }
56 if value.type_ == OCONFIG_TYPE_BOOLEAN as i32 =>
57 {
58 Ok(ConfigValue::Boolean(boolean != 0))
59 }
60 _ => Err(ConfigError::UnknownType(value.type_)),
61 }
62 }
63}
64
65impl ConfigItem<'_> {
66 pub unsafe fn from(item: &oconfig_item_t) -> Result<ConfigItem, ConfigError> {
70 let key = CStr::from_ptr(item.key)
71 .to_str()
72 .map_err(ConfigError::StringDecode)?;
73
74 let values = if !item.values.is_null() {
75 slice::from_raw_parts(item.values, item.values_num.max(0) as usize)
76 .iter()
77 .map(|x| ConfigValue::from(x))
78 .collect::<Result<Vec<_>, _>>()?
79 } else {
80 Vec::new()
81 };
82
83 let children = if !item.children.is_null() {
84 slice::from_raw_parts(item.children, item.children_num.max(0) as usize)
85 .iter()
86 .map(|x| ConfigItem::from(x))
87 .collect::<Result<Vec<_>, _>>()?
88 } else {
89 Vec::new()
90 };
91
92 Ok(ConfigItem {
93 key,
94 values,
95 children,
96 })
97 }
98}