diff --git a/Cargo.toml b/Cargo.toml index 97ea287..1a3a875 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,6 @@ path = "src/se_ms_api.rs" [dependencies] chrono = "0.4" -reqwest = { version = "0.11", features = ["json", "blocking", "cookies"] } +reqwest = { version = "0.11", features = ["json", "blocking"] } serde = { version = "1", features = ["derive"] } - -[dev-dependencies] lazy_static = "1.4" diff --git a/src/current_version.rs b/src/current_version.rs index 3380775..d07bb93 100644 --- a/src/current_version.rs +++ b/src/current_version.rs @@ -1,6 +1,7 @@ //! Module for querying the current API version of the SolarEdge monitoring server. -use crate::SolaredgeCredentials; +use crate::error::Error; +use crate::{SolaredgeCredentials, REQWEST_CLIENT}; use serde::{Deserialize, Serialize}; /// Current version request @@ -36,21 +37,15 @@ impl CurrentVersionReq { /// # Returns /// The SolarEdge response or an error string. /// Errors can occur on the request send or when parsing the response. - pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result { + pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result { let url = format!( "{}version/current?{}", solaredge.url_start, solaredge.url_end ); - let res = match reqwest::blocking::get(&url) { - Ok(r) => r, - Err(e) => return Err(format!("reqwest get error {}", e)), - }; + let res = REQWEST_CLIENT.get(&url).send()?; - let parsed = match res.json::() { - Ok(p) => p, - Err(e) => return Err(format!("JSON parse error {}", e)), - }; + let parsed = res.json::()?; Ok(parsed) } diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..d8c7a6e --- /dev/null +++ b/src/error.rs @@ -0,0 +1,52 @@ +use std::error; +use std::fmt; + +/// An error that can occur in this library. +/// +/// Usually errors are when trying to send a request to the SolarEdge server, +/// or when trying to parse the response from the server. +#[derive(Debug)] +pub struct Error { + kind: ErrorKind, +} + +impl Error { + pub(crate) fn new(kind: ErrorKind) -> Error { + Error { kind } + } + + /// Convenience function for getting the kind of error. + pub fn kind(&self) -> &ErrorKind { + &self.kind + } +} + +/// The different kinds of errors that can occur. +#[derive(Debug)] +#[non_exhaustive] +pub enum ErrorKind { + /// An error returned from the reqwest crate. + ReqwestError(reqwest::Error), +} + +impl error::Error for Error { + fn description(&self) -> &str { + match self.kind { + ErrorKind::ReqwestError(_) => "Reqwest error", + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self.kind { + ErrorKind::ReqwestError(s) => write!(f, "Reqwest Error: HTTP status-code{}", s), + } + } +} + +impl From for Error { + fn from(e: reqwest::Error) -> Self { + Error::new(ErrorKind::ReqwestError(e)) + } +} diff --git a/src/se_ms_api.rs b/src/se_ms_api.rs index e5da1b9..d4d31dc 100644 --- a/src/se_ms_api.rs +++ b/src/se_ms_api.rs @@ -32,6 +32,9 @@ //! } //!} //! ``` +//! Due to the restrictions that SolarEdge imposes on this API, this library +//! does not try to be performant. For example, it makes blocking HTTP requests. +//! //! Supported API requests/responses include: //! * [CurrentVersionReq]/[CurrentVersionResp] //! * [SiteDetailsReq] / [SiteDetailsResp] @@ -65,26 +68,32 @@ //! SiteSensorList, //! SiteSensorData -//#![warn(unused_crate_dependencies)] +#![warn(unused_crate_dependencies)] #![deny(unused_extern_crates)] #![warn(missing_docs)] -pub mod site_details; +pub use current_version::{CurrentVersionReq, CurrentVersionResp}; +pub use error::{Error, ErrorKind}; +pub use meter_type::MeterType; pub use site_details::{SiteDetailsReq, SiteDetailsResp}; -pub mod site_energy_detailed; pub use site_energy_detailed::{SiteEnergyDetailedReq, SiteEnergyDetailedResp}; -pub mod current_version; -pub use current_version::{CurrentVersionReq, CurrentVersionResp}; -pub mod supported_versions; pub use supported_versions::{SupportedVersionsReq, SupportedVersionsResp}; -pub mod date_value; -pub mod meter_type; -pub use meter_type::MeterType; -pub mod meter_value; -pub mod site_location; -pub mod site_module; -pub mod site_public_settings; -pub mod time_unit; + +mod current_version; +mod date_value; +mod error; +mod meter_type; +mod meter_value; +mod site_details; +mod site_energy_detailed; +mod site_location; +mod site_module; +mod site_public_settings; +mod supported_versions; +mod time_unit; + +#[macro_use] +extern crate lazy_static; const URL_TIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S"; @@ -120,6 +129,11 @@ impl SolaredgeCredentials { } } +lazy_static! { + pub(crate) static ref REQWEST_CLIENT: reqwest::blocking::Client = + reqwest::blocking::Client::new(); +} + #[cfg(test)] pub(crate) fn is_normal() {} diff --git a/src/site_details.rs b/src/site_details.rs index a567dda..53a1d38 100644 --- a/src/site_details.rs +++ b/src/site_details.rs @@ -1,9 +1,10 @@ //! Module for site details requests and responses exchanged with the SolarEdge server monitoring API. +use crate::error::Error; use crate::site_location::SiteLocation; use crate::site_module::SiteModule; use crate::site_public_settings::SitePublicSettings; -use crate::SolaredgeCredentials; +use crate::{SolaredgeCredentials, REQWEST_CLIENT}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -90,21 +91,15 @@ impl SiteDetailsReq { /// # Returns /// The SolarEdge response or an error string. /// Errors can occur on the request send or when parsing the response. - pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result { + pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result { let url = format!( "{}site/{}/details?{}", solaredge.url_start, solaredge.site_id, solaredge.url_end ); - let res = match reqwest::blocking::get(&url) { - Ok(r) => r, - Err(e) => return Err(format!("reqwest get error {}", e)), - }; + let res = REQWEST_CLIENT.get(&url).send()?; - let parsed = match res.json::() { - Ok(p) => p, - Err(e) => return Err(format!("JSON parse error: {}", e)), - }; + let parsed = res.json::()?; Ok(parsed) } diff --git a/src/site_energy_detailed.rs b/src/site_energy_detailed.rs index c5576c1..3149a2d 100644 --- a/src/site_energy_detailed.rs +++ b/src/site_energy_detailed.rs @@ -1,10 +1,11 @@ //! Module for detailed site energy measurements from meters such as consumption, export (feed-in), import (purchase), etc. +use crate::error::Error; use crate::meter_type::MeterType; use crate::meter_value::MeterValue; use crate::time_unit::TimeUnit; -use crate::SolaredgeCredentials; use crate::URL_TIME_FORMAT; +use crate::{SolaredgeCredentials, REQWEST_CLIENT}; use serde::{Deserialize, Serialize}; /// site_energyDetails request @@ -92,7 +93,7 @@ impl SiteEnergyDetailedReq { /// # Returns /// The SolarEdge response or an error string. /// Errors can occur on the request send or when parsing the response. - pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result { + pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result { let url = format!( "{}site/{}/energyDetails?{}{}{}{}{}", solaredge.url_start, @@ -104,17 +105,9 @@ impl SiteEnergyDetailedReq { solaredge.url_end ); - //println!("url: {}\n", url); - let res = match reqwest::blocking::get(&url) { - Ok(r) => r, - Err(e) => return Err(format!("reqwest get error {}", e)), - }; - //println!("raw response: {:?}", res); + let res = REQWEST_CLIENT.get(&url).send()?; - let parsed = match res.json::() { - Ok(p) => p, - Err(e) => return Err(format!("JSON parse error {}", e)), - }; + let parsed = res.json::()?; Ok(parsed) } diff --git a/src/supported_versions.rs b/src/supported_versions.rs index f88844b..9560138 100644 --- a/src/supported_versions.rs +++ b/src/supported_versions.rs @@ -1,6 +1,7 @@ //! Module for querying the API versions supported by the SolarEdge monitoring server. -use crate::SolaredgeCredentials; +use crate::error::Error; +use crate::{SolaredgeCredentials, REQWEST_CLIENT}; use serde::{Deserialize, Serialize}; /// Supported versions request @@ -36,21 +37,15 @@ impl SupportedVersionsReq { /// # Returns /// The SolarEdge response or an error string. /// Errors can occur on the request send or when parsing the response. - pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result { + pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result { let url = format!( "{}version/supported?{}", solaredge.url_start, solaredge.url_end ); - let res = match reqwest::blocking::get(&url) { - Ok(r) => r, - Err(e) => return Err(format!("reqwest get error {}", e)), - }; + let res = REQWEST_CLIENT.get(&url).send()?; - let parsed = match res.json::() { - Ok(p) => p, - Err(e) => return Err(format!("JSON parse error {}", e)), - }; + let parsed = res.json::()?; Ok(parsed) }