mod args;
pub use args::Args;
mod device;
pub use device::Device;
pub use device::DeviceTrait;
pub use device::GenericDevice;
pub mod impls;
mod range;
pub use range::Range;
pub use range::RangeItem;
mod streamer;
pub use streamer::RxStreamer;
pub use streamer::TxStreamer;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("DeviceError")]
DeviceError,
#[error("Value ({1}) out of range ({0:?})")]
OutOfRange(Range, f64),
#[error("Value Error")]
ValueError,
#[error("Not Found")]
NotFound,
#[error("corresponding feature not enabled")]
FeatureNotEnabled,
#[error("Not Supported")]
NotSupported,
#[error("Overflow")]
Overflow,
#[error("Inactive")]
Inactive,
#[error("Json")]
Json(#[from] serde_json::Error),
#[error("Misc")]
Misc(String),
#[error("Io")]
Io(#[from] std::io::Error),
#[cfg(all(feature = "soapy", not(target_arch = "wasm32")))]
#[error("Soapy")]
Soapy(soapysdr::Error),
#[cfg(all(feature = "aaronia_http", not(target_arch = "wasm32")))]
#[error("Ureq")]
Ureq(Box<ureq::Error>),
#[cfg(all(feature = "rtlsdr", not(target_arch = "wasm32")))]
#[error("RtlSdr")]
RtlSdr(#[from] seify_rtlsdr::error::RtlsdrError),
}
#[cfg(all(feature = "aaronia_http", not(target_arch = "wasm32")))]
impl From<ureq::Error> for Error {
fn from(value: ureq::Error) -> Self {
Error::Ureq(Box::new(value))
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Driver {
Aaronia,
AaroniaHttp,
RtlSdr,
Soapy,
}
impl FromStr for Driver {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.to_lowercase();
if s == "aaronia" {
return Ok(Driver::Aaronia);
}
if s == "aaronia_http" || s == "aaronia-http" || s == "aaroniahttp" {
return Ok(Driver::AaroniaHttp);
}
if s == "rtlsdr" || s == "rtl-sdr" || s == "rtl" {
return Ok(Driver::RtlSdr);
}
if s == "soapy" || s == "soapysdr" {
return Ok(Driver::Soapy);
}
Err(Error::ValueError)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum Direction {
Rx,
Tx,
}
pub fn enumerate() -> Result<Vec<Args>, Error> {
enumerate_with_args(Args::new())
}
pub fn enumerate_with_args<A: TryInto<Args>>(a: A) -> Result<Vec<Args>, Error> {
let args: Args = a.try_into().or(Err(Error::ValueError))?;
let mut devs = Vec::new();
let driver = match args.get::<String>("driver") {
Ok(s) => Some(s.parse::<Driver>()?),
Err(_) => None,
};
#[cfg(all(feature = "aaronia", any(target_os = "linux", target_os = "windows")))]
{
if driver.is_none() || matches!(driver, Some(Driver::Aaronia)) {
devs.append(&mut impls::Aaronia::probe(&args)?)
}
}
#[cfg(not(all(feature = "aaronia", any(target_os = "linux", target_os = "windows"))))]
{
if matches!(driver, Some(Driver::Aaronia)) {
return Err(Error::FeatureNotEnabled);
}
}
#[cfg(all(feature = "aaronia_http", not(target_arch = "wasm32")))]
{
if driver.is_none() || matches!(driver, Some(Driver::AaroniaHttp)) {
devs.append(&mut impls::AaroniaHttp::probe(&args)?)
}
}
#[cfg(not(all(feature = "aaronia_http", not(target_arch = "wasm32"))))]
{
if matches!(driver, Some(Driver::AaroniaHttp)) {
return Err(Error::FeatureNotEnabled);
}
}
#[cfg(all(feature = "rtlsdr", not(target_arch = "wasm32")))]
{
if driver.is_none() || matches!(driver, Some(Driver::RtlSdr)) {
devs.append(&mut impls::RtlSdr::probe(&args)?)
}
}
#[cfg(not(all(feature = "rtlsdr", not(target_arch = "wasm32"))))]
{
if matches!(driver, Some(Driver::RtlSdr)) {
return Err(Error::FeatureNotEnabled);
}
}
#[cfg(all(feature = "soapy", not(target_arch = "wasm32")))]
{
if driver.is_none() || matches!(driver, Some(Driver::Soapy)) {
devs.append(&mut impls::Soapy::probe(&args)?)
}
}
#[cfg(not(all(feature = "soapy", not(target_arch = "wasm32"))))]
{
if matches!(driver, Some(Driver::Soapy)) {
return Err(Error::FeatureNotEnabled);
}
}
let _ = &mut devs;
Ok(devs)
}