claxon/
error.rs

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
// Claxon -- A FLAC decoding library in Rust
// Copyright 2014 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

//! The `error` module defines the error and result types.

use std::error;
use std::fmt;
use std::io;
use std::result;
use std::string;

/// An error that prevents successful decoding of the FLAC stream.
#[derive(Debug)]
pub enum Error {
    /// Not a decoding error, but a problem with the underlying IO.
    IoError(io::Error),

    /// An ill-formed FLAC stream was encountered.
    FormatError(&'static str),

    /// A currently unsupported feature of the FLAC format was encountered.
    ///
    /// Claxon reads the FLAC format as it was with FLAC 1.3.1. Values in the
    /// specification that are marked as reserved will cause a `FormatError`;
    /// `Unsupported` is used for features that are in the specification, but
    /// which are not implemented by Claxon.
    Unsupported(&'static str),
}

impl PartialEq for Error {
    fn eq(&self, other: &Error) -> bool {
        use error::Error::{IoError, FormatError, Unsupported};
        match (self, other) {
            (&FormatError(r1), &FormatError(r2)) => r1 == r2,
            (&Unsupported(f1), &Unsupported(f2)) => f1 == f2,
            (&IoError(_), _) => false,
            (&FormatError(_), _) => false,
            (&Unsupported(_), _) => false,
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
        match *self {
            Error::IoError(ref err) => err.fmt(formatter),
            Error::FormatError(reason) => {
                try!(formatter.write_str("Ill-formed FLAC stream: "));
                formatter.write_str(reason)
            }
            Error::Unsupported(feature) => {
                try!(formatter.write_str("A currently unsupported feature of the FLAC format \
                                          was encountered: "));
                formatter.write_str(feature)
            }
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::IoError(ref err) => err.description(),
            Error::FormatError(reason) => reason,
            Error::Unsupported(_) => "unsupported feature",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::IoError(ref err) => Some(err),
            Error::FormatError(_) => None,
            Error::Unsupported(_) => None,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::IoError(err)
    }
}

impl From<string::FromUtf8Error> for Error {
    fn from(_: string::FromUtf8Error) -> Error {
        // Vendor strings and Vorbis comments are the only place where UTF-8 is
        // parsed into a String.
        Error::FormatError("Vorbis comment or vendor string is not valid UTF-8")
    }
}

/// A type for results generated by Claxon where the error type is hard-wired.
pub type Result<T> = result::Result<T, Error>;

/// Shorthand for producing a format error with reason.
pub fn fmt_err<T>(reason: &'static str) -> Result<T> {
    Err(Error::FormatError(reason))
}