use std::fmt;
#[derive(PartialEq, Clone, Debug)]
pub enum Error {
MsgToLarge,
UnknownId(u8),
Incomplete(&'static str),
InvalidProtocolId,
InvalidInfoHash,
InvalidPeerId,
InvalidLength(&'static str),
InvalidPieceIndex(&'static str),
FileNotFound,
FileCannotWrite,
PeerNotFound,
PieceNotRequested,
PieceNotLoaded,
PieceBuffMissing,
PieceHashMismatch,
KeepAliveTimeout,
InfoMissing,
SocketNotAvailable,
CantReadFromSocket,
ConnectionReset,
ConnectionClosed,
DecodeUnexpectedChar(&'static str, usize),
DecodeIncorrectChar(&'static str, usize),
DecodeUnableConvert(&'static str, &'static str, usize),
DecodeNotEnoughChars(&'static str, usize),
DecodeMissingTerminalChars(&'static str, usize),
DecodeLeadingZero(&'static str, usize),
DecodeOddNumOfElements(&'static str, usize),
DecodeKeyNotString(&'static str, usize),
TrackerBEncodeMissing,
TrackerDataMissing,
TrackerIncorrectOrMissing(&'static str),
TrackerRespFail(String),
MetaFileNotFound,
MetaBEncodeMissing,
MetaDataMissing,
MetaLenAndFilesConflict,
MetaLenOrFilesMissing,
MetaInvalidUtf8(&'static str),
MetaIncorrectOrMissing(&'static str),
MetaInvalidU64(&'static str),
MetaNotDivisible(&'static str),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::MsgToLarge => write!(f, "Message to large"),
Error::UnknownId(msg_id) => write!(f, "Unknown Id({})", msg_id),
Error::Incomplete(msg) => write!(f, "Incomplete {}", msg),
Error::InvalidProtocolId => write!(f, "Invalid protocol Id"),
Error::InvalidInfoHash => write!(f, "Invalid info hash"),
Error::InvalidPeerId => write!(f, "Invalid peer id"),
Error::InvalidLength(msg) => write!(f, "Invalid length in {}", msg),
Error::InvalidPieceIndex(msg) => write!(f, "Invalid piece index in {}", msg),
Error::FileNotFound => write!(f, "File not found"),
Error::FileCannotWrite => write!(f, "Can't write to file"),
Error::PeerNotFound => write!(f, "Peer not found"),
Error::PieceNotRequested => write!(f, "Piece not requested"),
Error::PieceNotLoaded => write!(f, "Piece not loaded"),
Error::PieceBuffMissing => write!(f, "Piece buff missing"),
Error::PieceHashMismatch => write!(f, "Piece hash mismatch"),
Error::KeepAliveTimeout => write!(f, "Keep alive timeout"),
Error::SocketNotAvailable => write!(f, "Socket not available"),
Error::CantReadFromSocket => write!(f, "Can't read from socket"),
Error::InfoMissing => write!(f, "Info field missing"),
Error::ConnectionReset => write!(f, "Connection reset by peer"),
Error::ConnectionClosed => write!(f, "Connection closed by peer"),
Error::DecodeUnexpectedChar(fun, pos) => {
write!(f, "{}: unexpected end character at {}", fun, pos)
}
Error::DecodeIncorrectChar(fun, pos) => {
write!(f, "{}: incorrect character at {}", fun, pos)
}
Error::DecodeUnableConvert(fun, name, pos) => {
write!(f, "{}: unable convert to {} at {}", fun, name, pos)
}
Error::DecodeNotEnoughChars(fun, pos) => {
write!(f, "{}: not enough characters at {}", fun, pos)
}
Error::DecodeMissingTerminalChars(fun, pos) => {
write!(f, "{}: missing terminate character at {}", fun, pos)
}
Error::DecodeLeadingZero(fun, pos) => write!(f, "{}: leading zero at {}", fun, pos),
Error::DecodeOddNumOfElements(fun, pos) => {
write!(f, "{}: odd number of elements at {}", fun, pos)
}
Error::DecodeKeyNotString(fun, pos) => {
write!(f, "{}: key is not string at {}", fun, pos)
}
Error::TrackerBEncodeMissing => write!(f, "Tracker, bencode is missing"),
Error::TrackerDataMissing => write!(f, "Tracker, data is missing"),
Error::TrackerIncorrectOrMissing(name) => {
write!(f, "Tracker, incorrect or missing '{}' value", name)
}
Error::TrackerRespFail(reason) => write!(f, "Tracker fail: {}", reason),
Error::MetaFileNotFound => write!(f, "Metainfo, file not found"),
Error::MetaBEncodeMissing => write!(f, "Metainfo, bencode is missing"),
Error::MetaDataMissing => write!(f, "Metainfo, data is missing"),
Error::MetaLenAndFilesConflict => write!(
f,
"Metainfo, conflicting 'length' and 'files' values present. Only one is allowed"
),
Error::MetaLenOrFilesMissing => write!(f, "Metainfo, missing 'length' or 'files'"),
Error::MetaInvalidUtf8(name) => {
write!(f, "Metainfo, Can't convert '{}' to UTF-8", name)
}
Error::MetaIncorrectOrMissing(name) => {
write!(f, "Metainfo, incorrect or missing '{}' value", name)
}
Error::MetaInvalidU64(name) => write!(f, "Metainfo, can't convert '{}' to u64", name),
Error::MetaNotDivisible(name) => write!(f, "Metainfo, '{}' not divisible by 20", name),
}
}
}
impl std::error::Error for Error {}