synd_term/application/
direction.rs

1#[derive(Debug, PartialEq, Eq, Clone, Copy)]
2pub(crate) enum Direction {
3    Up,
4    Down,
5    Left,
6    Right,
7}
8
9#[derive(PartialEq, Eq, Clone, Copy, Debug)]
10pub(crate) enum IndexOutOfRange {
11    Wrapping,
12    #[allow(dead_code)]
13    Saturating,
14}
15
16impl Direction {
17    #[allow(
18        clippy::cast_sign_loss,
19        clippy::cast_possible_truncation,
20        clippy::cast_possible_wrap
21    )]
22    pub(crate) fn apply(self, index: usize, len: usize, out: IndexOutOfRange) -> usize {
23        if len == 0 {
24            return 0;
25        }
26        let diff = match self {
27            Direction::Up | Direction::Left => -1,
28            Direction::Down | Direction::Right => 1,
29        };
30
31        let index = index as i64;
32        if index + diff < 0 {
33            match out {
34                IndexOutOfRange::Wrapping => len - 1,
35                IndexOutOfRange::Saturating => 0,
36            }
37        } else if index + diff >= len as i64 {
38            match out {
39                IndexOutOfRange::Wrapping => 0,
40                IndexOutOfRange::Saturating => len - 1,
41            }
42        } else {
43            (index + diff) as usize
44        }
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use proptest::prelude::{prop_oneof, proptest, Just, ProptestConfig, Strategy};
52
53    proptest! {
54        #![proptest_config(ProptestConfig::default())]
55        #[test]
56        #[allow(clippy::cast_possible_wrap)]
57        fn apply(
58            dir in direction_strategy(),
59            index in 0..10_usize,
60            len in 0..10_usize,
61            out in index_out_of_range_strategy())
62        {
63            let apply = dir.apply(index, len,out) as i64;
64            let index = index as i64;
65            let len = len as i64;
66            assert!(
67                (apply - index).abs() == 1 ||
68                apply == 0 ||
69                apply == len-1
70            );
71        }
72
73
74    }
75    fn direction_strategy() -> impl Strategy<Value = Direction> {
76        prop_oneof![
77            Just(Direction::Up),
78            Just(Direction::Down),
79            Just(Direction::Left),
80            Just(Direction::Right),
81        ]
82    }
83
84    fn index_out_of_range_strategy() -> impl Strategy<Value = IndexOutOfRange> {
85        prop_oneof![
86            Just(IndexOutOfRange::Wrapping),
87            Just(IndexOutOfRange::Saturating)
88        ]
89    }
90}