pub mod basic;
pub mod pattern;
pub mod registry;
pub mod specialized;
pub mod traits;
pub use registry::FieldGeneratorRegistry;
pub use traits::{FieldGenerator, FieldGeneratorFactory};
use crate::Result;
use crate::config::{DataQuality, FieldGeneratorConfig};
use serde_json::Value;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct GenerationContext {
pub property: String,
pub datatype: String,
pub subject: String,
pub parameters: HashMap<String, Value>,
pub quality: DataQuality,
pub locale: String,
}
impl GenerationContext {
pub fn new(property: String, datatype: String, subject: String) -> Self {
Self {
property,
datatype,
subject,
parameters: HashMap::new(),
quality: DataQuality::Medium,
locale: "en".to_string(),
}
}
pub fn with_quality(mut self, quality: DataQuality) -> Self {
self.quality = quality;
self
}
pub fn with_locale(mut self, locale: String) -> Self {
self.locale = locale;
self
}
pub fn with_parameter<K: Into<String>, V: Into<Value>>(mut self, key: K, value: V) -> Self {
self.parameters.insert(key.into(), value.into());
self
}
}
pub struct FieldGenerationManager {
registry: FieldGeneratorRegistry,
config: FieldGeneratorConfig,
}
impl FieldGenerationManager {
pub fn new(config: FieldGeneratorConfig) -> Result<Self> {
let mut registry = FieldGeneratorRegistry::new();
registry.register_default_generators()?;
Ok(Self { registry, config })
}
pub fn generate_field(&self, context: &GenerationContext) -> Result<String> {
if let Some(prop_config) = self.config.properties.get(&context.property) {
let generator = self.registry.get_generator(&prop_config.generator)?;
let mut gen_context = context.clone();
for (key, value) in &prop_config.parameters {
gen_context.parameters.insert(key.clone(), value.clone());
}
return generator.generate(&gen_context);
}
if let Some(datatype_config) = self.config.datatypes.get(&context.datatype) {
let generator = self.registry.get_generator(&datatype_config.generator)?;
let mut gen_context = context.clone();
for (key, value) in &datatype_config.parameters {
gen_context.parameters.insert(key.clone(), value.clone());
}
return generator.generate(&gen_context);
}
let generator = self.registry.get_default_generator(&context.datatype)?;
generator.generate(context)
}
pub async fn generate_fields_parallel(
&self,
contexts: Vec<GenerationContext>,
) -> Result<Vec<String>> {
use rayon::prelude::*;
let results: Result<Vec<String>> = contexts
.into_par_iter()
.map(|context| self.generate_field(&context))
.collect();
results
}
}