random_data/
data.rs

1mod computational;
2mod raw;
3extern crate alloc;
4use crate::generator::DataGenerator;
5use alloc::fmt;
6use rand::RngCore;
7
8#[allow(unused_imports, reason = "minimal feature doesn't use this")]
9use rand::seq::IndexedRandom as _;
10
11macro_rules! strings {
12    ($($fn_module:ident, $fn_feature:literal, $fn_variant:ident, $fn_func:ident)*;  $($list_module:ident, $list_feature:literal, $list_variant:ident, $list_const:ident)*) => {
13
14
15        /// Representation of type that can be generated randomly.
16        ///
17        /// There are two types of generated data: some are hard-coded with a list of possible
18        /// values, others are produced by formulas. Both are usable the same way. If you don't
19        /// want to load all the possible values for all the types, you can choose to enable
20        /// the data types you want (all features are enabled by default).
21        ///
22        /// # Examples
23        ///
24        /// ```
25        /// use random_data::*;
26        /// let mut generator = DataGenerator::default();
27        ///
28        /// #[cfg(feature = "datetime")]
29        /// {
30        ///     let random_month = DataType::Month.random(&mut generator);
31        ///     println!("{random_month}");
32        /// }
33        ///
34        /// #[cfg(feature = "address")]
35        /// {
36        ///     let random_address = DataType::Address.random(&mut generator);
37        ///     println!("{random_address}");
38        /// }
39        /// ```
40        #[non_exhaustive]
41        #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
42        #[allow(clippy::arbitrary_source_item_ordering, reason="ordered by type")]
43        #[allow(missing_docs, reason="macro produced")]
44        pub enum DataType {
45            $(
46                #[cfg(feature = $fn_feature)]
47                $fn_variant,
48            )*
49            $(
50                #[cfg(feature = $list_feature)]
51                $list_variant,
52            )*
53        }
54
55        impl DataType {
56            const STRINGS_LIST: &[&str] = &[
57                $(
58                    #[cfg(feature = $fn_feature)]
59                    stringify!($fn_variant),
60                )*
61                $(
62                    #[cfg(feature = $list_feature)]
63                    stringify!($list_variant),
64                )*
65            ];
66
67            const TYPES_LIST: &[Self] = &[
68                $(
69                    #[cfg(feature = $fn_feature)]
70                    Self::$fn_variant,
71                )*
72                $(
73                    #[cfg(feature = $list_feature)]
74                    Self::$list_variant,
75                )*
76            ];
77
78
79            /// Generate a random value of the according [`DataType`]
80            ///
81            /// # Examples
82            ///
83            /// ```
84            /// use random_data::*;
85            /// let mut generator = DataGenerator::default();
86            ///
87            /// #[cfg(feature = "science")]
88            /// {
89            ///     let random_address = DataType::ChemicalElement.random(&mut generator);
90            ///     println!("{random_address}");
91            /// }
92            /// ```
93            pub fn random<Rng: RngCore>(&self, generator: &mut DataGenerator<Rng>) -> String {
94                match self {
95                    $(
96                        #[cfg(feature = $fn_feature)]
97                        DataType::$fn_variant => crate::data::computational::$fn_module::$fn_func(generator),
98                    )*
99                    $(
100                        #[cfg(feature = $list_feature)]
101                        DataType::$list_variant => (crate::data::raw::$list_module::$list_const).choose(generator.rng()).unwrap().to_string(),
102                    )*
103                }
104            }
105
106            /// Returns the list of possible values of a data type if applicable
107            ///
108            /// # Returns
109            ///
110            /// - Some if the data type is defined by a list of values
111            /// - None if it is generated from a formula
112            ///
113            /// # Examples
114            ///
115            /// ```
116            /// use random_data::*;
117            /// let mut generator = DataGenerator::default();
118            ///
119            /// #[cfg(feature = "people")]
120            /// {
121            ///     let mathematician = DataType::Mathematician.random(&mut generator);
122            ///     let mathematicians = DataType::Mathematician.values().unwrap();
123            ///     assert!(mathematicians.contains(&mathematician.as_ref()));
124            /// }
125            ///
126            /// #[cfg(feature = "personal")]
127            /// assert!(DataType::Email.values().is_none());
128            /// ```
129            #[must_use]
130            #[allow(unreachable_patterns, reason="features")]
131            pub const fn values(&self) -> Option<&'static[&'static str]> {
132                match self {
133                    $(
134                        #[cfg(feature = $list_feature)]
135                        Self::$list_variant => Some(&crate::data::raw::$list_module::$list_const),
136                    )*
137                        _ => None
138                }
139            }
140
141        }
142
143        impl TryFrom<&str> for DataType {
144            type Error = ();
145
146            fn try_from(value: &str) -> Result<Self, ()> {
147                match value {
148                    $(
149                        #[cfg(feature = $fn_feature)]
150                        stringify!($fn_variant) => Ok(Self::$fn_variant),
151                    )*
152                    $(
153                        #[cfg(feature = $list_feature)]
154                        stringify!($list_variant) => Ok(Self::$list_variant),
155                    )*
156                    _ => Err(())
157
158                }
159            }
160        }
161
162    };
163}
164
165impl DataType {
166    /// List of all the available data types.
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// use random_data::*;
172    ///
173    /// #[cfg(feature = "computer")]
174    /// assert!(DataType::list().contains(&DataType::DirPath));
175    /// ```
176    #[must_use]
177    pub const fn list() -> &'static [Self] {
178        Self::TYPES_LIST
179    }
180
181    /// List of all the available data types, in string format.
182    ///
183    /// # Examples
184    ///
185    /// ```
186    /// use random_data::*;
187    ///
188    /// #[cfg(feature = "sky_space")]
189    /// assert!(DataType::list_str().contains(&"TypesOfCloud"));
190    /// ```
191    #[must_use]
192    pub const fn list_str() -> &'static [&'static str] {
193        Self::STRINGS_LIST
194    }
195}
196
197#[allow(clippy::use_debug, reason = "fine here")]
198#[allow(clippy::min_ident_chars, reason = "follow trait naming pattern")]
199impl fmt::Display for DataType {
200    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201        write!(f, "{self:?}")
202    }
203}
204
205impl TryFrom<&String> for DataType {
206    type Error = ();
207
208    fn try_from(value: &String) -> Result<Self, Self::Error> {
209        Self::try_from(value.as_str())
210    }
211}
212
213strings!(
214// cd src/data/computational && ls | while read f; do cat $f | grep '^pub fn' | tr '(' ' ' | awk '{print $3}' | sort | while read l; do echo "$f, $(caseify -p "$l"), $l"; done; done
215address, "address", Address, address
216address, "address", FrenchAddress, french_address
217address, "address", FrenchPostCode, french_post_code
218address, "address", FrenchStreet, french_street_name
219address, "address", Latitude, latitude
220address, "address", LatitudeLongitude, latitude_longitude
221address, "address", Longitude, longitude
222address, "address", StreetNumber, street_number
223address, "address", UkAddress, uk_address
224address, "address", UkPostCode, uk_post_code
225colour, "minimal", HexColour, hex_colour
226colour, "minimal", HslaColour, hsla_colour
227colour, "minimal", HslColour, hsl_colour
228colour, "minimal", RgbaColour, rgba_colour
229colour, "minimal", RgbColour, rgb_colour
230computer, "computer", DirPath, dir_path
231computer, "computer", FileName, file_name
232computer, "computer", FilePath, file_path
233computer, "computer", Ipv4, ipv4
234computer, "computer", Ipv6, ipv6
235computer, "computer", MacAddress, mac_address
236computer, "computer", Semver, semver
237computer, "computer", SemverStable, semver_stable
238computer, "computer", SemverUnstable, semver_unstable
239finance, "finance", Bic, bic
240finance, "finance", Iban, iban
241finance, "finance", Isin, isin
242isbn, "minimal", RandomIsbn10, random_isbn10
243isbn, "minimal", RandomIsbn13, random_isbn13
244people, "people", FamousPerson, famous_person
245personal, "personal", CreditCard, credit_card
246personal, "personal", Email, email
247personal, "personal", FrenchEmail, french_email
248personal, "personal", FrenchLicencePlate, french_licence_plate
249personal, "personal", FrenchPhoneNumber, french_phone_number
250personal, "personal", NhsNumber, nhs_number
251personal, "personal", Password, password
252personal, "personal", PhoneNumber, phone_number
253personal, "personal", SecuriteSociale, securite_sociale
254personal, "personal", UkLicencePlate, uk_licence_plate
255personal, "personal", UkPhoneNumber, uk_phone_number
256primitives, "minimal", AlphanumericCapitalChar, alphanumeric_capital_char
257primitives, "minimal", AlphanumericChar, alphanumeric_char
258primitives, "minimal", Boolean, boolean
259primitives, "minimal", CapitalChar, capital_char
260primitives, "minimal", Digit, digit
261primitives, "minimal", LowerChar, lower_char
262primitives, "minimal", Number, number
263text, "text", Sentence, sentence
264text, "text", Paragraph, paragraph
265;
266// cd src/data/raw && ls | while read f; do cat $f | grep '^pub const' | tr ':' ' ' | awk '{print $3}' | while read l; do echo "$f, $(caseify -p $l), $l" | sed 's/\.rs//;s/\( .*s\), /\1, /'; done  ; done
267animals, "animals", Animal, ANIMALS
268animals, "animals", Mammal, MAMMALS
269animals, "animals", Bird, BIRDS
270animals, "animals", Insect, INSECTS
271animals, "animals", Fishe, FISHES
272animals, "animals", Amphibian, AMPHIBIANS
273animals, "animals", Reptile, REPTILES
274animals, "animals", Mollusc, MOLLUSC
275animals, "animals", AnimalType, ANIMAL_TYPES
276animals, "animals", MythologicalCreature, MYTHOLOGICAL_CREATURES
277art, "art", LiteraryGenre, LITERARY_GENRES
278art, "art", ArchitecturalStyle, ARCHITECTURAL_STYLES
279art, "art", MusicalGenre, MUSICAL_GENRES
280art, "art", MusicalInstrument, MUSICAL_INSTRUMENTS
281colours, "colours", ColourName, COLOUR_NAMES
282currencies, "currencies", CurrencyName, CURRENCY_NAMES
283currencies, "currencies", CurrencySymbol, CURRENCY_SYMBOLS
284currencies, "currencies", CurrencyCode, CURRENCY_CODES
285datetime, "datetime", DaysOfWeek, DAYS_OF_WEEK
286datetime, "datetime", Month, MONTHS
287datetime, "datetime", DaysOfWeekAbbr, DAYS_OF_WEEK_ABBR
288datetime, "datetime", MonthsAbbr, MONTHS_ABBR
289datetime, "datetime", TimeZone, TIME_ZONES
290datetime, "datetime", TimeUnit, TIME_UNITS
291datetime, "datetime", AmPm, AM_PM
292education, "education", SchoolSubject, SCHOOL_SUBJECTS
293education, "education", AcademicDiscipline, ACADEMIC_DISCIPLINES
294education, "education", DegreesTitle, DEGREES_TITLES
295education, "education", University, UNIVERSITIES
296education, "education", Sport, SPORTS
297france, "france", FamousFrenchStreet, FRENCH_STREETS
298france, "france", FrenchRoadType, FRENCH_ROAD_TYPES
299france, "france", FrenchCounty, FRENCH_COUNTIES
300france, "france", FrenchRiver, FRENCH_RIVERS
301history, "history", HistoricalBattle, HISTORICAL_BATTLES
302internet, "internet", EmailDomain, EMAIL_DOMAINS
303internet, "internet", OpenSourceApp, OPEN_SOURCE_APPS
304internet, "internet", TopLevelDomain, TOP_LEVEL_DOMAINS
305internet, "internet", UserAgent, USER_AGENTS
306internet, "internet", HttpStatusCode, HTTP_STATUS_CODES
307internet, "internet", MimeType, MIME_TYPES
308names, "names", NameTitle, NAME_TITLES
309names, "names", FirstName, FIRST_NAMES
310names, "names", FrenchFirstName, FRENCH_FIRST_NAMES
311names, "names", FrenchLastName, FRENCH_LAST_NAMES
312names, "names", LastName, LAST_NAMES
313people, "people", Painter, PAINTERS
314people, "people", Writer, WRITERS
315people, "people", Composer, COMPOSERS
316people, "people", Mathematician, MATHEMATICIANS
317people, "people", Physician, PHYSICIANS
318people, "people", Biologist, BIOLOGISTS
319people, "people", ComputerScientist, COMPUTER_SCIENTISTS
320people, "people", Philosopher, PHILOSOPHERS
321computer, "computer", ProgrammingLanguage, PROGRAMMING_LANGUAGES
322computer, "computer", ProgrammingParadigm, PROGRAMMING_PARADIGMS
323computer, "computer", EditorColourTheme, EDITOR_COLOUR_THEMES
324computer, "computer", ItDomain, IT_DOMAINS
325computer, "computer", FileExtension, FILE_EXTENSIONS
326science, "science", ChemicalElement, CHEMICAL_ELEMENTS
327science, "science", MathematicalFunction, MATHEMATICAL_FUNCTIONS
328sky_space, "sky_space", TypesOfCloud, TYPES_OF_CLOUDS
329sky_space, "sky_space", Constellation, CONSTELLATIONS
330sky_space, "sky_space", Planet, PLANETS
331sky_space, "sky_space", Star, STARS
332sky_space, "sky_space", Galaxy, GALAXIES
333uk, "uk", UkCountyCode, UK_COUNTY_CODES
334uk, "uk", UkPostcodeArea, UK_POSTCODE_AREAS
335uk, "uk", UkCounty, UK_COUNTIES
336uk, "uk", UkCity, UK_CITIES
337uk, "uk", UkRoadType, UK_ROAD_TYPES
338uk, "uk", UkRiver, UK_RIVERS
339uk, "uk", UkStreet, UK_STREETS
340us, "us", UsStateAbbr, US_STATE_ABBR
341us, "us", UsState, US_STATES
342us, "us", UsRoad, US_ROADS
343us, "us", UsRoadType, US_ROAD_TYPES
344text, "text", Word, WORDS
345work, "work", Job, JOBS
346work, "work", CompanyName, COMPANY_NAMES
347work, "work", ItCompanyName, IT_COMPANY_NAMES
348work, "work", EnergyCompanyName, ENERGY_COMPANY_NAMES
349work, "work", FinanceCompanyName, FINANCE_COMPANY_NAMES
350work, "work", RetailCompanyName, RETAIL_COMPANY_NAMES
351work, "work", FoodCompanyName, FOOD_COMPANY_NAMES
352work, "work", TravelCompanyName, TRAVEL_COMPANY_NAMES
353work, "work", ConstructionCompanyName, CONSTRUCTION_COMPANY_NAMES
354work, "work", MediaCompanyName, MEDIA_COMPANY_NAMES
355work, "work", TelecomCompanyName, TELECOM_COMPANY_NAMES
356work, "work", BioCompanyName, BIO_COMPANY_NAMES
357work, "work", CarBrand, CAR_BRANDS
358work, "work", AirDefenseCompanyName, AIR_DEFENSE_COMPANY_NAMES
359work, "work", ClothingCompanyName, CLOTHING_COMPANY_NAMES
360world, "world", Country, COUNTRIES
361world, "world", City, CITIES
362world, "world", Continent, CONTINENTS
363world, "world", CountryCode, COUNTRY_CODES
364world, "world", Street, STREETS
365world, "world", River, RIVERS
366);