diff --git a/CHANGELOG.md b/CHANGELOG.md index c0acc90..421cbcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +* Replaced Box dyn Error with RbError enum + ## [0.6.1] 2023-10-20 ### Fixed diff --git a/README.md b/README.md index 1f54c82..940407e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ radiobrowser = { version = "*", features = ["blocking"] } use radiobrowser::blocking::RadioBrowserAPI; use std::error::Error; -fn main() -> Result<(), Box> { +fn main() -> Result<(), RbError> { let mut api = RadioBrowserAPI::new()?; let servers = RadioBrowserAPI::get_default_servers()?; println!("Servers: {:?}", servers); @@ -50,7 +50,7 @@ use radiobrowser::StationOrder; use std::error::Error; #[async_std::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<(), RbError> { let mut api = RadioBrowserAPI::new().await?; let stations = api .get_stations() diff --git a/examples/test-async.rs b/examples/test-async.rs index 62b6adb..80011fc 100644 --- a/examples/test-async.rs +++ b/examples/test-async.rs @@ -1,10 +1,10 @@ use futures::join; use radiobrowser::RadioBrowserAPI; +use radiobrowser::RbError; use radiobrowser::StationOrder; -use std::error::Error; #[async_std::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<(), RbError> { let mut api = RadioBrowserAPI::new().await?; let countries = api.get_countries().send(); let languages = api.get_languages().send(); diff --git a/examples/test.rs b/examples/test.rs index 70fa879..367728a 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -1,7 +1,6 @@ -use radiobrowser::blocking::RadioBrowserAPI; -use std::error::Error; +use radiobrowser::{blocking::RadioBrowserAPI, RbError}; -fn main() -> Result<(), Box> { +fn main() -> Result<(), RbError> { let mut api = RadioBrowserAPI::new()?; let servers = RadioBrowserAPI::get_default_servers()?; println!("Servers: {:?}", servers); diff --git a/src/api.rs b/src/api.rs index 6a3887b..0b9c0b1 100644 --- a/src/api.rs +++ b/src/api.rs @@ -2,6 +2,7 @@ use crate::ApiStationClickResult; use crate::ApiStationHistory; use crate::ApiStationVoteResult; use crate::ApiStatus; +use crate::RbError; use crate::external::post_api; use crate::ApiConfig; use crate::CountrySearchBuilder; @@ -11,7 +12,6 @@ use crate::TagSearchBuilder; use serde::de::DeserializeOwned; use std::collections::HashMap; -use std::error::Error; use rand::seq::SliceRandom; use rand::thread_rng; @@ -27,10 +27,10 @@ use async_std_resolver::{config, resolver}; /// /// Example /// ```rust -/// use std::error::Error; +/// use radiobrowser::RbError; /// use radiobrowser::RadioBrowserAPI; /// #[async_std::main] -/// async fn main() -> Result<(), Box> { +/// async fn main() -> Result<(), RbError> { /// let mut api = RadioBrowserAPI::new().await?; /// Ok(()) /// } @@ -45,7 +45,7 @@ impl RadioBrowserAPI { /// Create a new instance of a radiobrowser api client. /// It will fetch a list of radiobrowser server with get_default_servers() /// and save it internally. - pub async fn new() -> Result> { + pub async fn new() -> Result { Ok(RadioBrowserAPI { servers: RadioBrowserAPI::get_default_servers().await?, current: 0, @@ -54,7 +54,7 @@ impl RadioBrowserAPI { /// Create a new instance of a radiobrowser api client from /// a single dns name. Use this is you want to connect to a single named server. - pub async fn new_from_dns_a>(dnsname: P) -> Result> { + pub async fn new_from_dns_a>(dnsname: P) -> Result { Ok(RadioBrowserAPI { servers: vec![dnsname.as_ref().to_string()], current: 0, @@ -63,7 +63,7 @@ impl RadioBrowserAPI { /// Create a new instance of a radiobrowser api client from /// a dns srv record which may have multiple dns A/AAAA records. - pub async fn new_from_dns_srv>(srvname: P) -> Result> { + pub async fn new_from_dns_srv>(srvname: P) -> Result { Ok(RadioBrowserAPI { servers: RadioBrowserAPI::get_servers_from_dns_srv(srvname).await?, current: 0, @@ -83,12 +83,12 @@ impl RadioBrowserAPI { async fn post_api>( &mut self, endpoint: A, - ) -> Result> { + ) -> Result { let mapjson = HashMap::new(); post_api(self.get_current_server(), endpoint.as_ref(), mapjson).await } - pub async fn get_station_changes(&mut self, limit: u64, last_change_uuid: Option) -> Result, Box> { + pub async fn get_station_changes(&mut self, limit: u64, last_change_uuid: Option) -> Result, RbError> { let query = match last_change_uuid { Some(uuid) => format!("/json/stations/changed?limit={}&lastchangeuuid={}", limit, uuid), None => format!("/json/stations/changed?limit={}", limit) @@ -96,21 +96,21 @@ impl RadioBrowserAPI { Ok(self.post_api(query).await?) } - pub async fn get_server_config(&mut self) -> Result> { + pub async fn get_server_config(&mut self) -> Result { Ok(self.post_api("/json/config").await?) } - pub async fn get_server_status(&mut self) -> Result> { + pub async fn get_server_status(&mut self) -> Result { Ok(self.post_api("/json/stats").await?) } /// Add a click to a station found by stationuuid - pub async fn station_click>(&mut self, stationuuid: P) -> Result> { + pub async fn station_click>(&mut self, stationuuid: P) -> Result { Ok(self.post_api(format!("/json/url/{}",stationuuid.as_ref())).await?) } /// Add a vote to a station found by a stationuuid - pub async fn station_vote>(&mut self, stationuuid: P) -> Result> { + pub async fn station_vote>(&mut self, stationuuid: P) -> Result { Ok(self.post_api(format!("/json/vote/{}",stationuuid.as_ref())).await?) } @@ -134,16 +134,16 @@ impl RadioBrowserAPI { &mut self, endpoint: P, mapjson: HashMap, - ) -> Result> { + ) -> Result { post_api(self.get_current_server(), endpoint, mapjson).await } - pub async fn get_default_servers() -> Result, Box> { + pub async fn get_default_servers() -> Result, RbError> { trace!("get_default_servers()"); RadioBrowserAPI::get_servers_from_dns_srv("_api._tcp.radio-browser.info").await } - async fn get_servers_from_dns_srv>(srvname: P) -> Result, Box> { + async fn get_servers_from_dns_srv>(srvname: P) -> Result, RbError> { trace!("get_servers_from_dns_srv()"); let resolver = resolver( config::ResolverConfig::default(), diff --git a/src/blocking/api.rs b/src/blocking/api.rs index 9340c96..f94a77a 100644 --- a/src/blocking/api.rs +++ b/src/blocking/api.rs @@ -1,4 +1,5 @@ use crate::ApiStationHistory; +use crate::RbError; use crate::blocking::stationsearchbuilder::StationSearchBuilder; use crate::blocking::CountrySearchBuilder; use crate::blocking::LanguageSearchBuilder; @@ -10,7 +11,6 @@ use crate::ApiConfig; use serde::de::DeserializeOwned; use std::collections::HashMap; -use std::error::Error; #[derive(Clone, Debug)] pub struct RadioBrowserAPI { @@ -20,40 +20,40 @@ pub struct RadioBrowserAPI { use async_std::task; impl RadioBrowserAPI { - pub fn new() -> Result> { + pub fn new() -> Result { task::block_on(async { crate::RadioBrowserAPI::new().await }) .map(|api| RadioBrowserAPI { api }) } - pub fn new_from_dns_a>(dnsname: P) -> Result> { + pub fn new_from_dns_a>(dnsname: P) -> Result { task::block_on(async { crate::RadioBrowserAPI::new_from_dns_a(dnsname).await }) .map(|api| RadioBrowserAPI { api }) } - pub fn new_from_dns_srv>(srvname: P) -> Result> { + pub fn new_from_dns_srv>(srvname: P) -> Result { task::block_on(async { crate::RadioBrowserAPI::new_from_dns_srv(srvname).await }) .map(|api| RadioBrowserAPI { api }) } - pub fn get_server_status(&mut self) -> Result> { + pub fn get_server_status(&mut self) -> Result { task::block_on(async { self.api.get_server_status().await }) } - pub fn get_station_changes(&mut self, limit: u64, last_change_uuid: Option) -> Result, Box> { + pub fn get_station_changes(&mut self, limit: u64, last_change_uuid: Option) -> Result, RbError> { task::block_on(async { self.api.get_station_changes(limit, last_change_uuid).await }) } - pub fn get_server_config(&mut self) -> Result> { + pub fn get_server_config(&mut self) -> Result { task::block_on(async { self.api.get_server_config().await }) } /// Add a click to a station found by stationuuid - pub fn station_click>(&mut self, stationuuid: P) -> Result> { + pub fn station_click>(&mut self, stationuuid: P) -> Result { task::block_on(async { self.api.station_click(stationuuid).await }) } /// Add a vote to a station found by a stationuuid - pub fn station_vote>(&mut self, stationuuid: P) -> Result> { + pub fn station_vote>(&mut self, stationuuid: P) -> Result { task::block_on(async { self.api.station_vote(stationuuid).await }) } @@ -77,11 +77,11 @@ impl RadioBrowserAPI { &mut self, endpoint: P, mapjson: HashMap, - ) -> Result> { + ) -> Result { task::block_on(async { self.api.send(endpoint, mapjson).await }) } - pub fn get_default_servers() -> Result, Box> { + pub fn get_default_servers() -> Result, RbError> { task::block_on(async { crate::RadioBrowserAPI::get_default_servers().await }) } } diff --git a/src/blocking/countrysearchbuilder.rs b/src/blocking/countrysearchbuilder.rs index 22366b0..6c355ad 100644 --- a/src/blocking/countrysearchbuilder.rs +++ b/src/blocking/countrysearchbuilder.rs @@ -1,6 +1,5 @@ -use crate::ApiCountry; +use crate::{ApiCountry, RbError}; use async_std::task; -use std::error::Error; #[derive(Clone, Debug)] pub struct CountrySearchBuilder { @@ -48,7 +47,7 @@ impl CountrySearchBuilder { } } - pub fn send(self) -> Result, Box> { + pub fn send(self) -> Result, RbError> { task::block_on(async { self.builder.send().await }) } } diff --git a/src/blocking/languagesearchbuilder.rs b/src/blocking/languagesearchbuilder.rs index 2ac25eb..001327b 100644 --- a/src/blocking/languagesearchbuilder.rs +++ b/src/blocking/languagesearchbuilder.rs @@ -1,6 +1,5 @@ -use crate::ApiLanguage; +use crate::{ApiLanguage, RbError}; use async_std::task; -use std::error::Error; #[derive(Clone, Debug)] pub struct LanguageSearchBuilder { @@ -48,7 +47,7 @@ impl LanguageSearchBuilder { } } - pub fn send(self) -> Result, Box> { + pub fn send(self) -> Result, RbError> { task::block_on(async { self.builder.send().await }) } } diff --git a/src/blocking/stationsearchbuilder.rs b/src/blocking/stationsearchbuilder.rs index 584d78b..caea886 100644 --- a/src/blocking/stationsearchbuilder.rs +++ b/src/blocking/stationsearchbuilder.rs @@ -1,7 +1,6 @@ use crate::structs::ApiStation; -use crate::StationOrder; +use crate::{StationOrder, RbError}; use async_std::task; -use std::error::Error; #[derive(Clone, Debug)] pub struct StationSearchBuilder { @@ -151,7 +150,7 @@ impl StationSearchBuilder { } } - pub fn send(self) -> Result, Box> { + pub fn send(self) -> Result, RbError> { task::block_on(async { self.builder.send().await }) } } diff --git a/src/blocking/tagsearchbuilder.rs b/src/blocking/tagsearchbuilder.rs index 367b382..238ab3e 100644 --- a/src/blocking/tagsearchbuilder.rs +++ b/src/blocking/tagsearchbuilder.rs @@ -1,6 +1,5 @@ -use crate::ApiTag; +use crate::{ApiTag, RbError}; use async_std::task; -use std::error::Error; #[derive(Clone, Debug)] pub struct TagSearchBuilder { @@ -48,7 +47,7 @@ impl TagSearchBuilder { } } - pub fn send(self) -> Result, Box> { + pub fn send(self) -> Result, RbError> { task::block_on(async { self.builder.send().await }) } } diff --git a/src/countrysearchbuilder.rs b/src/countrysearchbuilder.rs index de99fcc..fcca842 100644 --- a/src/countrysearchbuilder.rs +++ b/src/countrysearchbuilder.rs @@ -1,9 +1,8 @@ use crate::ApiCountry; use crate::RadioBrowserAPI; +use crate::RbError; use std::fmt::Display; - use std::collections::HashMap; -use std::error::Error; pub enum CountryOrder { Name, @@ -69,7 +68,7 @@ impl CountrySearchBuilder { self } - pub async fn send(mut self) -> Result, Box> { + pub async fn send(mut self) -> Result, RbError> { if let Some(filter) = self.filter { Ok(self .api diff --git a/src/external.rs b/src/external.rs index 4b2ea0e..f32b2af 100644 --- a/src/external.rs +++ b/src/external.rs @@ -1,13 +1,14 @@ use reqwest; use serde::de::DeserializeOwned; use std::collections::HashMap; -use std::error::Error; + +use crate::RbError; pub async fn post_api, B: AsRef>( server: A, endpoint: B, mapjson: HashMap, -) -> Result> { +) -> Result { static APP_USER_AGENT: &str = concat!("radiobrowser-lib-rust/", env!("CARGO_PKG_VERSION"),); let client = reqwest::Client::builder() diff --git a/src/languagesearchbuilder.rs b/src/languagesearchbuilder.rs index 377c124..d82cb89 100644 --- a/src/languagesearchbuilder.rs +++ b/src/languagesearchbuilder.rs @@ -1,9 +1,8 @@ use crate::ApiLanguage; use crate::RadioBrowserAPI; +use crate::RbError; use std::fmt::Display; - use std::collections::HashMap; -use std::error::Error; pub enum LanguageOrder { Name, @@ -69,7 +68,7 @@ impl LanguageSearchBuilder { self } - pub async fn send(mut self) -> Result, Box> { + pub async fn send(mut self) -> Result, RbError> { if let Some(filter) = self.filter { Ok(self .api diff --git a/src/lib.rs b/src/lib.rs index 78fa0e6..071d3d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,9 +7,9 @@ //! ``` //! ```rust //! use radiobrowser::blocking::RadioBrowserAPI; -//! use std::error::Error; +//! use radiobrowser::RbError; //! -//! fn main() -> Result<(), Box> { +//! fn main() -> Result<(), RbError> { //! let api = RadioBrowserAPI::new()?; //! let servers = RadioBrowserAPI::get_default_servers()?; //! println!("Servers: {:?}", servers); @@ -23,13 +23,13 @@ //! //! # Example async //! ```rust -//! use std::error::Error; +//! use radiobrowser::RbError; //! use futures::join; //! use radiobrowser::RadioBrowserAPI; //! use radiobrowser::StationOrder; //! //! #[async_std::main] -//! async fn main() -> Result<(), Box> { +//! async fn main() -> Result<(), RbError> { //! let mut api = RadioBrowserAPI::new().await?; //! let countries = api.get_countries().send(); //! let languages = api.get_languages().send(); @@ -60,7 +60,9 @@ mod countrysearchbuilder; mod languagesearchbuilder; mod tagsearchbuilder; mod structs; +mod rb_error; +pub use rb_error::RbError; pub use api::RadioBrowserAPI; pub use structs::ApiConfig; pub use structs::ApiCountry; diff --git a/src/rb_error.rs b/src/rb_error.rs new file mode 100644 index 0000000..0d15075 --- /dev/null +++ b/src/rb_error.rs @@ -0,0 +1,30 @@ +use async_std_resolver::ResolveError; + +#[derive(Debug)] +pub enum RbError { + Reqwest(reqwest::Error), + Resolve(ResolveError), +} + +impl std::error::Error for RbError {} + +impl std::fmt::Display for RbError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RbError::Reqwest(err) => write!(f, "Reqwest: {}", err), + RbError::Resolve(err) => write!(f, "Resolve: {}", err), + } + } +} + +impl From for RbError { + fn from(value: reqwest::Error) -> Self { + RbError::Reqwest(value) + } +} + +impl From for RbError { + fn from(value: ResolveError) -> Self { + RbError::Resolve(value) + } +} diff --git a/src/stationsearchbuilder.rs b/src/stationsearchbuilder.rs index a3dcb9b..9e5c5e9 100644 --- a/src/stationsearchbuilder.rs +++ b/src/stationsearchbuilder.rs @@ -1,9 +1,9 @@ +use crate::RbError; use crate::api::RadioBrowserAPI; use crate::structs::ApiStation; use std::fmt::Display; use std::collections::HashMap; -use std::error::Error; pub enum StationOrder { Name, @@ -206,7 +206,7 @@ impl StationSearchBuilder { self } - pub async fn send(mut self) -> Result, Box> { + pub async fn send(mut self) -> Result, RbError> { Ok(self.api.send("/json/stations/search", self.map).await?) } } diff --git a/src/tagsearchbuilder.rs b/src/tagsearchbuilder.rs index 506cfa9..b262fe3 100644 --- a/src/tagsearchbuilder.rs +++ b/src/tagsearchbuilder.rs @@ -1,9 +1,9 @@ use crate::ApiTag; use crate::RadioBrowserAPI; +use crate::RbError; use std::fmt::Display; use std::collections::HashMap; -use std::error::Error; pub enum TagOrder { Name, @@ -69,7 +69,7 @@ impl TagSearchBuilder { self } - pub async fn send(mut self) -> Result, Box> { + pub async fn send(mut self) -> Result, RbError> { if let Some(filter) = self.filter { Ok(self .api