1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use rand::Rng;
use std::ops::Range;

/// A random value or a static value
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RandOrStatic {
    /// A random value in the given range, [start, end).
    Rand { start: usize, end: usize },

    /// A static value, as given.
    Static { value: usize },
}

impl RandOrStatic {
    /// Generate a num if rng using the given rng,
    /// or return the static value.
    pub(crate) fn generate_num<R>(self, mut rng: R) -> usize
    where
        R: Rng,
    {
        match self {
            Self::Rand { start, end } => rng.gen_range(start..end),
            Self::Static { value } => value,
        }
    }
}

impl From<Range<usize>> for RandOrStatic {
    fn from(range: Range<usize>) -> Self {
        RandOrStatic::Rand {
            start: range.start,
            end: range.end,
        }
    }
}

impl From<(usize, usize)> for RandOrStatic {
    fn from((start, end): (usize, usize)) -> Self {
        RandOrStatic::Rand { start, end }
    }
}

impl From<usize> for RandOrStatic {
    fn from(value: usize) -> Self {
        RandOrStatic::Static { value }
    }
}