sbrd_gen/generator/build_string/
format_generator.rs

1use crate::builder::GeneratorBuilder;
2use crate::error::{BuildError, GenerateError};
3use crate::eval::Evaluator;
4use crate::generator::{GeneratorBase, Randomizer};
5use crate::value::{DataValue, DataValueMap};
6use crate::GeneratorType;
7
8/// The generator with [`DataValue::String`] formatted by specified `format` with evaluating by [`Evaluator`]
9///
10/// [`DataValue::String`]: ../../value/enum.DataValue.html#variant.String
11/// [`Evaluator`]: ../../eval/struct.Evaluator.html
12#[derive(Debug, PartialEq, Clone)]
13pub struct FormatGenerator {
14    nullable: bool,
15    format: String,
16}
17
18impl<R: Randomizer + ?Sized> GeneratorBase<R> for FormatGenerator {
19    fn create(builder: GeneratorBuilder) -> Result<Self, BuildError>
20    where
21        Self: Sized,
22    {
23        let GeneratorBuilder {
24            generator_type,
25            nullable,
26            format,
27            ..
28        } = builder;
29
30        if generator_type != GeneratorType::Format {
31            return Err(BuildError::InvalidType(generator_type));
32        }
33
34        match format {
35            None => Err(BuildError::NotExistValueOf("format".to_string())),
36            Some(_format) => Ok(Self {
37                nullable,
38                format: _format,
39            }),
40        }
41    }
42
43    fn is_nullable(&self) -> bool {
44        self.nullable
45    }
46
47    fn generate_without_null(
48        &self,
49        _rng: &mut R,
50        context: &DataValueMap<&str>,
51    ) -> Result<DataValue, GenerateError> {
52        Evaluator::new(context)
53            .format_script(&self.format)
54            .map(DataValue::String)
55            .map_err(|e| {
56                GenerateError::FailEval(
57                    e,
58                    self.format.to_string(),
59                    context
60                        .clone()
61                        .into_iter()
62                        .map(|(k, v)| (k.to_string(), v))
63                        .collect::<DataValueMap<String>>(),
64                )
65            })
66    }
67}