1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
use crate::{Dynamic, Op, Relation, Saved};
pub mod concat;
pub mod dynamic;
pub mod feedback;
pub mod input;
pub mod join;
pub mod map;
pub mod output;
pub mod pair;
pub mod reduce;
pub mod save;
pub mod split;
pub type Collection<'a, D> = Saved<Dynamic<'a, (D, isize)>>;
impl<C: Op> Relation<C>
where
C::D: Clone,
{
pub fn collect<'a>(self) -> Collection<'a, C::D>
where
C: 'a,
{
self.dynamic().save()
}
/// No-op which nails down the expected item type.
///
/// The compiler will complain if the provided type is wrong. This helps you spot type errors
/// where they occur rather than downstream.
///
/// Example:
///
/// ```
/// use standing_relations::CreationContext;
/// use std::{collections::HashMap, iter::FromIterator};
///
/// let mut context = CreationContext::new();
/// let (_foo_input, foo) = context.new_input::<(char, isize)>();
/// let (_bar_input, bar) = context.new_input::<char>();
/// let foobar =
/// foo.join(bar.counts()).flat_map(|(k,x,y)| if x < y {Some((k,x))} else {None});
/// let foobar = foobar.t::<(char, isize)>();
/// ```
///
/// Note that if instead of `flat_map`, we had accidentally used `map`, the compiler would
/// complain because `foobar` would have item type `Option<(char, isize)>` where we expect
/// `(char, isize)`.
pub fn t<D: Is<Myself = C::D>>(self) -> Self {
self
}
}
pub trait Is {
type Myself;
}
impl<T> Is for T {
type Myself = T;
}