1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use crate::datatypes::RandomData;

use serde_derive::{Deserialize, Serialize};
use std::collections::HashMap;
use std::string::ToString;

type Map<T> = HashMap<String, T>;
type GeneratedProperties = Map<String>;
type GeneratedModels = Map<GeneratedProperties>;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Model(pub HashMap<String, RandomData>);

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelMap {
	serialize: HashMap<String, Vec<String>>,
	models: HashMap<String, Model>,
}

impl Model {
	pub fn new() -> Self {
		Model(HashMap::new())
	}

	pub fn add_property<TS>(&mut self, name: TS, definition: RandomData) -> &mut Self
	where
		TS: ToString,
	{
		self.0.insert(name.to_string(), definition);
		self
	}
	pub fn get_property(&self, name: String) -> Option<&RandomData> {
		self.0.get(&name)
	}
	pub fn generate_data(&self) -> GeneratedProperties {
		let mut generated = HashMap::with_capacity(self.0.len());
		for (name, generator) in &self.0 {
			generated.insert(name.clone(), generator.to_string());
		}

		generated
	}
	/// Returns a list of types in this model that reference other models. The [RandomData] in the tuple will always
	/// be a [RandomData::Reference] type
	pub fn get_reference_types(&self) -> Vec<(String, RandomData)> {
		self.0
			.iter()
			.filter_map(|(key, value)| match value {
				RandomData::Reference { .. } => Some((key.to_string(), value.clone())),
				_ => None,
			})
			.collect()
	}
}

pub mod io {
	use crate::model::ModelMap;

	use serde_json::from_str;
	use std::fs::read_to_string;
	use std::io::{Error, Result};
	use std::path::Path;

	pub fn read_from_spec<P>(path: P) -> Result<ModelMap>
	where
		P: AsRef<Path>,
	{
		let file = read_to_string(path.as_ref())?;
		from_str(&file).map_err(|e| Error::from(e))
	}
	//    pub fn _write_to_spec<P>(model: ModelMap, path: P) -> Result<()> where P: AsRef<Path> {
	//        let output = to_string(&model);
	//        println!("{:?}", output);
	//        Ok(())
	//    }
}

impl ModelMap {
	pub fn new() -> Self {
		ModelMap {
			serialize: HashMap::new(),
			models: HashMap::new(),
		}
	}

	pub fn add_model<TS>(&mut self, name: TS, model: Model) -> &mut Self
	where
		TS: ToString,
	{
		self.models.insert(name.to_string(), model);
		self
	}
	pub fn get_model(&self, name: String) -> Option<&Model> {
		self.models.get(&name)
	}
	pub fn generate_data(&self) -> GeneratedModels {
		let mut generated = HashMap::with_capacity(self.models.len());
		for (name, model) in &self.models {
			generated.insert(name.clone(), model.generate_data());
		}

		generated
	}
	pub fn get_models_ref(&self) -> &HashMap<String, Model> {
		&self.models
	}
	pub fn get_serialize_ref(&self) -> &HashMap<String, Vec<String>> {
		&self.serialize
	}
}

#[test]
fn generate_random_data() {
	use crate::datatypes::RandomData;
	use crate::model::Model;

	let mut model = Model::new();

	model
		.add_property("name".to_owned(), RandomData::FullName)
		.add_property("email".to_owned(), RandomData::Email);

	println!("Random user: {:?}", model.generate_data());
}