use surrealdb_types::Value;
pub trait Extractor: Sized {
fn take<I>(iterator: &mut I) -> Option<Self>
where
I: Iterator<Item = Value>;
}
impl Extractor for Value {
fn take<I>(iterator: &mut I) -> Option<Self>
where
I: Iterator<Item = Value>,
{
iterator.next()
}
}
impl Extractor for Option<Value> {
fn take<I>(iterator: &mut I) -> Option<Self>
where
I: Iterator<Item = Value>,
{
Some(iterator.next())
}
}
macro_rules! impl_tuple{
($($I:ident),*$(,)?) => {
impl<$($I: Extractor),*> Extractor for ($($I,)*){
#[allow(non_snake_case)]
fn take<I>(iterator: &mut I) -> Option<Self>
where
I: Iterator<Item = Value>,
{
$(
let $I = $I::take(iterator)?;
)*
if iterator.next().is_some(){
return None
}
Some(($($I,)*))
}
}
}
}
impl_tuple!();
impl_tuple!(A);
impl_tuple!(A, B);
impl_tuple!(A, B, C);
impl_tuple!(A, B, C, D);
impl_tuple!(A, B, C, D, E);
impl_tuple!(A, B, C, D, E, F);
pub fn extract_args<E>(args: Vec<Value>) -> Option<E>
where
E: Extractor,
{
let mut iter = args.into_iter();
E::take(&mut iter)
}