use thiserror::Error;

#[derive(Debug, Error)]
pub enum ParseError {
    #[error("Invalid opcode: valid are 0 to 2 and 4 to 6, got {0}")]
    InvalidOpcode(u8),

    #[error("Invalid rcode: valid are 0 to 11 and 16 to 23, got {0}")]
    InvalidRcode(u16),

    #[error("Invalid (or unimplemented) type: {0}")]
    InvalidType(u16),

    #[error("Invalid class: valid are 1, 3, 4, 254 or 255, got {0}")]
    InvalidClass(u16),

    #[error("Invalid name in OPT record: must be root, is {0}")]
    InvalidOptName(String),

    #[error("Invalid label type: extended or invalid ({0})")]
    InvalidLabelType(u8),

    #[error("Received truncated message: if possible, resend query via TCP")]
    TruncatedMessage,

    #[error("IO error: {0}")]
    IoError(#[from] std::io::Error)
}

#[derive(Debug, Error)]
pub enum EncodeError {
    #[error("Domain name too long: allowed are up to 255 bytes, got {0}")]
    DomainTooLong(usize),

    #[error("Label too long: allowed are up to 63 bytes, got {0}")]
    LabelTooLong(usize),

    #[error("DO flag set but not using EDNS")]
    DoSetButNoEdns,

    #[error("AA or RA flag set in a query")]
    AaOrRaInQuery,

    #[error("IO error: {0}")]
    IoError(#[from] std::io::Error)
}