diff --git a/src/main.rs b/src/main.rs index d03de6a..e1c9282 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,20 +4,39 @@ // Implicit tag // h1 a#id."a b c" href="/" {"foo"}; -type Offset = usize; -type Parse<'a> = (&'a str, &'a str, Offset); -type MaybeParse<'a> = Option>; +mod lex; -fn parse_until(i: &str, condition: impl Fn(char) -> bool) -> Parse { +type Offset = usize; +type Parse<'a, T> = (T, &'a str, Offset); +type MaybeParse<'a, T> = Option>; + +#[derive(Debug, Clone)] +struct Tag<'a> { + name: &'a str, + id: &'a str, + classes: &'a str +} + +impl Tag<'_> { + fn write_open(&self, out: &mut String) { + out.push_str(&format!("<{} id={} class={}>", self.name, self.id, self.classes)); + } + + fn write_close(&self, out: &mut String) { + out.push_str(&format!("", self.name)); + } +} + +fn parse_until(i: &str, condition: impl Fn(char) -> bool) -> Parse<&str> { i.chars() .position(condition) .map(|pos| (&i[..pos], &i[pos..], pos)) .unwrap_or((&i, "", i.len())) } -fn parse_ws(i: &str) -> Parse { parse_until(i, |c| !c.is_whitespace()) } +fn parse_ws(i: &str) -> Parse<&str> { parse_until(i, |c| !c.is_whitespace()) } -fn parse_char(i: &str, matches: char) -> MaybeParse { +fn parse_char(i: &str, matches: char) -> MaybeParse<&str> { if let Some(c) = i.chars().next() { if c == matches { return Some((&i[0..1], &i[1..], 1)); @@ -26,7 +45,7 @@ fn parse_char(i: &str, matches: char) -> MaybeParse { None } -fn not_empty(parse: Parse) -> MaybeParse { +fn not_empty<'a>(parse: Parse<'a, &'a str>) -> MaybeParse<&'a str> { if !parse.0.is_empty() { Some(parse) } else { @@ -34,7 +53,7 @@ fn not_empty(parse: Parse) -> MaybeParse { } } -fn parse_string(i: &str) -> MaybeParse { +fn parse_string(i: &str) -> MaybeParse<&str> { let mut skip = false; let (_, i, o1) = parse_char(i, '"')?; let mut o2 = 0; @@ -45,20 +64,21 @@ fn parse_string(i: &str) -> MaybeParse { skip = true; } else if c == '"' { let off = o1 + o2 - 1; - return Some((&i[..off], &i[off..], off)); + return Some((&i[..off], &i[off+1..], off+2)); } o2 += 1; } None } -fn parse_name(i: &str) -> MaybeParse { - let (name, i, o1) = not_empty(parse_until(i, |c| c.is_whitespace()))?; + +fn parse_name(i: &str) -> MaybeParse<&str> { + let (name, i, o1) = not_empty(parse_until(i, |c| !(c != '_') || !(c != '-') || !c.is_alphabetic()))?; let (_, i, o2) = parse_ws(i); Some((name, i, o1 + o2)) } -fn parse_id(i: &str) -> MaybeParse { +fn parse_id(i: &str) -> MaybeParse<&str> { let (_, i, o1) = parse_char(i, '#')?; let (_, i, o2) = parse_ws(i); let (id, i, o3) = parse_name(i)?; @@ -66,7 +86,7 @@ fn parse_id(i: &str) -> MaybeParse { Some((id, i, o1 + o2 + o3 + o4)) } -fn parse_classes(i: &str) -> MaybeParse { +fn parse_classes(i: &str) -> MaybeParse<&str> { let (_, i, o1) = parse_char(i, '.')?; let (_, i, o2) = parse_ws(i); let (classes, i, o3) = parse_string(i)?; @@ -74,21 +94,33 @@ fn parse_classes(i: &str) -> MaybeParse { Some((classes, i, o1 + o2 + o3 + o4)) } -fn parse_tag(i: &str) -> Option<()> { - let (name, i, o1) = parse_name(i)?; - let (id, i, o2) = parse_id(i).unwrap_or(("", i, 0)); - let (classes, i, o3) = parse_classes(i).unwrap_or(("", i, 0)); - Some(()) +enum TokenType { + String, + Name, + Id, + Classes, + Equals, + Close } -fn parse(i: &str) { - let mut explicit_stack: Vec<&str> = vec![]; - let mut inline_stack: Vec<&str> = vec![]; - let mut out = String::new(); - let mut off = 0; +struct Token<'a> { + tty: TokenType, + slice: &'a str, + offset: usize } +fn tokenize(i: &str) -> Vec { + let mut tokens = vec![]; + let mut off = 0; + while !i.is_empty() { + + } + tokens +} + + fn main() { - let p = parse_classes(".\"a b c\""); - println!("{:?}", p); + let (_, i, o1) = parse_string("\"asdf\"\"asdf\"").unwrap(); + let (_, i, o2) = parse_string(i).unwrap(); + println!("{i} {:?}", o1+o2); }