I'm learning rust and doing an exercise where to parse a particular SGML document. Each line in a document can be either an opening tag "" , a closing tag "" or a scalar: " Val". I'm using a regex with named capture groups to detect and extract, and would like to return an enum afterwards.
I came up with the following code, but it feels overly verbose and un-idiomatic, so I'm seeking feedback, particularly on the extract_tag_from_line_match function
use regex::Captures;
use regex::Regex;
struct LineParseError;
enum Tag {
Open(String),
Close(String),
Scalar(String, String),
}
fn extract_line_tag(line: &str) -> Result<Tag, LineParseError> {
let reg: Regex = Regex::new(r"<((?P<close>/))|((?P<open>.+)>(?P<value>.+)?)").unwrap();
let capture = reg.captures(line);
match capture {
None => Err(LineParseError),
Some(cap) => Ok(extract_tag_from_line_match(cap)),
}
}
fn extract_tag_from_line_match(capture: Captures) -> Tag {
let close = capture.name("close");
let open = capture.name("open");
let value = capture.name("value");
let scalar = open.zip(value);
if (scalar.is_some()) {
let (o, v) = scalar.unwrap();
return Tag::Scalar(String::from(o.as_str()), String::from(v.as_str()));
} else if close.is_some() {
let c = close.unwrap();
return Tag::Close(String::from(c.as_str()));
} else {
let v = open.unwrap();
return Tag::Open(String::from(v.as_str()));
}
}