use std::sync::Arc;
use crate::iteration::comprehension::ir::{interpret, Program, TupleStream};
use crate::iteration::comprehension::strategies::Tuple;
pub struct CoordinateStream {
#[allow(dead_code)]
program: Arc<Program>,
stream: Box<dyn TupleStream>,
}
impl CoordinateStream {
pub(crate) fn new(program: Arc<Program>) -> Self {
let stream = interpret(&program);
Self { program, stream }
}
pub fn advance(&mut self) -> Option<Tuple> {
self.stream.advance()
}
}
impl Iterator for CoordinateStream {
type Item = Tuple;
fn next(&mut self) -> Option<Self::Item> {
self.advance()
}
}
impl std::fmt::Debug for CoordinateStream {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CoordinateStream")
.field("program_ops", &self.program.len())
.finish_non_exhaustive()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::iteration::comprehension::ast::Comprehension;
use crate::iteration::comprehension::source::{LiteralValue, Source};
use crate::iteration::comprehension::strategies::TupleValue;
use crate::iteration::comprehension::surfaces::compile;
fn clause(name: &str, vs: &[i64]) -> Comprehension {
Comprehension::clause(
name,
Source::Literal {
values: vs.iter().map(|n| LiteralValue::Int(*n)).collect(),
},
)
}
#[test]
fn advance_returns_tuples_then_none() {
let compiled = compile(&clause("k", &[1, 2, 3]));
let mut stream = compiled.coordinate_stream();
assert!(stream.advance().is_some());
assert!(stream.advance().is_some());
assert!(stream.advance().is_some());
assert!(stream.advance().is_none());
assert!(stream.advance().is_none()); }
#[test]
fn iterator_collect() {
let compiled = compile(&clause("k", &[10, 20, 30]));
let stream = compiled.coordinate_stream();
let tuples: Vec<Tuple> = stream.collect();
assert_eq!(tuples.len(), 3);
assert_eq!(tuples[0].bindings[0].1, TupleValue::I64(10));
assert_eq!(tuples[2].bindings[0].1, TupleValue::I64(30));
}
#[test]
fn iterator_take_truncates() {
let compiled = compile(&clause("k", &[1, 2, 3, 4, 5]));
let stream = compiled.coordinate_stream();
let tuples: Vec<Tuple> = stream.take(2).collect();
assert_eq!(tuples.len(), 2);
}
}