1 use crate::err; 2 use core::{cmp::Eq, cmp::PartialEq, fmt::Debug, fmt::Display, hash::Hash}; 3 4 /// Error if a value exceeds the maximum allowed value. 5 #[derive(Clone, Debug, Eq, PartialEq, Hash)] 6 pub struct ValueTooBigError<T: Sized + Clone + Display + Debug + Eq + PartialEq + Hash> { 7 /// Value that was disallowed. 8 pub actual: T, 9 10 /// Maximum allowed value (inclusive). 11 pub max_allowed: T, 12 13 /// Type of value. 14 pub value_type: err::ValueType, 15 } 16 17 impl<T> core::fmt::Display for ValueTooBigError<T> 18 where 19 T: Sized + Clone + Display + Debug + Eq + PartialEq + Hash, 20 { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result21 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 22 write!( 23 f, 24 "Error '{}' is too big to be a '{}' (maximum allowed value is '{}')", 25 self.actual, self.value_type, self.max_allowed 26 ) 27 } 28 } 29 30 #[cfg(feature = "std")] 31 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 32 impl<T> std::error::Error for ValueTooBigError<T> 33 where 34 T: Sized + Clone + Display + Debug + Eq + PartialEq + Hash, 35 { source(&self) -> Option<&(dyn std::error::Error + 'static)>36 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 37 None 38 } 39 } 40 41 #[cfg(test)] 42 mod test { 43 use super::*; 44 use std::{collections::hash_map::DefaultHasher, error::Error, format, hash::Hasher}; 45 46 #[test] fmt()47 fn fmt() { 48 assert_eq!( 49 format!( 50 "{}", 51 ValueTooBigError { 52 actual: 3, 53 max_allowed: 2, 54 value_type: err::ValueType::IpFragmentOffset 55 } 56 ), 57 "Error '3' is too big to be a 'IP Fragment Offset' (maximum allowed value is '2')" 58 ); 59 } 60 61 #[test] dbg()62 fn dbg() { 63 assert_eq!( 64 format!( 65 "{:?}", 66 ValueTooBigError { 67 actual: 3, 68 max_allowed: 2, 69 value_type: err::ValueType::IpFragmentOffset 70 } 71 ), 72 format!( 73 "ValueTooBigError {{ actual: {}, max_allowed: {}, value_type: {:?} }}", 74 3, 75 2, 76 err::ValueType::IpFragmentOffset 77 ) 78 ); 79 } 80 81 #[test] clone_eq_hash()82 fn clone_eq_hash() { 83 let err = ValueTooBigError { 84 actual: 3, 85 max_allowed: 2, 86 value_type: err::ValueType::IpFragmentOffset, 87 }; 88 assert_eq!(err, err.clone()); 89 let hash_a = { 90 let mut hasher = DefaultHasher::new(); 91 err.hash(&mut hasher); 92 hasher.finish() 93 }; 94 let hash_b = { 95 let mut hasher = DefaultHasher::new(); 96 err.clone().hash(&mut hasher); 97 hasher.finish() 98 }; 99 assert_eq!(hash_a, hash_b); 100 } 101 102 #[cfg(feature = "std")] 103 #[test] source()104 fn source() { 105 assert!(ValueTooBigError { 106 actual: 3, 107 max_allowed: 2, 108 value_type: err::ValueType::IpFragmentOffset 109 } 110 .source() 111 .is_none()); 112 } 113 } 114