nhs_number/
testable.rs

1use crate::NHSNumber;
2use rand::Rng;
3use std::ops::RangeInclusive;
4use std::sync::LazyLock;
5
6/// Get the NHS Number testable range minimum value.
7/// This number is valid but is never going to be issued.
8///
9/// Example:
10///
11/// ```rust
12/// use nhs_number::NHSNumber;
13/// use nhs_number::testable::TESTABLE_MIN;
14/// let nhs_number = NHSNumber { digits: [9, 9, 9, 0, 1, 2, 3, 4, 5, 6] };
15/// assert!(nhs_number >= *TESTABLE_MIN);
16/// ```
17///
18#[allow(dead_code)]
19pub static TESTABLE_MIN: LazyLock<NHSNumber> = LazyLock::new(|| NHSNumber {
20    digits: [9, 9, 9, 0, 0, 0, 0, 0, 0, 0],
21});
22
23/// Get the NHS Number testable range maximum value.
24/// This number is valid but is never going to be issued.
25///
26/// Example:
27///
28/// ```rust
29/// use nhs_number::NHSNumber;
30/// use nhs_number::testable::TESTABLE_MAX;
31/// let nhs_number = NHSNumber { digits: [9, 9, 9, 0, 1, 2, 3, 4, 5, 6] };
32/// assert!(nhs_number <= *TESTABLE_MAX);
33/// ```
34///
35#[allow(dead_code)]
36pub static TESTABLE_MAX: LazyLock<NHSNumber> = LazyLock::new(|| NHSNumber {
37    digits: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
38});
39
40/// Get the NHS Number testable range.
41/// This range is valid but is never going to be issued.
42///
43/// Example:
44/// ```rust
45///  use nhs_number::{NHSNumber, testable::*};
46/// let nhs_number = NHSNumber { digits: [9, 9, 9, 0, 1, 2, 3, 4, 5, 6] };
47///  assert!(TESTABLE_RANGE_INCLUSIVE.contains(&nhs_number));
48/// ```
49#[allow(dead_code)]
50pub static TESTABLE_RANGE_INCLUSIVE: LazyLock<RangeInclusive<NHSNumber>> =
51    LazyLock::new(|| RangeInclusive::new(*TESTABLE_MIN, *TESTABLE_MAX));
52
53/// Generate a NHS Number testable range random sample.
54/// The generated number is valid but is never going to be issued.
55///
56/// Example:
57///
58/// ```rust
59/// use nhs_number::{NHSNumber, testable::*};
60/// let nhs_number = testable_random_sample();
61/// assert!(nhs_number >= *TESTABLE_MIN);
62/// assert!(nhs_number <= *TESTABLE_MAX);
63/// ```
64///
65#[allow(dead_code)]
66pub fn testable_random_sample() -> NHSNumber {
67    let mut rng = rand::rng();
68    NHSNumber {
69        digits: [
70            9,
71            9,
72            9,
73            rng.random_range(0..=9) as i8,
74            rng.random_range(0..=9) as i8,
75            rng.random_range(0..=9) as i8,
76            rng.random_range(0..=9) as i8,
77            rng.random_range(0..=9) as i8,
78            rng.random_range(0..=9) as i8,
79            rng.random_range(0..=9) as i8,
80        ],
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn test_random() {
90        let a = testable_random_sample();
91        assert!(a >= *TESTABLE_MIN);
92        assert!(a <= *TESTABLE_MAX);
93    }
94}