use displaydoc::Display;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Display)]
#[non_exhaustive]
pub enum Error {
WebSocket(Box<tokio_tungstenite::tungstenite::Error>),
Json(serde_json::Error),
Url(url::ParseError),
Env(String),
Io(std::io::Error),
MissingCredentials,
AuthFailed(String),
NdaxError(i32, String),
Timeout,
ConnectionClosed,
}
impl std::error::Error for Error {}
impl From<tokio_tungstenite::tungstenite::Error> for Error {
fn from(err: tokio_tungstenite::tungstenite::Error) -> Self {
Error::WebSocket(Box::new(err))
}
}
impl From<serde_json::Error> for Error {
fn from(err: serde_json::Error) -> Self { Error::Json(err) }
}
impl From<url::ParseError> for Error {
fn from(err: url::ParseError) -> Self { Error::Url(err) }
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self { Error::Io(err) }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = Error::MissingCredentials;
assert_eq!(
format!("{}", err),
"Missing credentials required for authenticated API"
);
let err = Error::NdaxError(100, "Invalid request".to_string());
assert_eq!(
format!("{}", err),
"NDAX API error (code 100): Invalid request"
);
let err = Error::Timeout;
assert_eq!(format!("{}", err), "Request timeout");
let err = Error::ConnectionClosed;
assert_eq!(format!("{}", err), "Connection closed");
let err = Error::AuthFailed("bad signature".to_string());
assert_eq!(format!("{}", err), "Authentication failed: bad signature");
let err = Error::Env("NDAX_API_KEY not set".to_string());
assert_eq!(
format!("{}", err),
"Environment variable error: NDAX_API_KEY not set"
);
}
}