gqb 0.10.0

GQL Query Builder API.
Documentation
use crate::prelude::*;

/// Trait for passing variables to a function.
pub trait Variables
{
  /// Fill the vector of variables
  fn fill(self, vector: &mut Vec<Variable>);
}

impl Variables for Variable
{
  fn fill(self, vector: &mut Vec<Variable>)
  {
    vector.push(self);
  }
}

impl Variables for Vec<Variable>
{
  fn fill(mut self, vector: &mut Vec<Variable>)
  {
    vector.append(&mut self);
  }
}

/// Trait for passing typed variables to a query function.
pub trait TypedVariables: Variables
{
  /// The type of the output a query
  type Output;
  /// Construct the output from a vector of values
  fn from_value_vector(vector: Vec<graphcore::Value>) -> Result<Self::Output>;
}

macro_rules! impl_variables {
  ($n:tt $($idx:tt $t:ident),*) => {
    impl Variables
      for ($(__variable!($idx),)*)
    {
      fn fill(self, vector: &mut Vec<Variable>) {
        $(
          vector.push(self.$idx);
        )*
      }
    }
    impl<$($t,)*> Variables
      for ($(TypedVariable<$t>,)*)
      where $($t: TryFrom<graphcore::Value>),*
    {
      fn fill(self, vector: &mut Vec<Variable>) {
        $(
          vector.push(self.$idx.into());
        )*
      }
    }
    impl<$($t,)*> TypedVariables
      for ($(TypedVariable<$t>,)*)
      where $($t: TryFrom<graphcore::Value, Error = graphcore::Error>),*
    {
        type Output = ($($t,)*);
        fn from_value_vector(vector: Vec<graphcore::Value>) -> Result<Self::Output>
        {
          if vector.len() != $n
          {
            return Err(crate::Error::MissingEntryInTable)
          }
          let mut it = vector.into_iter();
          Ok((
            $(
              $t::try_from(it.next().unwrap())?,
            )*
          ))
        }
    }
  };
}

// Generate implementations for 1..=20
macro_rules! impl_all_variables {
  ($($n:tt $($idx:tt $t:ident),*;)*) => {
    $(impl_variables!($n $($idx $t),*);)*
  };
}

impl_all_variables! {
  1 0 T0;
  2 0 T0, 1 T1;
  3 0 T0, 1 T1, 2 T2;
  4 0 T0, 1 T1, 2 T2, 3 T3;
  5 0 T0, 1 T1, 2 T2, 3 T3, 4 T4;
  6 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5;
  7 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6;
  8 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7;
  9 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8;
  10 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9;
  11 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10;
  12 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11;
  13 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12;
  14 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13;
  15 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14;
  16 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15;
  17 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15, 16 T16;
  18 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15, 16 T16, 17 T17;
  19 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15, 16 T16, 17 T17, 18 T18;
  20 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15, 16 T16, 17 T17, 18 T18, 19 T19;
}

impl<T> Variables for TypedVariable<T>
where
  T: TryFrom<graphcore::Value>,
{
  fn fill(self, vector: &mut Vec<Variable>)
  {
    vector.push(self.into());
  }
}

impl<T> TypedVariables for TypedVariable<T>
where
  T: TryFrom<graphcore::Value>,
  Error: From<<T as TryFrom<graphcore::Value>>::Error>,
{
  type Output = T;
  fn from_value_vector(vector: Vec<graphcore::Value>) -> Result<Self::Output>
  {
    if vector.len() != 1
    {
      return Err(crate::Error::MissingEntryInTable);
    }
    let mut it = vector.into_iter();
    Ok(T::try_from(it.next().unwrap())?)
  }
}