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
use crate::{
    gl::{
        GetError, INVALID_ENUM, INVALID_FRAMEBUFFER_OPERATION, INVALID_OPERATION, INVALID_VALUE,
        NO_ERROR, OUT_OF_MEMORY,
    },
    GLenum,
};
use std::convert::TryInto;

/// Error Object for OpenGL.
#[derive(Clone, Copy, Default, PartialEq, Eq)]
pub struct Error(GLenum);

impl Error {
    /// Create an new error with glGetError.
    pub fn new() -> Self {
        Self {
            0: unsafe { GetError() },
        }
    }

    /// Return true if error raised.
    pub fn is_error(self) -> bool {
        self.0 != NO_ERROR.try_into().unwrap()
    }

    /// Return true if no error.
    pub fn is_okay(self) -> bool {
        self.0 == NO_ERROR.try_into().unwrap()
    }

    /// Return human reable text of the error code.
    pub fn to_str(self) -> &'static str {
        match self.0 as u32 {
            NO_ERROR => "No error",
            INVALID_ENUM => "An unacceptable value is specified for an enumerated argument",
            INVALID_VALUE => "A numeric argument is out of range",
            INVALID_OPERATION => "The specified operation is not allowed in the current state",
            INVALID_FRAMEBUFFER_OPERATION => "The framebuffer object is not complete",
            OUT_OF_MEMORY => "There is not enough memory left to execute the command",
            _ => "Unknown error",
        }
    }
}

impl std::fmt::Debug for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Error({}, \"{}\")", self.0, self.to_str())
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Error({}, \"{}\")", self.0, self.to_str())
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        self.to_str()
    }

    fn cause(&self) -> Option<&dyn std::error::Error> {
        None
    }
}