sbrd_gen/generator/evaluate/
eval_generator.rs1use crate::builder::GeneratorBuilder;
2use crate::error::{BuildError, GenerateError};
3use crate::eval::{EvalResult, Evaluator};
4use crate::generator::{GeneratorBase, Randomizer};
5use crate::value::{DataValue, DataValueMap, SbrdBool, SbrdInt, SbrdReal, SbrdString};
6use crate::GeneratorType;
7use std::marker::PhantomData;
8
9#[derive(Debug, PartialEq, Clone)]
13pub struct EvalGenerator<T> {
14 nullable: bool,
15 script: String,
16 _calculated_type: PhantomData<T>,
17}
18
19impl<R: Randomizer + ?Sized, F: ForEvalGeneratorType> GeneratorBase<R> for EvalGenerator<F> {
20 fn create(builder: GeneratorBuilder) -> Result<Self, BuildError>
21 where
22 Self: Sized,
23 {
24 let GeneratorBuilder {
25 generator_type,
26 nullable,
27 script,
28 ..
29 } = builder;
30
31 if generator_type != F::get_generator_type() {
32 return Err(BuildError::InvalidType(generator_type));
33 }
34
35 match script {
36 None => Err(BuildError::NotExistValueOf("script".to_string())),
37 Some(_script) => Ok(Self {
38 nullable,
39 script: _script,
40 _calculated_type: PhantomData,
41 }),
42 }
43 }
44
45 fn is_nullable(&self) -> bool {
46 self.nullable
47 }
48
49 fn generate_without_null(
50 &self,
51 _rng: &mut R,
52 context: &DataValueMap<&str>,
53 ) -> Result<DataValue, GenerateError> {
54 F::eval_script(&self.script, context).map_err(|e| {
55 GenerateError::FailEval(
56 e,
57 self.script.clone(),
58 context
59 .iter()
60 .map(|(k, v)| (k.to_string(), v.clone()))
61 .collect::<DataValueMap<String>>(),
62 )
63 })
64 }
65}
66
67pub trait ForEvalGeneratorType {
69 fn get_generator_type() -> GeneratorType;
71
72 fn eval_script<'a>(script: &'a str, context: &'a DataValueMap<&str>) -> EvalResult<DataValue>;
74}
75
76impl ForEvalGeneratorType for SbrdInt {
77 fn get_generator_type() -> GeneratorType {
78 GeneratorType::EvalInt
79 }
80
81 fn eval_script<'a>(script: &'a str, context: &'a DataValueMap<&str>) -> EvalResult<DataValue> {
82 let evaluator = Evaluator::new(context);
83 evaluator.eval_int(script).map(|v| v.into())
84 }
85}
86impl ForEvalGeneratorType for SbrdReal {
87 fn get_generator_type() -> GeneratorType {
88 GeneratorType::EvalReal
89 }
90
91 fn eval_script<'a>(script: &'a str, context: &'a DataValueMap<&str>) -> EvalResult<DataValue> {
92 let evaluator = Evaluator::new(context);
93 evaluator.eval_real(script).map(|v| v.into())
94 }
95}
96impl ForEvalGeneratorType for SbrdBool {
97 fn get_generator_type() -> GeneratorType {
98 GeneratorType::EvalBool
99 }
100
101 fn eval_script<'a>(script: &'a str, context: &'a DataValueMap<&str>) -> EvalResult<DataValue> {
102 let evaluator = Evaluator::new(context);
103 evaluator.eval_bool(script).map(|v| v.into())
104 }
105}
106impl ForEvalGeneratorType for SbrdString {
107 fn get_generator_type() -> GeneratorType {
108 GeneratorType::EvalString
109 }
110
111 fn eval_script<'a>(script: &'a str, context: &'a DataValueMap<&str>) -> EvalResult<DataValue> {
112 let evaluator = Evaluator::new(context);
113 evaluator.eval_string(script).map(|v| v.into())
114 }
115}