use serde_json::Value;
use thiserror::Error;
use zarrs_codec::CodecError;
use zarrs_data_type::FillValue;
use zarrs_metadata::FillValueMetadata;
use super::{ArrayBytesFixedDisjointViewCreateError, ArrayIndices, ArrayShape};
use crate::array::{ArraySubset, ArraySubsetError, IncompatibleDimensionalityError};
use crate::node::NodePathError;
use zarrs_plugin::PluginCreateError;
use zarrs_storage::StorageError;
#[derive(Clone, Debug, Error)]
pub enum ArrayCreateError {
#[error(transparent)]
NodePathError(#[from] NodePathError),
#[error(transparent)]
AdditionalFieldUnsupportedError(#[from] AdditionalFieldUnsupportedError),
#[error(transparent)]
DataTypeCreateError(PluginCreateError),
#[error("invalid fill value for data type `{data_type_name}`: {fill_value}")]
InvalidFillValue {
data_type_name: String,
fill_value: FillValue,
},
#[error("invalid fill value metadata for data type `{data_type_name}`: {fill_value_metadata}")]
InvalidFillValueMetadata {
data_type_name: String,
fill_value_metadata: FillValueMetadata,
},
#[error(transparent)]
CodecsCreateError(PluginCreateError),
#[error(transparent)]
StorageTransformersCreateError(PluginCreateError),
#[error(transparent)]
ChunkGridCreateError(PluginCreateError),
#[error(transparent)]
ChunkKeyEncodingCreateError(PluginCreateError),
#[error("chunk grid dimensionality {0} does not match array dimensionality {1}")]
InvalidChunkGridDimensionality(usize, usize),
#[error("the number of dimension names {0} does not match array dimensionality {1}")]
InvalidDimensionNames(usize, usize),
#[error("invalid subchunk shape {0:?}: all elements must be non-zero")]
InvalidSubchunkShape(super::ArrayShape),
#[error(transparent)]
StorageError(#[from] StorageError),
#[error("array metadata is missing")]
MissingMetadata,
#[error("unsupported Zarr V2 array: {_0}")]
UnsupportedZarrV2Array(String),
}
#[derive(Clone, Debug, Error)]
#[non_exhaustive]
pub enum ArrayError {
#[error(transparent)]
ArrayBytesFixedDisjointViewCreateError(#[from] ArrayBytesFixedDisjointViewCreateError),
#[error(transparent)]
StorageError(#[from] StorageError),
#[error(transparent)]
CodecError(#[from] CodecError),
#[error("invalid chunk grid indices: {_0:?}")]
InvalidChunkGridIndicesError(Vec<u64>),
#[error(transparent)]
IncompatibleDimensionalityError(#[from] IncompatibleDimensionalityError),
#[error(transparent)]
ArraySubsetError(#[from] ArraySubsetError),
#[error("array subset {_0} is not compatible with array shape {_1:?}")]
InvalidArraySubset(ArraySubset, ArrayShape),
#[error("chunk subset {_0} is not compatible with chunk {_1:?} with shape {_2:?}")]
InvalidChunkSubset(ArraySubset, ArrayIndices, ArrayShape),
#[error("got chunk decoded size {_0:?}, expected {_1:?}")]
UnexpectedChunkDecodedSize(usize, usize),
#[error("got bytes with size {_0:?}, expected {_1:?}")]
InvalidBytesInputSize(usize, u64),
#[error("got chunk decoded shape {_0:?}, expected {_1:?}")]
UnexpectedChunkDecodedShape(ArrayShape, ArrayShape),
#[error(transparent)]
ElementError(#[from] super::ElementError),
#[error("data has shape {_0:?}, expected {_1:?}")]
InvalidDataShape(Vec<usize>, Vec<usize>),
#[error("unsupported array method: {_0}")]
UnsupportedMethod(String),
#[cfg(feature = "dlpack")]
#[error(transparent)]
TensorError(#[from] super::TensorError),
#[error("{_0}")]
Other(String),
}
impl From<zarrs_codec::ExpectedFixedLengthBytesError> for ArrayError {
fn from(err: zarrs_codec::ExpectedFixedLengthBytesError) -> Self {
Self::CodecError(err.into())
}
}
impl From<zarrs_codec::ExpectedVariableLengthBytesError> for ArrayError {
fn from(err: zarrs_codec::ExpectedVariableLengthBytesError) -> Self {
Self::CodecError(err.into())
}
}
impl From<zarrs_codec::ExpectedOptionalBytesError> for ArrayError {
fn from(err: zarrs_codec::ExpectedOptionalBytesError) -> Self {
Self::CodecError(err.into())
}
}
#[derive(Clone, Debug, Error)]
#[error("unsupported additional field {name} with value {value}")]
pub struct AdditionalFieldUnsupportedError {
name: String,
value: Value,
}
impl AdditionalFieldUnsupportedError {
#[must_use]
pub fn new(name: String, value: Value) -> AdditionalFieldUnsupportedError {
Self { name, value }
}
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
#[must_use]
pub const fn value(&self) -> &Value {
&self.value
}
}