dataforge/generation/
mod.rs

1pub mod custom;
2pub mod generators;
3
4use std::collections::HashMap;
5use serde_json::Value;
6use crate::error::{DataForgeError, Result};
7
8// 核心生成器 Trait
9pub trait Generator: Send + Sync {
10    fn generate(&self) -> Value;
11}
12
13// 类型别名简化复杂类型
14type CustomGenerator = Box<dyn Fn() -> Value + Send + Sync>;
15
16// 数据生成器注册表
17#[derive(Default)]
18pub struct DataForge {
19    generators: HashMap<&'static str, CustomGenerator>,
20    lang: Language,
21}
22
23#[derive(Debug, Clone, Copy, Default)]
24pub enum Language {
25    #[default]
26    ZhCN,
27    EnUS,
28    JaJP,
29}
30
31impl DataForge {
32    /// 创建新的数据生成器实例
33    pub fn new(lang: Language) -> Self {
34        let mut df = Self {
35            generators: HashMap::new(),
36            lang,
37        };
38        df.register_builtin_generators();
39        df
40    }
41
42    /// 注册内置生成器
43    fn register_builtin_generators(&mut self) {
44        // 基础生成器
45        self.generators.insert("uuid_v4", Box::new(|| Value::String(crate::generators::uuid_v4())));
46        self.generators.insert("zh_cn_name", Box::new(|| Value::String(crate::generators::name::zh_cn_fullname())));
47        self.generators.insert("en_name", Box::new(|| Value::String(crate::generators::name::en_us_fullname())));
48        self.generators.insert("email", Box::new(|| Value::String(crate::generators::internet::email())));
49        self.generators.insert("datetime_now", Box::new(|| Value::String(crate::generators::datetime::iso8601())));
50        self.generators.insert("date_now", Box::new(|| Value::String(crate::generators::datetime::date_iso())));
51        self.generators.insert("province", Box::new(|| crate::regions::china::province()));
52        
53        // 数字生成器
54        self.generators.insert("random_int", Box::new(|| Value::Number(serde_json::Number::from(crate::generators::random_int(0, 1000)))));
55        self.generators.insert("random_float", Box::new(|| Value::Number(serde_json::Number::from_f64(crate::generators::random_float(0.0, 100.0)).unwrap())));
56        self.generators.insert("random_bool", Box::new(|| Value::Bool(crate::generators::random_bool())));
57        
58        // 姓名生成器
59        self.generators.insert("en_first_name", Box::new(|| Value::String(crate::generators::name::en_first_name())));
60        self.generators.insert("en_last_name", Box::new(|| Value::String(crate::generators::name::en_last_name())));
61        
62        // 电话号码生成器
63        self.generators.insert("phone_cn", Box::new(|| Value::String(crate::generators::number::phone_number_cn())));
64        
65        // URL生成器
66        self.generators.insert("url", Box::new(|| Value::String(crate::generators::internet::url())));
67        
68        // 日期生成器
69        self.generators.insert("random_date", Box::new(|| Value::String(crate::generators::datetime::random_date_between("2000-01-01", "2023-12-31"))));
70    }
71
72    /// 生成数据
73    pub fn generate(&self, generator_name: &str) -> Option<Value> {
74        self.generators.get(generator_name).map(|gen| gen())
75    }
76
77    /// 注册自定义生成器
78    pub fn register<F>(&mut self, name: &'static str, generator: F)
79    where
80        F: Fn() -> Value + Send + Sync + 'static,
81    {
82        self.generators.insert(name, Box::new(generator));
83    }
84
85    /// 获取当前语言设置
86    pub fn language(&self) -> Language {
87        self.lang
88    }
89
90    /// 设置语言
91    pub fn set_language(&mut self, lang: Language) {
92        self.lang = lang;
93    }
94
95    /// 批量生成数据
96    pub fn generate_batch(&self, generator_name: &str, count: usize) -> Result<Vec<Value>> {
97        let generator = self.generators.get(generator_name)
98            .ok_or_else(|| DataForgeError::generator(format!("Generator '{}' not found", generator_name)))?;
99        
100        Ok((0..count).map(|_| generator()).collect())
101    }
102}
103
104impl Language {
105    /// 获取语言代码
106    pub fn code(&self) -> &'static str {
107        match self {
108            Language::ZhCN => "zh-CN",
109            Language::EnUS => "en-US", 
110            Language::JaJP => "ja-JP",
111        }
112    }
113}