use fake::faker;
use fake::{Fake, Faker};
use rand::Rng;
use serde_derive::{Deserialize, Serialize};
use std::ops::Add;
use uuid;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum RandomData {
FirstName,
LastName,
FullName,
Email,
Number {
digits: usize,
},
NumberBetween {
min: usize,
max: usize,
},
Paragraphs {
amount: Option<usize>,
},
Paragraph,
Sentences {
amount: Option<usize>,
},
Sentence,
Company,
City,
StreetAddress,
Latitude,
Longitude,
LatLong,
LongLat,
GeoPoint,
Postcode,
FullAddress,
UUID4,
PhoneNumber,
LoremPicsum {
width: Option<usize>,
height: Option<usize>,
grayscale: Option<bool>,
},
NullValue,
String {
content: String,
},
Reference {
model: String,
field: String,
},
}
impl RandomData {
pub fn into_data(self) -> String {
generate_fake_data(self)
}
}
impl std::string::ToString for RandomData {
fn to_string(&self) -> String {
self.clone().into_data()
}
}
fn number_with_length(length: usize) -> String {
let mut random = rand::thread_rng();
let mut buffer = String::with_capacity(length);
buffer = buffer + &format!("{}", random.gen_range(1, 10));
for _ in 0..length - 1 {
buffer = buffer + &format!("{}", random.gen_range(0, 10));
}
buffer
}
#[test]
fn generate_number_format_of_correct_length() {
assert_eq!(number_with_length(1).len(), 1);
assert_eq!(number_with_length(2).len(), 2);
assert_eq!(number_with_length(10).len(), 10);
assert_eq!(number_with_length(1000).len(), 1000);
}
pub fn generate_fake_data(spec: RandomData) -> String {
match spec {
RandomData::FirstName => format!("{}", faker::name::en::FirstName().fake::<String>()),
RandomData::LastName => format!("{}", faker::name::en::LastName().fake::<String>()),
RandomData::FullName => format!("{}", faker::name::en::Name().fake::<String>()),
RandomData::Email => format!("{}", faker::internet::en::SafeEmail().fake::<String>()),
RandomData::Number { digits } => format!("{}", number_with_length(digits)),
RandomData::NumberBetween { min, max } => {
format!("{}", rand::thread_rng().gen_range(min, max))
}
RandomData::Paragraph => faker::lorem::en::Paragraph(1..2).fake::<String>(),
RandomData::Paragraphs { amount } => {
let val = amount.unwrap_or(1usize);
format!(
"{}",
faker::lorem::en::Paragraph(val..val + 1).fake::<String>()
)
}
RandomData::Sentence => faker::lorem::en::Sentence(1..2).fake::<String>(),
RandomData::Sentences { amount } => {
let val = amount.unwrap_or(1usize);
format!(
"{}",
faker::lorem::en::Sentence(val..val + 1).fake::<String>()
)
}
RandomData::Company => format!("{}", faker::company::en::CompanyName().fake::<String>()),
RandomData::City => format!("{}", faker::address::en::CityName().fake::<String>()),
RandomData::StreetAddress => {
format!("{}", faker::address::en::StreetName().fake::<String>())
}
RandomData::Latitude => format!("{}", faker::address::en::Latitude().fake::<String>()),
RandomData::Longitude => format!("{}", faker::address::en::Longitude().fake::<String>()),
RandomData::LatLong => format!(
r#"[{}, {}]"#,
faker::address::en::Latitude().fake::<String>(),
faker::address::en::Longitude().fake::<String>()
),
RandomData::LongLat => format!(
r#"[{}, {}]"#,
faker::address::en::Longitude().fake::<String>(),
faker::address::en::Latitude().fake::<String>()
),
RandomData::GeoPoint => format!(
r#"POINT({} {})"#,
faker::address::en::Longitude().fake::<String>(),
faker::address::en::Latitude().fake::<String>()
),
RandomData::Postcode => format!("{}", faker::address::en::PostCode().fake::<String>()),
RandomData::FullAddress => format!(
"{}, {}, {}",
faker::address::en::StreetName().fake::<String>(),
faker::address::en::CityName().fake::<String>(),
faker::address::en::PostCode().fake::<String>()
),
RandomData::UUID4 => format!("{}", uuid::Uuid::new_v4()),
RandomData::PhoneNumber => format!(
"{}",
faker::phone_number::en::PhoneNumber().fake::<String>()
),
RandomData::LoremPicsum {
width,
height,
grayscale,
} => format!(
"https://picusm.photos/{}{}/{}",
if grayscale.unwrap_or(false) { "g/" } else { "" },
width.unwrap_or(200),
height.unwrap_or(200)
),
RandomData::NullValue => format!("null"),
RandomData::String { content } => content.clone(),
RandomData::Reference { .. } => format!("null"),
}
}