sbrd_gen/generator/random_values/
select_generator.rs

1use crate::builder::GeneratorBuilder;
2use crate::error::{BuildError, GenerateError};
3use crate::generator::{GeneratorBase, Randomizer, ValueGeneratorBase};
4use crate::value::{DataValue, DataValueMap, SbrdInt, SbrdReal, SbrdString};
5use crate::GeneratorType;
6use rand::seq::SliceRandom;
7use std::str::FromStr;
8
9/// The generator with generate value as the type T from value's list as the type
10pub struct SelectGenerator<T> {
11    nullable: bool,
12    selectable_values: Vec<T>,
13}
14
15impl<R: Randomizer + ?Sized, T: ForSelectGeneratorType> ValueGeneratorBase<R, T>
16    for SelectGenerator<T>
17{
18    fn parse(input: &str) -> Result<T, BuildError> {
19        T::parse(input)
20    }
21}
22
23impl<R: Randomizer + ?Sized, T: ForSelectGeneratorType> GeneratorBase<R> for SelectGenerator<T> {
24    fn create(builder: GeneratorBuilder) -> Result<Self, BuildError>
25    where
26        Self: Sized,
27    {
28        let GeneratorBuilder {
29            generator_type,
30            nullable,
31            chars,
32            values,
33            filepath,
34            ..
35        } = builder;
36
37        if generator_type != T::get_generator_type() {
38            return Err(BuildError::InvalidType(generator_type));
39        }
40
41        let selectable_values =
42            <Self as ValueGeneratorBase<R, T>>::build_selectable(chars, values, filepath)?;
43
44        Ok(Self {
45            nullable,
46            selectable_values,
47        })
48    }
49
50    fn is_nullable(&self) -> bool {
51        self.nullable
52    }
53
54    fn generate_without_null(
55        &self,
56        rng: &mut R,
57        _context: &DataValueMap<&str>,
58    ) -> Result<DataValue, GenerateError> {
59        self.selectable_values
60            .choose(rng)
61            .map(|v| v.to_data_value())
62            .ok_or_else(|| GenerateError::FailGenerate("Fail Select Value".to_string()))
63    }
64}
65
66/// Helper traits for generators that the generate value
67pub trait ForSelectGeneratorType {
68    /// The type of the generator
69    fn get_generator_type() -> GeneratorType;
70
71    /// Function of parser the input value
72    fn parse(s: &str) -> Result<Self, BuildError>
73    where
74        Self: Sized;
75
76    /// Function of converter for a generated value
77    fn to_data_value(&self) -> DataValue;
78}
79
80impl ForSelectGeneratorType for SbrdInt {
81    fn get_generator_type() -> GeneratorType {
82        GeneratorType::SelectInt
83    }
84
85    fn parse(s: &str) -> Result<SbrdInt, BuildError> {
86        SbrdInt::from_str(s).map_err(|e| {
87            BuildError::FailParseValue(s.to_string(), "Int".to_string(), e.to_string())
88        })
89    }
90
91    fn to_data_value(&self) -> DataValue {
92        DataValue::Int(*self)
93    }
94}
95
96impl ForSelectGeneratorType for SbrdReal {
97    fn get_generator_type() -> GeneratorType {
98        GeneratorType::SelectReal
99    }
100
101    fn parse(s: &str) -> Result<SbrdReal, BuildError> {
102        SbrdReal::from_str(s).map_err(|e| {
103            BuildError::FailParseValue(s.to_string(), "Real".to_string(), e.to_string())
104        })
105    }
106
107    fn to_data_value(&self) -> DataValue {
108        DataValue::Real(*self)
109    }
110}
111
112impl ForSelectGeneratorType for SbrdString {
113    fn get_generator_type() -> GeneratorType {
114        GeneratorType::SelectString
115    }
116
117    fn parse(s: &str) -> Result<String, BuildError> {
118        Ok(s.to_string())
119    }
120
121    fn to_data_value(&self) -> DataValue {
122        DataValue::String(self.to_string())
123    }
124}