diff --git a/src/main.rs b/src/main.rs index 15bef38..ab53ff6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,12 @@ -use std::fmt::Display; +use std::{collections::HashMap, str::FromStr}; -use winnow::{IResult, bytes::{take_while0, take_until0}, character::{alphanumeric1, multispace0}, error::ParseError, Parser, sequence::{delimited, preceded}, branch, combinator::todo, multi::{fold_many0, many0}}; +use winnow::prelude::*; + +use crate::parser::el_parser; + +mod parser; +mod element; +mod util; const TEST_IHL: &str = " html { @@ -12,7 +18,7 @@ html { p \"this is a test file\" p { \"some text followed by \" - a \"a hyperlink\" + a [ href = \"https://schrottkatze.de\" ] \"a hyperlink\" } } } @@ -24,98 +30,23 @@ fn main() { println!("{e}"); } -fn el_parser(input: &str) -> IResult<&str, Element> { - ( - el_name_parser, - el_body_parser - ).map(|(name, children)| Element { name, children }).parse_next(input) -} +type Name<'a> = &'a str; - -fn el_name_parser(input: &str) -> IResult<&str, &str> { - ws(alphanumeric1).parse_next(input) -} - -fn el_body_parser(input: &str) -> IResult<&str, ElBody> { - ws(branch::alt(( - string_parser.map(|s| ElBody::Text(s)), - delimited( - '{', - many0(content_parser).map(|v| ElBody::Elements(v)), - '}' - ) - ))).parse_next(input) -} - -fn content_parser(input: &str) -> IResult<&str, ElContent> { - ws(branch::alt(( - string_parser.map(|s| ElContent::Text(s)), - el_parser.map(|e| ElContent::El(e)) - ))).parse_next(input) -} - -fn string_parser(input: &str) -> IResult<&str, &str> { - delimited( - '"', - take_until0("\""), - '"', - ).parse_next(input) -} - -#[derive(Debug)] -struct Element<'a> { - name: &'a str, - children: ElBody<'a>, -} - -impl<'a> Display for Element<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "<{0}>{1}", self.name, self.children) - } -} - -/// the direct content of `children`, so it can be a plaintext element -#[derive(Debug)] -enum ElBody<'a> { - Elements(Vec>), +enum Token<'a> { + Name(Name<'a>), Text(&'a str), -} -impl<'a> Display for ElBody<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ElBody::Text(s) => f.write_str(s), - ElBody::Elements(els) => els.iter().try_for_each(|e| f.write_str(&e.to_string())) - } - } + Number(i32), // TODO: more complex number type + // + BlockBrackets(Vec>), // [] block + BlockBraces(Vec>), // {} block + BlockParentheses(Vec>), // () block + + PunctColon, // : + PunctSemi, // ; + PunctComma, // , + PunctDot, // . + + KwItem, // `item` defines a new simple ish item type } -#[derive(Debug)] -enum ElContent<'a> { - El(Element<'a>), - Text(&'a str), -} -impl<'a> Display for ElContent<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ElContent::Text(s) => f.write_str(s), - ElContent::El(el) => f.write_str(&el.to_string()) - } - } -} - -#[test] -fn parse_basic() { -} - -// whitespace combinator from [winnow docs](https://docs.rs/winnow/latest/winnow/_topic/language/index.html#wrapper-combinators-that-eat-whitespace-before-and-after-a-parser) -fn ws<'a, F, O, E: ParseError<&'a str>>(inner: F) -> impl Parser<&'a str, O, E> - where - F: Parser<&'a str, O, E>, -{ - delimited( - multispace0, - inner, - multispace0 - ) -}