pub type ByteVector = Vec<u8>;
pub mod cd;
pub mod types;

pub enum Error {
    IOError(Option<String>, std::io::Error),
    TypeError(String),
    GenericError(String),
    NoSectorForLBA(usize),
    IncorrectCUELine(String),
    CUEDataTypeNotSupported(types::cue::DataType),
    EOF,
    TimeToLarge,    
    NotImplemented,
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Error::IOError(file_opt, code) => {
                if let Some(file) = file_opt {
                    write!(f, "IO-Error for file \"{}\": {}", file, code)
                }
                
                else {
                    write!(f, "IO-Error: {}", code)
                }
            },
            Error::TypeError(file)                   => write!(f, "Type error: \"{}\"", file),
            Error::GenericError(text)                => write!(f, "{}", text),
            Error::NoSectorForLBA(lba)               => write!(f, "No sector for lba {}", lba),
            Error::IncorrectCUELine(line)            => write!(f, "Failed parsing \"{}\" as CUE", line),
            Error::CUEDataTypeNotSupported(cue_type) => write!(f, "CUE type \"{}\" not supported currently", cue_type),
            Error::EOF                               => write!(f, "Unexpected end of file"),
            Error::TimeToLarge                       => write!(f, "Time exceeded {}min", types::time::Time::MAX_MINUTES),
            Error::NotImplemented                    => write!(f, "<not implemented>"),
        }
    }
}

impl std::convert::From<std::io::Error> for Error {
    fn from(error: std::io::Error) -> Self {
        Error::IOError(None, error)
    }
}