use std::fmt;

/// This error indicates
/// that the provided length exceeded the maximum.
///
/// The maximum length allowed and the actual length provided
/// are retrievable from the error object.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TooLongError {
    max: usize,
    len: usize,
}

impl fmt::Display for TooLongError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "length must be <={}, but {}", self.max, self.len)
    }
}

impl std::error::Error for TooLongError {}

impl TooLongError {
    /// Constructs an error object from the specified parameters.
    pub fn new(max: usize, len: usize) -> Self {
        Self { max, len }
    }

    /// Returns the maximum length allowed.
    pub fn max(&self) -> usize {
        self.max
    }

    /// Returns the actual length provided.
    pub fn actual_len(&self) -> usize {
        self.len
    }
}

/// This error indicates
/// that the provided length was shorter than the minimum.
///
/// The minimum length allowed and the actual length provided
/// are retrievable from the error object.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TooShortError {
    min: usize,
    len: usize,
}

impl fmt::Display for TooShortError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "length must be >={}, but {}", self.min, self.len)
    }
}

impl std::error::Error for TooShortError {}

impl TooShortError {
    /// Constructs an error object from the specified parameters.
    pub fn new(min: usize, len: usize) -> Self {
        Self { min, len }
    }

    /// Returns the maximum length allowed.
    pub fn min(&self) -> usize {
        self.min
    }

    /// Returns the actual length provided.
    pub fn actual_len(&self) -> usize {
        self.len
    }
}
