1use is_sorted::IsSorted;
11use itertools::Itertools;
12use std::fmt;
13
14#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
16pub enum InvalidPositions {
17 Unsorted,
18 OutOfBound,
19 Duplicated,
20}
21
22impl fmt::Display for InvalidPositions {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 match self {
25 InvalidPositions::Unsorted => "some positions are not sorted".fmt(f),
26 InvalidPositions::OutOfBound => "some positions are out of bound".fmt(f),
27 InvalidPositions::Duplicated => "some positions are duplicated".fmt(f),
28 }
29 }
30}
31
32impl std::error::Error for InvalidPositions {}
33
34pub(crate) fn validate_positions(
35 length: usize,
36 positions: &[usize],
37) -> Result<(), InvalidPositions> {
38 for position in positions.iter() {
39 if *position >= length {
40 return Result::Err(InvalidPositions::OutOfBound);
41 }
42 }
43 if !IsSorted::is_sorted(&mut positions.iter()) {
44 return Result::Err(InvalidPositions::Unsorted);
45 }
46 if positions.iter().unique().count() != positions.len() {
47 return Result::Err(InvalidPositions::Duplicated);
48 }
49 Ok(())
50}
51
52#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
55pub struct IncompatibleDimensions<DL, DR> {
56 left_dimensions: DL,
57 right_dimensions: DR,
58}
59
60impl<DL, DR> IncompatibleDimensions<DL, DR> {
61 pub fn new(left_dimensions: DL, right_dimensions: DR) -> Self {
62 Self {
63 left_dimensions,
64 right_dimensions,
65 }
66 }
67}
68
69pub type VecVecIncompatibleDimensions = IncompatibleDimensions<usize, usize>;
70pub type MatVecIncompatibleDimensions = IncompatibleDimensions<(usize, usize), usize>;
71pub type VecMatIncompatibleDimensions = IncompatibleDimensions<usize, (usize, usize)>;
72pub type MatMatIncompatibleDimensions = IncompatibleDimensions<(usize, usize), (usize, usize)>;
73
74macro_rules! impl_dim_error {
75 ($dl:ty, $dr:ty) => {
76 impl fmt::Display for IncompatibleDimensions<$dl, $dr> {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 format!(
79 "incompatible dimensions {:?} and {:?}",
80 self.left_dimensions, self.right_dimensions
81 )
82 .fmt(f)
83 }
84 }
85
86 impl std::error::Error for IncompatibleDimensions<$dl, $dr> {}
87 };
88}
89
90impl_dim_error!(usize, usize); impl_dim_error!((usize, usize), usize); impl_dim_error!(usize, (usize, usize)); impl_dim_error!((usize, usize), (usize, usize));