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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// error.rs
//
// Copyright (c) 2019  Douglas Lau
//
use std::error::Error as _;
use std::fmt::{self, Display};
use std::io;
use std::str;

/// Parse errors
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ParseError {
    ExpectedBool,
    ExpectedMore,
    ExpectedChar,
    ExpectedDate,
    ExpectedDateTime,
    ExpectedInt,
    ExpectedNumber,
    ExpectedTime,
    ExpectedTimeOffset,
    InvalidIndent,
    InvalidSeparator,
    InvalidSubstitute,
    InvalidType,
    MissingKey,
    MissingLinefeed,
    MissingSeparator,
    UnexpectedKey,
    UnexpectedSchemaSeparator,
}

impl ParseError {
    fn description(&self) -> &'static str {
        use ParseError::*;
        match self {
            ExpectedBool => "expected bool",
            ExpectedMore => "expected more input data",
            ExpectedChar => "expected char",
            ExpectedDate => "expected date",
            ExpectedDateTime => "expected datetime",
            ExpectedInt => "expected int",
            ExpectedNumber => "expected number",
            ExpectedTime => "expected time",
            ExpectedTimeOffset => "expected time offset",
            InvalidIndent => "invalid indent",
            InvalidSeparator => "invalid separator",
            InvalidSubstitute => "invalid substitute value",
            InvalidType => "invalid type",
            MissingKey => "missing key",
            MissingLinefeed => "missing line feed",
            MissingSeparator => "missing separator",
            UnexpectedKey => "unexpected key",
            UnexpectedSchemaSeparator => "unexpected schema separator",
        }
    }
}

/// Errors which can occur when serializing and deserializing MuON data.
#[derive(Debug)]
pub enum Error {
    /// I/O errors
    IO(io::Error),
    /// Formatting error while serializing
    Format(fmt::Error),
    /// Invalid UTF-8 while deserializing
    Utf8(str::Utf8Error),
    /// Invalid UTF-8 while serializing
    FromUtf8(std::string::FromUtf8Error),
    /// Serializing error from serde
    Serialize(String),
    /// Deserializing error from serde
    Deserialize(String),
    /// Unsupported type error
    UnsupportedType(&'static str),
    /// Invalid key
    InvalidKey,
    /// Failed parse while deserializing
    FailedParse(ParseError),
}

/// MuON result type
pub type Result<T> = std::result::Result<T, Error>;

impl serde::ser::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error::Serialize(msg.to_string())
    }
}

impl serde::de::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error::Deserialize(msg.to_string())
    }
}

impl Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str(self.description())
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::IO(ref e) => e.description(),
            Error::Format(ref e) => e.description(),
            Error::Utf8(ref e) => e.description(),
            Error::FromUtf8(ref e) => e.description(),
            Error::Serialize(ref msg) => msg,
            Error::Deserialize(ref msg) => msg,
            Error::UnsupportedType(ref msg) => msg,
            Error::InvalidKey => "string keys only",
            Error::FailedParse(ref e) => e.description(),
        }
    }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self {
        Error::IO(e)
    }
}

impl From<fmt::Error> for Error {
    fn from(e: fmt::Error) -> Self {
        Error::Format(e)
    }
}

impl From<str::Utf8Error> for Error {
    fn from(e: str::Utf8Error) -> Self {
        Error::Utf8(e)
    }
}

impl From<std::string::FromUtf8Error> for Error {
    fn from(e: std::string::FromUtf8Error) -> Self {
        Error::FromUtf8(e)
    }
}