1//! Component range error
23use core::{fmt, hash};
45use crate::error;
67/// An error type indicating that a component provided to a method was out of range, causing a
8/// failure.
9// i64 is the narrowest type fitting all use cases. This eliminates the need for a type parameter.
10#[derive(Debug, Clone, Copy, Eq)]
11pub struct ComponentRange {
12/// Name of the component.
13pub(crate) name: &'static str,
14/// Minimum allowed value, inclusive.
15pub(crate) minimum: i64,
16/// Maximum allowed value, inclusive.
17pub(crate) maximum: i64,
18/// Value that was provided.
19pub(crate) value: i64,
20/// The minimum and/or maximum value is conditional on the value of other
21 /// parameters.
22pub(crate) conditional_message: Option<&'static str>,
23}
2425impl ComponentRange {
26/// Obtain the name of the component whose value was out of range.
27pub const fn name(self) -> &'static str {
28self.name
29 }
3031/// Whether the value's permitted range is conditional, i.e. whether an input with this
32 /// value could have succeeded if the values of other components were different.
33pub const fn is_conditional(self) -> bool {
34self.conditional_message.is_some()
35 }
36}
3738impl PartialEq for ComponentRange {
39fn eq(&self, other: &Self) -> bool {
40self.name == other.name
41 && self.minimum == other.minimum
42 && self.maximum == other.maximum
43 && self.value == other.value
44// Skip the contents of the message when comparing for equality.
45&& self.conditional_message.is_some() == other.conditional_message.is_some()
46 }
47}
4849impl hash::Hash for ComponentRange {
50fn hash<H: hash::Hasher>(&self, state: &mut H) {
51self.name.hash(state);
52self.minimum.hash(state);
53self.maximum.hash(state);
54self.value.hash(state);
55// Skip the contents of the message when comparing for equality.
56self.conditional_message.is_some().hash(state);
57 }
58}
5960impl fmt::Display for ComponentRange {
61fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62write!(
63 f,
64"{} must be in the range {}..={}",
65self.name, self.minimum, self.maximum
66 )?;
6768if let Some(message) = self.conditional_message {
69write!(f, " {message}")?;
70 }
7172Ok(())
73 }
74}
7576impl From<ComponentRange> for crate::Error {
77fn from(original: ComponentRange) -> Self {
78Self::ComponentRange(original)
79 }
80}
8182impl TryFrom<crate::Error> for ComponentRange {
83type Error = error::DifferentVariant;
8485fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
86match err {
87crate::Error::ComponentRange(err) => Ok(err),
88_ => Err(error::DifferentVariant),
89 }
90 }
91}
9293/// **This trait implementation is deprecated and will be removed in a future breaking release.**
94#[cfg(feature = "serde")]
95impl serde::de::Expected for ComponentRange {
96fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97write!(
98 f,
99"a value in the range {}..={}",
100self.minimum, self.maximum
101 )
102 }
103}
104105#[cfg(feature = "serde")]
106impl ComponentRange {
107/// Convert the error to a deserialization error.
108pub(crate) fn into_de_error<E: serde::de::Error>(self) -> E {
109 E::invalid_value(serde::de::Unexpected::Signed(self.value), &self)
110 }
111}
112113#[cfg(feature = "std")]
114impl std::error::Error for ComponentRange {}