1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Error handling.

use std::fmt::{Debug, Formatter};

/// Error enumeration.
pub enum Error {
    /// Description error.
    Text(String),
    /// Parallelisation poison.
    Parallel,
    /// Formatting error.
    Format(std::fmt::Error),
    /// Missing environment variable error.
    EnvVar(std::env::VarError),
    /// File loading error.
    LoadFile(std::io::Error),
    /// Integer parsing error.
    ParseInt(std::num::ParseIntError),
    /// Float parsing error.
    ParseFloat(std::num::ParseFloatError),
    /// Hexadecimal parsing error.
    ParseHex(hex::FromHexError),
    /// Json reading error.
    ReadJson(json5::Error),
    /// Json writing error.
    WriteJson(serde_json::Error),
    /// Png writing error.
    WritePng(png::EncodingError),
    /// Shape error.
    InvalidShape(ndarray::ShapeError),
    /// Min/max error.
    MinMax(ndarray_stats::errors::MinMaxError),
    /// NetCDF io error.
    #[cfg(feature = "netcdf")]
    NetCDF(netcdf::error::Error),
}

macro_rules! impl_from_for_err {
    ($enum:path, $error:ty) => {
        impl From<$error> for Error {
            #[inline]
            fn from(e: $error) -> Self {
                $enum(e)
            }
        }
    };
}

impl From<&str> for Error {
    #[inline]
    fn from(err: &str) -> Self {
        Self::Text(err.to_string())
    }
}

impl<T> From<std::sync::PoisonError<T>> for Error {
    #[inline]
    fn from(_e: std::sync::PoisonError<T>) -> Self {
        Self::Parallel
    }
}

impl_from_for_err!(Self::Format, std::fmt::Error);
impl_from_for_err!(Self::EnvVar, std::env::VarError);
impl_from_for_err!(Self::LoadFile, std::io::Error);
impl_from_for_err!(Self::ParseInt, std::num::ParseIntError);
impl_from_for_err!(Self::ParseFloat, std::num::ParseFloatError);
impl_from_for_err!(Self::ParseHex, hex::FromHexError);
impl_from_for_err!(Self::ReadJson, json5::Error);
impl_from_for_err!(Self::WriteJson, serde_json::Error);
impl_from_for_err!(Self::WritePng, png::EncodingError);
impl_from_for_err!(Self::InvalidShape, ndarray::ShapeError);
impl_from_for_err!(Self::MinMax, ndarray_stats::errors::MinMaxError);
#[cfg(feature = "netcdf")]
impl_from_for_err!(Self::NetCDF, netcdf::error::Error);

impl Debug for Error {
    #[inline]
    fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
        write!(
            fmt,
            "{} error: `{}`",
            match self {
                Self::Text { .. } => "Text string",
                Self::Parallel { .. } => "Parallelisation poison",
                Self::Format { .. } => "Formatting",
                Self::EnvVar { .. } => "Environment variable",
                Self::LoadFile { .. } => "File loading",
                Self::ParseInt { .. } => "Integer parsing",
                Self::ParseFloat { .. } => "Float parsing",
                Self::ParseHex { .. } => "Hexadecimal parsing",
                Self::ReadJson { .. } => "Json reading",
                Self::WriteJson { .. } => "Json writing",
                Self::WritePng { .. } => "Png writing",
                Self::InvalidShape { .. } => "Invalid array shape",
                Self::MinMax { .. } => "MinMax",
                #[cfg(feature = "netcdf")]
                Self::NetCDF { .. } => "NetCDF IO",
            },
            match self {
                Self::Format { 0: err } => format!("{:?}", err),
                Self::Parallel => "Parallelisation fail".to_string(),
                Self::Text { 0: err } => format!("{:?}", err),
                Self::EnvVar { 0: err } => format!("{:?}", err),
                Self::LoadFile { 0: err } => format!("{:?}", err),
                Self::ParseInt { 0: err } => format!("{:?}", err),
                Self::ParseFloat { 0: err } => format!("{:?}", err),
                Self::ParseHex { 0: err } => format!("{:?}", err),
                Self::ReadJson { 0: err } => format!("{:?}", err),
                Self::WriteJson { 0: err } => format!("{:?}", err),
                Self::WritePng { 0: err } => format!("{:?}", err),
                Self::InvalidShape { 0: err } => format!("{:?}", err),
                Self::MinMax { 0: err } => format!("{:?}", err),
                #[cfg(feature = "netcdf")]
                Self::NetCDF { 0: err } => format!("{:?}", err),
            }
        )
    }
}