use std::convert::Infallible;
use thiserror::Error as ThisError;
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, ThisError)]
#[non_exhaustive]
pub enum Error {
#[error("{0}")]
Config(String),
#[error("not found: {0}")]
NotFound(String),
#[error("already exists: {0}")]
AlreadyExists(String),
#[error("invalid: {0}")]
Invalid(String),
#[error("commit conflict: {0}")]
Conflict(String),
#[error(transparent)]
Format(#[from] timelake_format::FormatError),
#[error(transparent)]
Iceberg(#[from] iceberg::Error),
#[error(transparent)]
ObjectStore(#[from] object_store::Error),
#[error(transparent)]
ObjectPath(#[from] object_store::path::Error),
#[error(transparent)]
Arrow(#[from] arrow::error::ArrowError),
#[error(transparent)]
Parquet(#[from] parquet::errors::ParquetError),
#[error(transparent)]
DataFusion(#[from] datafusion::error::DataFusionError),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Json(#[from] serde_json::Error),
}
impl Error {
pub(crate) fn config(msg: impl Into<String>) -> Self {
Self::Config(msg.into())
}
pub(crate) fn invalid(msg: impl Into<String>) -> Self {
Self::Invalid(msg.into())
}
}
impl From<timelake_format::error::WriteError> for Error {
fn from(e: timelake_format::error::WriteError) -> Self {
use timelake_format::error::WriteError as W;
match e {
W::Invalid(m) => Self::Invalid(m),
W::Conflict(m) => Self::Conflict(m),
W::NotFound(m) => Self::NotFound(m),
W::Store(m) | W::Corrupt(m) => Self::Io(std::io::Error::other(m)),
W::Format(e) => Self::Format(e),
W::Arrow(e) => Self::Arrow(e),
W::Parquet(e) => Self::Parquet(e),
}
}
}
impl From<Infallible> for Error {
fn from(e: Infallible) -> Self {
match e {}
}
}
impl From<Error> for datafusion::error::DataFusionError {
fn from(e: Error) -> Self {
match e {
Error::DataFusion(e) => e,
e => Self::External(Box::new(e)),
}
}
}