use thiserror::Error;
pub use yldfi_common::api::ApiError;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum DomainError {
#[error("Price feed not found: {0}")]
FeedNotFound(String),
#[error("Invalid feed ID: {0}")]
InvalidFeedId(String),
#[error("Stale price data")]
StalePrice,
#[error("URL parse error: {0}")]
UrlParse(#[from] url::ParseError),
#[error("Insecure URL scheme: HTTPS required for non-localhost URLs")]
InsecureScheme,
#[error("Invalid URL: {0}")]
InvalidUrl(String),
}
pub type Error = ApiError<DomainError>;
pub type Result<T> = std::result::Result<T, Error>;
pub fn feed_not_found(feed_id: impl Into<String>) -> Error {
ApiError::domain(DomainError::FeedNotFound(feed_id.into()))
}
pub fn invalid_feed_id(feed_id: impl Into<String>) -> Error {
ApiError::domain(DomainError::InvalidFeedId(feed_id.into()))
}
#[must_use]
pub fn stale_price() -> Error {
ApiError::domain(DomainError::StalePrice)
}
#[must_use]
pub fn insecure_scheme() -> Error {
ApiError::domain(DomainError::InsecureScheme)
}
pub fn invalid_url(msg: impl Into<String>) -> Error {
ApiError::domain(DomainError::InvalidUrl(msg.into()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_feed_not_found() {
let err = feed_not_found("test-feed");
assert!(err.to_string().contains("Price feed not found"));
assert!(err.to_string().contains("test-feed"));
}
#[test]
fn test_invalid_feed_id() {
let err = invalid_feed_id("bad-id");
assert!(err.to_string().contains("Invalid feed ID"));
assert!(err.to_string().contains("bad-id"));
}
#[test]
fn test_stale_price() {
let err = stale_price();
assert!(err.to_string().contains("Stale price data"));
}
}