use serde::de::DeserializeOwned;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[error("information: {0}")]
AlphaVantageInformation(String),
#[error("error_message: {0}")]
AlphaVantageErrorMessage(String),
#[error("note: {0}")]
AlphaVantageNote(String),
#[error("alpha vantage returns invalid data")]
AlphaVantageInvalidData,
#[error("desired number of latest data not found try using less than {0} as n")]
DesiredNumberOfDataNotPresent(usize),
#[error("server returned empty response")]
EmptyResponse,
#[error("failed to get output from sever")]
GetRequestFailed,
#[error("failed to decode string into struct")]
DecodeJsonToStruct,
#[error("failed to create url")]
CreateUrl,
}
#[derive(serde::Deserialize)]
pub(crate) struct ErrorHolder<T> {
#[serde(rename = "Information")]
information: Option<String>,
#[serde(rename = "Error Message")]
error_message: Option<String>,
#[serde(rename = "Note")]
note: Option<String>,
#[serde(flatten)]
data: Option<T>,
}
impl<T> ErrorHolder<T>
where
T: DeserializeOwned,
{
pub(crate) fn handle_common_error(self) -> Result<T> {
if let Some(information) = self.information {
return Err(Error::AlphaVantageInformation(information));
}
if let Some(error_message) = self.error_message {
return Err(Error::AlphaVantageErrorMessage(error_message));
}
if let Some(note) = self.note {
return Err(Error::AlphaVantageNote(note));
}
let Some(data) = self.data else {
return Err(Error::AlphaVantageInvalidData);
};
Ok(data)
}
}