use crate::data_result::DataResult; use crate::dynamic_ops::DynamicOps; /// A trait for building lists. #[must_use] pub trait ListBuilder { type Value; /// Builds the final list and returns the result. fn build(self, prefix: Self::Value) -> DataResult; /// Adds a direct value to this [`ListBuilder`]. #[must_use] fn add(self, value: Self::Value) -> Self; /// Adds a [`DataResult`] to this [`ListBuilder`]. #[must_use] fn add_data_result(self, value: DataResult) -> Self; } /// An implementation of [`ListBuilder`]. pub struct ListBuilderImpl { elements: DataResult>, ops: &'static O, } pub fn new_list_builder_impl( ops: &'static impl DynamicOps, ) -> impl ListBuilder { ListBuilderImpl { elements: DataResult::new_success(vec![]), ops, } } impl ListBuilder for ListBuilderImpl where O: DynamicOps, { type Value = T; fn build(self, prefix: Self::Value) -> DataResult { self.elements .flat_map(|e| self.ops.merge_values_into_list(prefix, e)) } fn add(mut self, value: Self::Value) -> Self { self.elements = self.elements.map(|mut e: Vec| { e.push(value); e }); self } fn add_data_result(mut self, value: DataResult) -> Self { self.elements = self.elements.apply_2_and_make_stable( |mut e, v| { e.push(v); e }, value, ); self } }