fosk 0.1.12

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

pub struct StringParser;

impl StringParser {
    pub fn is_string_delimiter(parser: &QueryParser) -> bool {
        parser.current() == '"' || parser.current() == '\''
    }

    pub fn parse(parser: &mut QueryParser) -> Result<Literal, ParseError> {
        let mut pivot = parser.position;

        if !StringParser::is_string_delimiter(parser) {
            return Err(ParseError::new("Invalid string value", pivot, parser));
        }

        let delimiter = parser.current();
        parser.next();
        pivot = parser.position;

        while !parser.eof() && parser.current() != delimiter {
            if WordComparer::is_current_break_line(parser) {
                return Err(ParseError::new("Invalid string", pivot, parser));
            }

            parser.next();
        }
        if parser.eof() {
            return Err(ParseError::new("Invalid string", pivot, parser));
        }

        let text = parser.text_from_pivot(pivot);
        parser.next();

        Ok(Literal::String(text))
    }
}

#[cfg(test)]
pub mod tests {
    use crate::parser::{ast::{Literal, StringParser}, QueryParser};

    #[test]
    pub fn test_string_parser() {
        let text = "\"identifier\"";

        let mut parser = QueryParser::new(text);

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

        match result {
            Ok(result) => match result {
                Literal::String(result) => assert_eq!(result, "identifier"),
                _ => panic!(),
            },
            Err(_) => panic!(),
        }
    }

    #[test]
    pub fn test_string_parser_single_quote() {
        let text = "'identifier'";

        let mut parser = QueryParser::new(text);

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

        match result {
            Ok(result) => match result {
                Literal::String(result) => assert_eq!(result, "identifier"),
                _ => panic!(),
            },
            Err(_) => panic!(),
        }
    }

    #[test]
    pub fn test_string_parser_tab() {
        let text = "\"start\tend\"";

        let mut parser = QueryParser::new(text);

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

        match result {
            Ok(result) => match result {
                Literal::String(result) => assert_eq!(result, "start\tend"),
                _ => panic!(),
            },
            Err(_) => panic!(),
        }
    }

    #[test]
    pub fn test_string_parser_break_line() {
        let text = "\"lets\r\nbreak line\"";

        let mut parser = QueryParser::new(text);

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

        match result {
            Ok(_) => panic!(),
            Err(err) => {
                assert_eq!(err.text, "lets\r");
                assert_eq!(err.start, 1);
                assert_eq!(err.end, 5);
            },
        }
    }
}