use crate::{
constants::{DOMAIN_NAME_LABEL_MAX_LENGTH, DOMAIN_NAME_MAX_LENGTH, DOMAIN_NAME_MAX_POINTERS},
message::{MessageType, OpCode, RCode, RecordsSection},
records::{Class, Type},
};
#[allow(missing_docs)]
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("io error")]
IoError(#[from] std::io::Error),
#[error("unknown type: {0}")]
UnknownType(Type),
#[error("TYPE {0} is not expected")]
UnexpectedType(Type),
#[error("unknown class: {0}")]
UnknownClass(Class),
#[error("unknown operation code: {0}")]
UnknownOpCode(OpCode),
#[error("unknown response code: {0}")]
UnknownRCode(RCode),
#[error("{0}: {1:#02X}")]
DomainNameLabelInvalidChar(&'static str, u8),
#[error(
"domain name label length exceeds allowed limit {limit}: {0}",
limit = DOMAIN_NAME_LABEL_MAX_LENGTH
)]
DomainNameLabelTooLong(usize),
#[error("domain name label is empty")]
DomainNameLabelIsEmpty,
#[error(
"domain name length exceeds allowed limit {limit}: {0}",
limit = DOMAIN_NAME_MAX_LENGTH
)]
DomainNameTooLong(usize),
#[error(
"domain name pointer count exceeds allowed limit {limit}",
limit = DOMAIN_NAME_MAX_POINTERS
)]
DomainNameTooMuchPointers,
#[error("domain name label type is invalid: label = {0:#02X}")]
DomainNameBadLabelType(u8),
#[error("domain name label pointer {pointer} exceeds buffer max offset {max_offset}")]
DomainNameBadPointer { pointer: usize, max_offset: usize },
#[error("buffer end reached unexpectedly")]
EndOfBuffer,
#[error("buffer window end reached unexpectedly")]
EndOfWindow,
#[error("cursor is already in window mode")]
CursorAlreadyInWindow,
#[error("cursor not in window mode")]
CursorNotInWindow,
#[error("cursor window error: window_end {window_end}, pos {pos}")]
CursorWindowError { window_end: usize, pos: usize },
#[error("buffer is not large enough: {0} bytes required")]
BufferTooShort(usize),
#[error("unexpected questions count {0}")]
BadQuestionsCount(usize),
#[error("message type {0} is incompatible in this context")]
BadMessageType(MessageType),
#[error("bad response code: {0}")]
BadResponseCode(RCode),
#[error("message is truncated")]
MessageTruncated,
#[error("message size exceeds 65535 bytes: {0}")]
MessageTooLong(usize),
#[error("section '{0}' offset is unknown")]
RecordsSectionOffsetUnknown(RecordsSection),
#[error("message contains no records that answer the query")]
NoAnswer,
#[error("Type {0} is not supported")]
UnsupportedType(Type),
#[error("Class {0} is not supported")]
UnsupportedClass(Class),
#[error("operation timed-out")]
Timeout,
#[error("bad parameter: {0}")]
BadParam(&'static str),
#[error("internal error: {0}")]
InternalError(&'static str),
#[error("records reader is exhausted or a previous call resulted in error")]
ReaderDone,
}
#[derive(thiserror::Error, Debug)]
#[error("ClassFromStrError")]
pub struct ClassFromStrError;
#[derive(thiserror::Error, Debug)]
#[error("UnknownClassName")]
pub struct UnknownClassName;
#[derive(thiserror::Error, Debug)]
#[error("ClassFromStrError")]
pub struct RCodeFromStrError;
#[derive(thiserror::Error, Debug)]
#[error("UnknownRCodeName")]
pub struct UnknownRCodeName;
#[derive(thiserror::Error, Debug)]
#[error("TypeFromStrError")]
pub struct TypeFromStrError;
#[derive(thiserror::Error, Debug)]
#[error("UnknownTypeName")]
pub struct UnknownTypeName;
#[derive(thiserror::Error, Debug)]
#[error("OpCodeFromStrError")]
pub struct OpCodeFromStrError;
#[derive(thiserror::Error, Debug)]
#[error("UnknownOpCodeName")]
pub struct UnknownOpCodeName;
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn print_size() {
println!("size_of(Error) = {}", std::mem::size_of::<Error>());
println!(
"size_of(io::Error) = {}",
std::mem::size_of::<std::io::Error>()
);
assert_eq!(std::mem::size_of::<Error>(), 24);
}
}