1use core::{
2 error::Error,
3 fmt::{self, Debug},
4};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct LengthOutOfRange {
9 len: usize,
11 min: u32,
13 max: u32,
15}
16
17impl LengthOutOfRange {
18 #[cfg(feature = "image")]
19 #[inline]
20 pub(crate) fn check_dimensions(width: u32, height: u32) -> Result<u32, Self> {
21 if let Some(len) = width.checked_mul(height) {
22 Ok(len)
23 } else {
24 Err(Self {
25 len: width as usize * height as usize,
26 min: 0,
27 max: crate::MAX_PIXELS,
28 })
29 }
30 }
31
32 #[inline]
33 pub(crate) const fn check_u32<T>(slice: &[T], min: u32, max: u32) -> Result<u32, Self> {
34 let len = slice.len();
35 #[allow(clippy::cast_possible_truncation)]
36 if min as usize <= len && len <= max as usize {
37 Ok(len as u32)
38 } else {
39 Err(Self { len, min, max })
40 }
41 }
42
43 #[inline]
44 pub(crate) const fn check_u16<T>(slice: &[T], min: u16, max: u16) -> Result<u16, Self> {
45 let len = slice.len();
46 #[allow(clippy::cast_possible_truncation)]
47 if min as usize <= len && len <= max as usize {
48 Ok(len as u16)
49 } else {
50 Err(Self { len, min: min as u32, max: max as u32 })
51 }
52 }
53}
54
55impl fmt::Display for LengthOutOfRange {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 let Self { len, min, max } = *self;
58 if min == 0 {
59 write!(
60 f,
61 "got an input with length {len} which is above the maximum {max}",
62 )
63 } else {
64 write!(
65 f,
66 "got an input with length {len} which is not in the supported range of {min}..={max}",
67 )
68 }
69 }
70}
71
72impl Error for LengthOutOfRange {}