sbrd_gen/
schema.rs

1#![deny(missing_debug_implementations)]
2//! Module for schema
3
4use crate::builder::ParentGeneratorBuilder;
5use crate::error::{BuildError, GenerateError, IntoSbrdError, SchemaErrorKind, SchemaResult};
6use crate::generator::{GeneratorBase, Randomizer};
7use crate::value::{DataValue, DataValueMap};
8use serde::ser::Error;
9use serde::{Deserialize, Serialize};
10
11/// Builder for [`Schema`] is consisting of values at `keys` key that need to be output and builders at `generators` key
12///
13/// [`Schema`]: ./struct.Schema.html
14#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
15pub struct SchemaBuilder {
16    keys: Vec<String>,
17    #[serde(rename = "generators")]
18    builders: Vec<ParentGeneratorBuilder>,
19}
20
21impl SchemaBuilder {
22    /// Constructor
23    pub fn new(keys: Vec<String>, builders: Vec<ParentGeneratorBuilder>) -> SchemaBuilder {
24        SchemaBuilder { keys, builders }
25    }
26
27    /// Build schema structure
28    pub fn build<R: Randomizer + ?Sized>(self) -> SchemaResult<Schema<R>> {
29        let SchemaBuilder {
30            keys: specified_keys,
31            builders,
32        } = self;
33        let mut generators = Vec::new();
34        let mut checked = Vec::new();
35
36        // check specified key's unique
37        let mut cloned = specified_keys.clone();
38        cloned.sort();
39        cloned.dedup();
40        if cloned.len() != specified_keys.len() {
41            return Err(BuildError::SpecifiedKeyNotUnique(specified_keys)
42                .into_sbrd_gen_error(SchemaErrorKind::BuildError));
43        }
44
45        for parent_builder in builders.into_iter() {
46            let (key, builder) = parent_builder.split_key();
47
48            if checked.contains(&key) {
49                return Err(BuildError::AlreadyExistKey(key)
50                    .into_sbrd_gen_error(SchemaErrorKind::BuildError));
51            }
52
53            let generator = builder.build()?;
54            generators.push((key.clone(), generator));
55            checked.push(key);
56        }
57        for specified_key in specified_keys.iter() {
58            if !checked.contains(specified_key) {
59                return Err(
60                    BuildError::NotExistSpecifiedKey(specified_key.to_string(), checked)
61                        .into_sbrd_gen_error(SchemaErrorKind::BuildError),
62                );
63            }
64        }
65
66        Ok(Schema {
67            keys: specified_keys,
68            generators,
69        })
70    }
71}
72
73/// Schema consisting of `keys` and` generators`
74#[allow(missing_debug_implementations)]
75pub struct Schema<R: Randomizer + ?Sized> {
76    keys: Vec<String>,
77    generators: Vec<(String, Box<dyn GeneratorBase<R>>)>,
78}
79
80impl<R: Randomizer + ?Sized> Schema<R> {
81    /// Get specified keys
82    pub fn get_keys(&self) -> &[String] {
83        &self.keys
84    }
85
86    /// Generate a values set
87    pub fn generate(&self, rng: &mut R) -> SchemaResult<GeneratedValues> {
88        let mut generated_values = DataValueMap::new();
89        for (key, generator) in self.generators.iter() {
90            let generated = generator
91                .generate(rng, &generated_values)
92                .map_err(|e| e.into_sbrd_gen_error(SchemaErrorKind::GenerateError))?;
93            generated_values.insert(key, generated);
94        }
95
96        Ok(GeneratedValues {
97            keys: self.get_keys(),
98            generated_values,
99        })
100    }
101}
102
103/// Structure for generated values set
104pub struct GeneratedValues<'a> {
105    keys: &'a [String],
106    generated_values: DataValueMap<&'a str>,
107}
108
109impl<'a> std::fmt::Debug for GeneratedValues<'a> {
110    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111        let key_values = self
112            .filter_values_with_key()
113            .map_err(|e| std::fmt::Error::custom(e.to_string()))?;
114        f.debug_map().entries(key_values).finish()
115    }
116}
117
118impl<'a> std::fmt::Display for GeneratedValues<'a> {
119    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120        let key_values = self
121            .filter_values_with_key()
122            .map_err(|e| std::fmt::Error::custom(e.to_string()))?;
123        write!(f, "{{")?;
124        for (i, (k, v)) in key_values.iter().enumerate() {
125            if i != 0 {
126                write!(f, ", ")?;
127            }
128            match v {
129                DataValue::Int(v) => write!(f, "{}: {:?}", k, v)?,
130                DataValue::Real(v) => write!(f, "{}: {:?}", k, v)?,
131                DataValue::Bool(v) => write!(f, "{}: {:?}", k, v)?,
132                DataValue::String(v) => write!(f, "{}: {:?}", k, v)?,
133                DataValue::Null => write!(f, "{}: null", k)?,
134            };
135        }
136        write!(f, "}}")
137    }
138}
139
140impl<'a> GeneratedValues<'a> {
141    /// Get all values regardless of whether the key is specified as the value for which output is required
142    pub fn get_all_values(&self) -> &DataValueMap<&str> {
143        &self.generated_values
144    }
145
146    /// Get all values for which the key is specified as the value for which output is required
147    pub fn filter_values(&self) -> SchemaResult<Vec<&DataValue>> {
148        let mut result = Vec::new();
149        for key in self.keys.iter() {
150            let value_result = self.generated_values.get(key.as_str());
151            let value = value_result.ok_or_else(|| {
152                GenerateError::NotExistGeneratedKey(
153                    key.to_string(),
154                    self.generated_values
155                        .iter()
156                        .map(|(k, v)| (k.to_string(), v.clone()))
157                        .collect::<DataValueMap<String>>(),
158                )
159                .into_sbrd_gen_error(SchemaErrorKind::GenerateError)
160            })?;
161
162            result.push(value);
163        }
164
165        Ok(result)
166    }
167
168    /// Get all keys and values for which the key is specified as the value for which output is required
169    pub fn filter_values_with_key<'b>(&'b self) -> SchemaResult<Vec<(&'a str, &'b DataValue)>> {
170        let mut result = Vec::new();
171        for key in self.keys.iter() {
172            let value_result = self.generated_values.get(key.as_str());
173            let value = value_result.ok_or_else(|| {
174                GenerateError::NotExistGeneratedKey(
175                    key.to_string(),
176                    self.generated_values
177                        .iter()
178                        .map(|(k, v)| (k.to_string(), v.clone()))
179                        .collect::<DataValueMap<String>>(),
180                )
181                .into_sbrd_gen_error(SchemaErrorKind::GenerateError)
182            })?;
183
184            result.push((key.as_str(), value));
185        }
186
187        Ok(result)
188    }
189
190    /// Convert to a sequence from all values for which the key is specified as the value for which output is required
191    pub fn into_values(self) -> SchemaResult<Vec<DataValue>> {
192        let mut result = Vec::new();
193        let GeneratedValues {
194            keys,
195            mut generated_values,
196        } = self;
197
198        // check
199        for key in keys.iter() {
200            if !generated_values.contains_key(key.as_str()) {
201                return Err(GenerateError::NotExistGeneratedKey(
202                    key.to_string(),
203                    generated_values
204                        .into_iter()
205                        .map(|(k, v)| (k.to_string(), v))
206                        .collect::<DataValueMap<String>>(),
207                )
208                .into_sbrd_gen_error(SchemaErrorKind::GenerateError));
209            }
210        }
211
212        // drain
213        for key in keys.iter() {
214            let value_result = generated_values.remove_entry(key.as_str());
215            let (_, value) = value_result
216                .unwrap_or_else(|| panic!("Already checked {}'s value is not exist.", key));
217
218            result.push(value);
219        }
220
221        Ok(result)
222    }
223
224    /// Convert to a sequence from all keys and values for which the key is specified as the value for which output is required
225    pub fn into_values_with_key(self) -> SchemaResult<Vec<(String, DataValue)>> {
226        let mut result = Vec::new();
227        let GeneratedValues {
228            keys,
229            mut generated_values,
230        } = self;
231
232        // check
233        for key in keys.iter() {
234            if !generated_values.contains_key(key.as_str()) {
235                return Err(GenerateError::NotExistGeneratedKey(
236                    key.to_string(),
237                    generated_values
238                        .into_iter()
239                        .map(|(k, v)| (k.to_string(), v))
240                        .collect::<DataValueMap<String>>(),
241                )
242                .into_sbrd_gen_error(SchemaErrorKind::GenerateError));
243            }
244        }
245
246        // drain
247        for key in keys.iter() {
248            let value_result = generated_values.remove_entry(key.as_str());
249            let (key, value) = value_result
250                .unwrap_or_else(|| panic!("Already checked {}'s value is not exist.", key));
251
252            result.push((key.to_string(), value));
253        }
254
255        Ok(result)
256    }
257}