random_nickname2/
lib.rs

1mod names;
2
3use rand::{rngs::ThreadRng, rng, Rng};
4use std::{
5    cell::RefCell,
6    fmt::{Display, Formatter},
7    sync::LazyLock,
8};
9
10const THREAD_RNG: LazyLock<RefCell<ThreadRng>> = LazyLock::new(|| RefCell::new(rng()));
11
12/// 性别枚举
13#[derive(Copy, Clone, Debug)]
14pub enum Gender {
15    /// 男性
16    Male,
17    /// 女性
18    Female,
19    /// 间性
20    Intersex,
21}
22
23/// 生成时可能发生的错误信息
24#[derive(Debug)]
25pub struct GenError(String);
26
27impl Display for GenError {
28    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29        write!(f, "{}", self.0)
30    }
31}
32
33/// 生成一个随机名字。
34///
35/// 根据指定的性别和名字长度生成一个名字。如果名字长度为0,则不限制长度。
36///
37/// # 参数
38///
39/// * `gender` - 指定的性别,可以是`Gender::Male`、`Gender::Female`或`Gender::Intersex`。
40/// * `LEN` - 名字的长度,可以是任意正整数或0。
41///
42/// # 返回值
43///
44/// 返回一个`Result`类型,成功时包含一个静态字符串切片,表示生成的名字;失败时包含一个`GenError`,表示生成名字时可能出现的错误。
45///
46/// # 示例
47///
48/// ```
49/// use random_nickname2::{ random, Gender };
50///
51/// match random::<4>(Gender::Female) {
52///     Ok(name) => println!("生成的名字是: {}", name),
53///     Err(e) => println!("生成名字时出错: {}", e),
54/// }
55/// ```
56///
57/// # 错误处理
58///
59/// 如果没有符合条件的名字,将返回一个`GenError`,其中包含错误信息。
60///
61pub fn random<const LEN: usize>(gender: Gender) -> Result<&'static str, GenError> {
62    use names::NAMES;
63    let data = NAMES
64        .iter()
65        .filter_map(move |(name, gender2)| match (gender, gender2) {
66            (Gender::Male, 0) | (Gender::Female, 1) | (Gender::Intersex, _)
67                if LEN > 0 && LEN == name.chars().collect::<Vec<_>>().len() || LEN <= 0 =>
68            {
69                Some(name)
70            }
71            _ => None,
72        })
73        .collect::<Vec<_>>();
74    if data.is_empty() {
75        return Err(GenError(format!("No result for {:?}: len {}", gender, LEN)));
76    }
77    let index = THREAD_RNG.borrow_mut().random_range(0..data.len());
78    Ok(data[index])
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn it_works() {
87        assert!(random::<1>(Gender::Female).is_ok());
88        assert!(random::<2>(Gender::Female).is_ok());
89        assert!(random::<3>(Gender::Female).is_ok());
90        assert!(random::<4>(Gender::Female).is_ok());
91        assert!(random::<1>(Gender::Male).is_ok());
92        assert!(random::<2>(Gender::Male).is_ok());
93        assert!(random::<3>(Gender::Male).is_ok());
94        assert!(random::<4>(Gender::Male).is_ok());
95    }
96}