yfelo 0.1.1

the Yfelo template engine
Documentation
use std::fmt;

use pest::{iterators::Pair, Parser};
use yfelo_core::{factory, SyntaxError};

use super::parser::{DefaultParser, Rule, ToRange};

#[derive(Debug, Clone, PartialEq)]
pub enum Pattern {
    Ident(String, Option<(usize, usize)>),
}

impl factory::Pattern for Pattern {
    fn into_ident(self) -> Option<String> {
        match self {
            Pattern::Ident(ident, _) => Some(ident),
        }
    }
}

impl Pattern {
    pub fn parse(input: &str, offset: usize) -> Result<(Pattern, usize), SyntaxError> {
        match DefaultParser::parse(Rule::pattern, input) {
            Ok(pairs) => {
                let len = pairs.as_str().len();
                Ok((Pattern::from(pairs.into_iter().next().unwrap(), offset), len))
            },
            Err(e) => return Err(SyntaxError {
                message: e.to_string(),
                range: e.location.to_range(offset),
            }),
        }
    }

    fn from(pair: Pair<Rule>, offset: usize) -> Self {
        let pair = pair.into_inner().next().unwrap();
        match pair.as_rule() {
            Rule::ident => Pattern::Ident(pair.as_str().to_string(), Some(pair.to_range(offset))),
            _ => unreachable!(),
        }
    }
}

impl<T: Into<String>> From<T> for Pattern {
    fn from(value: T) -> Self {
        Pattern::Ident(value.into(), None)
    }
}

impl fmt::Display for Pattern {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Pattern::Ident(ident, _) => write!(f, "{}", ident),
        }
    }
}