use std::str::FromStr;
use std::os::raw::c_char;
use num_complex::Complex;
use soapysdr_sys::*;
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
#[non_exhaustive]
pub enum Format {
CF64,
CF32,
CS32,
CU32,
CS16,
CU16,
CS12,
CU12,
CS8,
CU8,
CS4,
CU4,
F64,
F32,
S32,
U32,
S16,
U16,
S8,
U8,
}
type ParseFormatError = ();
impl FromStr for Format {
type Err = ParseFormatError;
fn from_str(s: &str) -> Result<Format, ParseFormatError> {
match s {
"CF64" => Ok(Format::CF64),
"CF32" => Ok(Format::CF32),
"CS32" => Ok(Format::CS32),
"CU32" => Ok(Format::CU32),
"CS16" => Ok(Format::CS16),
"CU16" => Ok(Format::CU16),
"CS12" => Ok(Format::CS12),
"CU12" => Ok(Format::CU12),
"CS8" => Ok(Format::CS8),
"CU8" => Ok(Format::CU8),
"CS4" => Ok(Format::CS4),
"CU4" => Ok(Format::CU4),
"F64" => Ok(Format::F64),
"F32" => Ok(Format::F32),
"S32" => Ok(Format::S32),
"U32" => Ok(Format::U32),
"S16" => Ok(Format::S16),
"U16" => Ok(Format::U16),
"S8" => Ok(Format::S8),
"U8" => Ok(Format::U8),
_ => Err(()),
}
}
}
impl Format {
fn as_str_with_nul(&self) -> &'static str {
match *self {
Format::CF64 => "CF64\0",
Format::CF32 => "CF32\0",
Format::CS32 => "CS32\0",
Format::CU32 => "CU32\0",
Format::CS16 => "CS16\0",
Format::CU16 => "CU16\0",
Format::CS12 => "CS12\0",
Format::CU12 => "CU12\0",
Format::CS8 => "CS8\0",
Format::CU8 => "CU8\0",
Format::CS4 => "CS4\0",
Format::CU4 => "CU4\0",
Format::F64 => "F64\0",
Format::F32 => "F32\0",
Format::S32 => "S32\0",
Format::U32 => "U32\0",
Format::S16 => "S16\0",
Format::U16 => "U16\0",
Format::S8 => "S8\0",
Format::U8 => "U8\0",
}
}
pub(crate) fn as_ptr(&self) -> *const c_char {
self.as_str_with_nul().as_ptr() as *const c_char
}
pub fn as_str(&self) -> &str {
let s = self.as_str_with_nul();
&s[..s.len()-1]
}
pub fn size(&self) -> usize {
unsafe { SoapySDR_formatToSize(self.as_ptr()) }
}
}
impl ::std::fmt::Debug for Format {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl ::std::fmt::Display for Format {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
pub unsafe trait StreamSample {
const STREAM_FORMAT: Format;
}
unsafe impl StreamSample for u8 { const STREAM_FORMAT: Format = Format::U8; }
unsafe impl StreamSample for u16 { const STREAM_FORMAT: Format = Format::U16; }
unsafe impl StreamSample for u32 { const STREAM_FORMAT: Format = Format::U32; }
unsafe impl StreamSample for i8 { const STREAM_FORMAT: Format = Format::S8; }
unsafe impl StreamSample for i16 { const STREAM_FORMAT: Format = Format::S16; }
unsafe impl StreamSample for i32 { const STREAM_FORMAT: Format = Format::S32; }
unsafe impl StreamSample for f32 { const STREAM_FORMAT: Format = Format::F32; }
unsafe impl StreamSample for f64 { const STREAM_FORMAT: Format = Format::F64; }
unsafe impl StreamSample for Complex<u8> { const STREAM_FORMAT: Format = Format::CU8; }
unsafe impl StreamSample for Complex<u16> { const STREAM_FORMAT: Format = Format::CU16; }
unsafe impl StreamSample for Complex<u32> { const STREAM_FORMAT: Format = Format::CU32; }
unsafe impl StreamSample for Complex<i8> { const STREAM_FORMAT: Format = Format::CS8; }
unsafe impl StreamSample for Complex<i16> { const STREAM_FORMAT: Format = Format::CS16; }
unsafe impl StreamSample for Complex<i32> { const STREAM_FORMAT: Format = Format::CS32; }
unsafe impl StreamSample for Complex<f32> { const STREAM_FORMAT: Format = Format::CF32; }
unsafe impl StreamSample for Complex<f64> { const STREAM_FORMAT: Format = Format::CF64; }