fosk 0.1.12

In-memory SQL-like query engine and lightweight data store for testing and prototyping.
Documentation
use crate::parser::{ast::Collection, ParseError, Phase, QueryParser};

pub struct CollectionsParser;

impl CollectionsParser {

    pub fn parse(parser: &mut QueryParser) -> Result<Vec<Collection>, ParseError> {

        if !parser.comparers.from.compare(parser) {
            return ParseError::new("Invalid select statement", parser.position, parser).err();
        }
        parser.jump(parser.comparers.from.length);

        parser.next_non_whitespace();

        let mut collections: Vec<Collection> = vec![];
        let mut can_consume = true;

        while parser.phase == Phase::Collections {
            if parser.current() == ',' {
                if can_consume {
                    return ParseError::new("Invalid select statement", parser.position, parser).err();
                }
                can_consume = true;
                parser.next();
            }


            if parser.current().is_whitespace() {
                parser.next_non_whitespace();
            } else if can_consume {
                collections.push(Collection::parse(parser)?);
                can_consume = false;
            }
        }

        if collections.is_empty() {
            return ParseError::new("Invalid select statement", parser.position, parser).err();
        }

        Ok(collections)
    }

}

#[cfg(test)]
mod tests {
    use crate::parser::{ast::{CollectionsParser}, Phase, QueryParser};

    #[test]
    pub fn test_collections() {
        let text = "FROM table";

        let mut parser = QueryParser::new(text);
        parser.phase = Phase::Collections;

        let result = CollectionsParser::parse(&mut parser).expect("Failed to parse collections");

        assert_eq!(result.len(), 1);
    }

    #[test]
    pub fn test_collections_with_alias() {
        let text = "FROM tableA a";

        let mut parser = QueryParser::new(text);
        parser.phase = Phase::Collections;

        let result = CollectionsParser::parse(&mut parser).expect("Failed to parse collections");

        assert_eq!(result.len(), 1);
    }

    #[test]
    pub fn test_collections_two() {
        let text = "FROM tableA, tableB";

        let mut parser = QueryParser::new(text);
        parser.phase = Phase::Collections;

        let result = CollectionsParser::parse(&mut parser).expect("Failed to parse collections");

        assert_eq!(result.len(), 2);
    }

    #[test]
    pub fn test_collections_three() {
        let text = "FROM tableA, tableB b, tableC c";

        let mut parser = QueryParser::new(text);
        parser.phase = Phase::Collections;

        let result = CollectionsParser::parse(&mut parser).expect("Failed to parse collections");

        assert_eq!(result.len(), 3);
    }

    #[test]
    pub fn test_collections_three_with_where() {
        let text = "FROM tableA, tableB b, tableC c WHERE ";

        let mut parser = QueryParser::new(text);
        parser.phase = Phase::Collections;

        let result = CollectionsParser::parse(&mut parser).expect("Failed to parse collections");

        assert_eq!(result.len(), 3);
    }

    #[test]
    pub fn test_collections_with_wrong_comma() {
        let text = "FROM tableA, tableB b, , tableC c WHERE ";

        let mut parser = QueryParser::new(text);
        parser.phase = Phase::Collections;

        let result = CollectionsParser::parse(&mut parser);

        match result {
            Ok(_) => panic!(),
            Err(err) => {
                assert_eq!(err.text, ",");
                assert_eq!(err.start, 23);
                assert_eq!(err.end, 23);
            },
        };
    }

    #[test]
    pub fn test_collections_with_wrong_alias() {
        let text = "FROM tableA, tableB b c, tableC c WHERE ";

        let mut parser = QueryParser::new(text);
        parser.phase = Phase::Collections;

        let result = CollectionsParser::parse(&mut parser);

        match result {
            Ok(_) => panic!(),
            Err(err) => {
                assert_eq!(err.text, "c");
                assert_eq!(err.start, 22);
                assert_eq!(err.end, 22);
            },
        };
    }

    #[test]
    pub fn test_collections_with_wrong_delimiter() {
        let text = "FROM tableA, tableB b, tableC c WHEE ";

        let mut parser = QueryParser::new(text);
        parser.phase = Phase::Collections;

        let result = CollectionsParser::parse(&mut parser);

        match result {
            Ok(_) => panic!(),
            Err(err) => {
                assert_eq!(err.text, "W");
                assert_eq!(err.start, 32);
                assert_eq!(err.end, 32);
            },
        };
    }
}