soapysdr/
arginfo.rs
1use soapysdr_sys::*;
2use std::slice;
3
4use std::ffi::CStr;
5use std::os::raw::c_char;
6
7#[derive(Copy, Clone, Eq, PartialEq, Debug)]
8pub enum ArgType {
9 Bool,
10 Float,
11 Int,
12 String,
13 __Nonexhaustive,
14}
15
16impl From<SoapySDRArgInfoType> for ArgType {
17 #[allow(non_upper_case_globals)]
18 fn from(arg_info_type: SoapySDRArgInfoType) -> Self {
19 match arg_info_type {
20 SoapySDRArgInfoType_SOAPY_SDR_ARG_INFO_BOOL => ArgType::Bool,
21 SoapySDRArgInfoType_SOAPY_SDR_ARG_INFO_FLOAT => ArgType::Float,
22 SoapySDRArgInfoType_SOAPY_SDR_ARG_INFO_INT => ArgType::Int,
23 SoapySDRArgInfoType_SOAPY_SDR_ARG_INFO_STRING => ArgType::String,
24 _ => ArgType::__Nonexhaustive,
25 }
26 }
27}
28
29
30#[derive(Debug)]
32pub struct ArgInfo {
33 pub key: String,
35
36 pub value: String,
38
39 pub name: Option<String>,
41
42 pub description: Option<String>,
44
45 pub units: Option<String>,
47
48 pub data_type: ArgType,
50
51 pub options: Vec<(String, Option<String>)>,
55}
56
57unsafe fn required_string(s: *mut c_char) -> String {
58 assert!(!s.is_null(), "Null string from SoapySDR");
59 CStr::from_ptr(s).to_string_lossy().into()
60}
61
62unsafe fn optional_string(s: *mut c_char) -> Option<String> {
63 if !s.is_null() {
64 Some(CStr::from_ptr(s).to_string_lossy().into())
65 } else {
66 None
67 }
68}
69
70pub unsafe fn arg_info_from_c(c: &SoapySDRArgInfo) -> ArgInfo {
71 ArgInfo {
72 key: required_string(c.key),
73 value: required_string(c.value),
74 name: optional_string(c.name),
75 description: optional_string(c.description),
76 units: optional_string(c.units),
77 data_type: c.type_.into(),
78 options: {
79 let option_vals = slice::from_raw_parts(c.options, c.numOptions);
80 let option_names = slice::from_raw_parts(c.optionNames, c.numOptions);
81 option_vals.iter().zip(option_names.iter()).map(|(&name, &val)| {
82 (required_string(name), optional_string(val))
83 }).collect()
84 }
85 }
86}