nom_html_parser 0.1.1

A parser to convert HTML string to HTML tree structure written with Nom
Documentation
use nom::*;
use nom::{
    IResult,
    bytes::complete::{take_while, take_until},
    character::complete::{char, newline, multispace0},
    sequence::{separated_pair},
    error::{ParseError,VerboseError,context}
};

use super::utils::*;
use super::errors::{
    ATTRIBUTE_SPACE_BEFORE_ERROR,
    ATTRIBUTE_MISSING_EQUAL_ERROR,
    ATTRIBUTE_TAG_ERROR,
    ATTRIBUTE_VALUE_ERROR,
    ATTRIBUTE_MISSING_OPENING_QUOTE_ERROR,
    ATTRIBUTE_MISSING_CLOSING_QUOTE_ERROR,
};

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum Attribute {
    Class(String),
    Event(String),
    Custom(String),
    Component(String),
}

impl Attribute {
    pub fn get_value(attr: &Attribute) -> &String {
       match attr {
        Attribute::Class(e) => e,
        Attribute::Event(e) => e,
        Attribute::Custom(e) => e,
        Attribute::Component(e) => e,
       } 
    }
}

pub type TagAttributes = Vec<(Attribute, String)>;

pub fn get_denominator(denominator: &str) -> Attribute {
    if denominator == "class" {
        Attribute::Class(denominator.to_string())
    } else if denominator == "component" {
        Attribute::Component(denominator.to_string())
    } else if denominator.contains("@") {
        Attribute::Event(denominator.to_string().replace("@", ""))
    } else {
        Attribute::Custom(denominator.to_string())
    }
}

pub fn attribute_value(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
    let (input, _opening_quote) = context(
        ATTRIBUTE_MISSING_OPENING_QUOTE_ERROR,
        char('`')
    )(input)?;
    let (input, value) = context(
        ATTRIBUTE_VALUE_ERROR,
        take_until("`")
    )(input)?;
    let (input, _opening_quote) = context(
        ATTRIBUTE_MISSING_CLOSING_QUOTE_ERROR,
        char('`')
    )(input)?;
    let (input, _newline) = opt!(input, multispace0)?; // eat remaining newlines or tab
    Ok((input, value))
}

pub fn attribute_tag(input: &str) -> IResult<&str, &str, VerboseError<&str>> { 
    let (input, denominator) = context(
        ATTRIBUTE_TAG_ERROR,
        take_while(is_html_value)
    )(input)?;
    Ok((input, denominator))
}

pub fn html_attribute(input: &str) -> IResult<&str, &str, VerboseError<&str>> { 
    let (input, _newline) = opt!(input, multispace0)?; // eat starting newlines or tab
    let (input, attr) = attribute_tag(input)?;
    Ok((input, attr))
}

pub fn attribute(input: &str) -> IResult<&str, (&str, &str), VerboseError<&str>> {
    let (input, _newline) = opt!(input, multispace0)?; // eat starting newlines or tab
    separated_pair(
        html_attribute,
        context(ATTRIBUTE_MISSING_EQUAL_ERROR, char('=')),
        attribute_value 
    )(input)
}