use crate::Parser;
use crate::parser::Context;

pub(crate) struct AlphabeticCharacterParser;

impl Parser<char> for AlphabeticCharacterParser {

    fn parse_fun(&self, input: String, ctx: &mut Context) -> Result<(char, String), String> {
        if input.len() == 0 {
            return Err("Empty string".to_owned());
        }
        let first = &input[..1];
        let rest = &input[1..];
        match first.chars().nth(0) {
            Some(c) => {
                if !c.is_alphabetic() {
                    return Err(format!("Non alphabetic character found {} at {},{}", first, ctx.row, ctx.col)); 
                }
                return Ok((c, rest.to_owned()));
            },
            None => return Err(String::from("Character not found")),
        }
    }

}

pub(crate) struct CharacterParser {
    pub character: char
}

impl Parser<char> for CharacterParser {

    fn parse_fun(&self, input: String, ctx: &mut Context) -> Result<(char, String), String> {
        if input.len() == 0 {
            return Err("Empty string".to_owned());
        }
        let first = &input[..1];
        let rest = &input[1..];
        match first.chars().nth(0) {
            Some(c) => {
                if c != self.character {
                    return Err(format!("Expected {} but found {} at {},{}", self.character, c, ctx.row, ctx.col)); 
                }
                return Ok((c, rest.to_owned()));
            },
            None => return Err(String::from("Character not found")),
        }
    }

}