#[derive(Debug, Default)]
pub struct ArrayBuilder<T> {
data: Vec<T>,
}
impl<T> ArrayBuilder<T> {
pub const fn new() -> Self {
Self { data: Vec::new() }
}
#[inline]
pub fn length(&self) -> usize {
self.data.len()
}
#[inline]
pub fn capacity(&self) -> usize {
self.data.capacity()
}
#[inline]
pub fn add_item(&mut self, value: T) {
self.data.push(value);
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
}
pub fn reset(&mut self) {
self.data = Vec::new();
}
#[inline]
pub fn as_span(&self) -> &[T] {
&self.data
}
#[inline]
pub fn as_span_mut(&mut self) -> &mut [T] {
&mut self.data
}
#[inline]
pub fn as_slice(&self, start: usize, length: usize) -> &[T] {
&self.data[start..start + length]
}
#[inline]
pub fn as_slice_to(&self, length: usize) -> &[T] {
&self.data[..length]
}
#[inline]
pub fn as_slice_mut(&mut self, start: usize, length: usize) -> &mut [T] {
&mut self.data[start..start + length]
}
}
impl<T: Clone + Default> ArrayBuilder<T> {
pub fn set_length(&mut self, value: usize) {
self.data.resize(value, T::default());
}
pub fn add(&mut self, length: usize) -> &mut [T] {
let position = self.data.len();
self.data.resize(position + length, T::default());
&mut self.data[position..]
}
pub fn add_slice(&mut self, value: &[T]) -> &mut [T] {
let position = self.data.len();
self.data.extend_from_slice(value);
&mut self.data[position..]
}
}
impl<T> std::ops::Index<usize> for ArrayBuilder<T> {
type Output = T;
#[inline]
fn index(&self, index: usize) -> &T {
&self.data[index]
}
}
impl<T> std::ops::IndexMut<usize> for ArrayBuilder<T> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut T {
&mut self.data[index]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add_and_reuse() {
let mut builder = ArrayBuilder::<i32>::new();
builder.add_item(1);
builder.add(2).fill(7);
builder.add_slice(&[9]);
assert_eq!(builder.as_span(), &[1, 7, 7, 9]);
let capacity = builder.capacity();
builder.clear();
assert_eq!(builder.length(), 0);
assert_eq!(builder.capacity(), capacity);
builder.set_length(2);
builder[1] = 5;
assert_eq!(builder.as_slice(1, 1), &[5]);
}
}