chinese_rand/
numeric.rs

1use crate::{ChineseFormatGenerator, InvalidLowerBound};
2use chinese_format::{Count, CountBase, Fraction};
3use std::ops::RangeInclusive;
4
5impl ChineseFormatGenerator {
6    /// Generates a random [i128] in the given range.
7    ///
8    /// ```
9    /// use chinese_rand::*;
10    ///
11    /// fastrand::seed(90);
12    /// let raw_generator = FastRandGenerator::new();
13    /// let generator = ChineseFormatGenerator::new(raw_generator);
14    ///
15    /// let integer = generator.integer(i128::MIN..=i128::MAX);
16    /// assert_eq!(integer, -139744823884027955216713073977120108615);
17    ///
18    /// let fixed = generator.integer(90..=90);
19    /// assert_eq!(fixed, 90);
20    /// ```
21    pub fn integer(&self, range: RangeInclusive<i128>) -> i128 {
22        self.raw_generator.i128(range)
23    }
24
25    /// Generates a [Fraction] having its components in the given ranges.
26    ///
27    /// The lower bound for the denominator cannot be 0, or the function
28    /// will fail with [InvalidLowerBound].
29    ///
30    /// ```
31    /// use chinese_rand::*;
32    /// use chinese_format::Fraction;
33    ///
34    /// # fn main() -> GenericResult<()> {
35    /// fastrand::seed(90);
36    /// let raw_generator = FastRandGenerator::new();
37    /// let generator = ChineseFormatGenerator::new(raw_generator);
38    ///
39    /// let fraction = generator.fraction(
40    ///     1..=u128::MAX,
41    ///     i128::MIN..=i128::MAX
42    /// )?;
43    /// assert_eq!(
44    ///     fraction,
45    ///     Fraction::try_new(
46    ///         200537543036910508246661533454648102841,
47    ///         -116432671981703681494469200238719654801
48    ///     )?
49    /// );
50    ///
51    /// let fixed = generator.fraction(5..=5, 4..=4)?;
52    /// assert_eq!(
53    ///     fixed,
54    ///     Fraction::try_new(5, 4)?
55    /// );
56    ///
57    /// let fraction_result = generator.fraction(0..=5, 4..=4);
58    /// assert_eq!(
59    ///     fraction_result,
60    ///     Err(InvalidLowerBound(0))
61    /// );
62    ///
63    /// # Ok(())
64    /// # }
65    /// ```
66    pub fn fraction(
67        &self,
68        denominator_range: RangeInclusive<u128>,
69        numerator_range: RangeInclusive<i128>,
70    ) -> Result<Fraction, InvalidLowerBound<u128>> {
71        if *denominator_range.start() == 0 {
72            return Err(InvalidLowerBound(0));
73        }
74
75        let denominator = self.raw_generator.u128(denominator_range);
76
77        let numerator = self.raw_generator.i128(numerator_range);
78
79        Ok(
80            Fraction::try_new(denominator, numerator)
81                .expect("Denominator non-zero by construction"),
82        )
83    }
84
85    /// Generates a random [Count] in the given range.
86    ///
87    /// ```
88    /// use chinese_rand::*;
89    /// use chinese_format::{Count, CountBase};
90    ///
91    /// fastrand::seed(90);
92    /// let raw_generator = FastRandGenerator::new();
93    /// let generator = ChineseFormatGenerator::new(raw_generator);
94    ///
95    /// let count = generator.count(0..=CountBase::MAX);
96    /// assert_eq!(count, Count(200537543036910508246661533454648102841));
97    ///
98    /// let fixed = generator.count(90..=90);
99    /// assert_eq!(fixed, Count(90));
100    /// ```
101    pub fn count(&self, range: RangeInclusive<CountBase>) -> Count {
102        Count(self.raw_generator.u128(range))
103    }
104}