#[cfg(no_std)]
use alloc::vec::Vec;
#[cfg(no_std)]
use core::{
any::Any,
ops::Deref
};
use crate::Argument;
#[cfg(not(no_std))]
use std::{
any::Any,
ops::Deref
};
use super::{Arguments, MAX_ARG_COUNT};
#[derive(Clone, Debug, Default)]
pub struct ArgumentsBuilder<'a>
{
table: Vec<Argument<'a>>
}
impl<'a> Deref for ArgumentsBuilder<'a>
{
type Target = [Argument<'a>];
#[inline(always)]
fn deref(&self) -> &[Argument<'a>]
{
&self.table
}
}
impl ArgumentsBuilder<'_>
{
#[inline(always)]
pub fn new() -> Self
{
Self
{
table: Vec::new()
}
}
#[inline(always)]
pub fn with_capacity(cap: usize) -> Self
{
let cap = if cap <= MAX_ARG_COUNT { cap } else { MAX_ARG_COUNT };
Self
{
table: Vec::with_capacity(cap)
}
}
#[inline(always)]
pub fn is_full(&self) -> bool
{
self.len() >= MAX_ARG_COUNT
}
#[inline(always)]
fn can_insert_args(&self) -> bool
{
self.len() < MAX_ARG_COUNT
}
#[inline(always)]
fn remaining(&self) -> usize
{
MAX_ARG_COUNT - self.len()
}
#[inline(always)]
pub fn capacity(&self) -> usize
{
self.table.capacity()
}
#[inline(always)]
pub fn reserve(&mut self, count: usize)
{
if self.capacity() < MAX_ARG_COUNT
{
let remaining = self.remaining();
let count =
if count > remaining
{
remaining
} else { count };
self.table.reserve(count);
}
}
#[inline(always)]
pub fn insert_owned<T>(&mut self, owned: T)
-> Result<(), T>
where
T: Any + Clone
{
if self.can_insert_args()
{
self.table.push(Argument::new_owned(owned));
Ok(())
} else { Err(owned) }
}
}
impl<'a> ArgumentsBuilder<'a>
{
#[inline(always)]
pub fn remove(&mut self, idx: usize) -> Option<Argument<'a>>
{
if idx < self.len()
{
Some(self.table.remove(idx))
} else { None }
}
#[inline(always)]
pub fn pop(&mut self) -> Option<Argument<'a>>
{
self.table.pop()
}
#[inline(always)]
pub fn insert_borrowed<T>(&mut self, borrowed: &'a T) -> bool
where
T: Any + Clone
{
if self.can_insert_args()
{
self.table.push(Argument::new_borrowed(borrowed));
true
} else { false }
}
#[inline(always)]
pub fn insert_argument(&mut self, arg: Argument<'a>) -> Result<(), Argument<'a>>
{
if self.can_insert_args()
{
self.table.push(arg);
Ok(())
} else { Err(arg) }
}
#[inline(always)]
pub fn extend<T>(&mut self, mut args: T) -> Vec<Argument<'a>>
where
T: Iterator<Item = Argument<'a>> + ExactSizeIterator
{
let remaining = self.remaining();
if remaining != 0
{
self.table.extend(args.by_ref().take(remaining));
}
#[cfg(debug_assertions)]
{
if self.is_full()
{
assert_eq!(self.len(), MAX_ARG_COUNT);
}
}
args.collect()
}
#[inline(always)]
pub fn build(self) -> Arguments<'a>
{
assert!(self.len() <= MAX_ARG_COUNT);
match Arguments::from_args(self.table)
{
Ok(a) => a,
_ => unreachable!()
}
}
}