Pumpkin/crates/pumpkin-codecs/src/list_builder.rs
2026-08-06 12:56:40 +02:00

66 lines
1.6 KiB
Rust

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<Self::Value>;
/// 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::Value>) -> Self;
}
/// An implementation of [`ListBuilder`].
pub struct ListBuilderImpl<T, O: 'static> {
elements: DataResult<Vec<T>>,
ops: &'static O,
}
pub fn new_list_builder_impl<T>(
ops: &'static impl DynamicOps<Value = T>,
) -> impl ListBuilder<Value = T> {
ListBuilderImpl {
elements: DataResult::new_success(vec![]),
ops,
}
}
impl<T, O> ListBuilder for ListBuilderImpl<T, O>
where
O: DynamicOps<Value = T>,
{
type Value = T;
fn build(self, prefix: Self::Value) -> DataResult<Self::Value> {
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<T>| {
e.push(value);
e
});
self
}
fn add_data_result(mut self, value: DataResult<T>) -> Self {
self.elements = self.elements.apply_2_and_make_stable(
|mut e, v| {
e.push(v);
e
},
value,
);
self
}
}