datasources 0.1.5

Async datasource interfaces, middleware, registry, and test doubles
Documentation
use crate::reader::Reader;
use crate::result::Result;
use crate::row::Row;
use async_trait::async_trait;
use std::sync::Mutex;

pub struct FirstResultReader {
    first: Vec<Row>,
    index: Mutex<isize>,
    first_set: Mutex<bool>,
    current: Mutex<Option<Row>>,
    live: Box<dyn Reader>,
}

impl FirstResultReader {
    pub async fn capture(live: Box<dyn Reader>) -> Result<(Box<dyn Reader>, Vec<Row>)> {
        let mut rows = Vec::new();
        while live.next().await? {
            if let Some(row) = live.current() {
                rows.push(row);
            }
        }
        Ok((
            Box::new(Self {
                first: rows.clone(),
                index: Mutex::new(-1),
                first_set: Mutex::new(true),
                current: Mutex::new(None),
                live,
            }) as Box<dyn Reader>,
            rows,
        ))
    }
}

#[async_trait]
impl Reader for FirstResultReader {
    fn current(&self) -> Option<Row> {
        self.current.lock().expect("reader").clone()
    }

    async fn next(&self) -> Result<bool> {
        if !*self.first_set.lock().expect("reader") {
            let moved = self.live.next().await?;
            *self.current.lock().expect("reader") = self.live.current();
            return Ok(moved);
        }
        let mut index = self.index.lock().expect("reader");
        *index += 1;
        let i = *index as usize;
        if i < self.first.len() {
            *self.current.lock().expect("reader") = Some(self.first[i].clone());
            Ok(true)
        } else {
            *self.current.lock().expect("reader") = None;
            Ok(false)
        }
    }

    async fn next_result(&self) -> Result<bool> {
        *self.first_set.lock().expect("reader") = false;
        *self.current.lock().expect("reader") = None;
        self.live.next_result().await
    }
}