#[derive(Default)]
pub struct MapBuilder {
map: serde_yaml::Mapping,
}
impl MapBuilder {
pub fn set<K: Into<serde_yaml::Value>, V: Into<serde_yaml::Value>>(
mut self,
key: K,
value: V,
) -> Self {
self.map.insert(key.into(), value.into());
self
}
pub fn build(self) -> serde_yaml::Value {
self.map.into()
}
}
pub fn parse(source: &str) -> Result<(serde_yaml::Value, String), serde_yaml::Error> {
let (yaml, markdown) = Parser::parse(source);
Ok((serde_yaml::from_str(&yaml)?, markdown))
}
enum State {
Start,
Head,
Body,
}
struct Parser {
state: State,
head: String,
body: String,
}
impl Parser {
fn parse(source: &str) -> (String, String) {
let mut parser = Self {
state: State::Start,
head: String::new(),
body: String::new(),
};
for line in source.lines() {
parser.push_line(line);
}
(parser.head, parser.body)
}
fn push_line(&mut self, line: &str) {
self.state = match (&self.state, line.trim()) {
(State::Start, "---") => State::Head,
(State::Start, "") => State::Start,
(State::Start | State::Body, _) => {
self.body += line;
self.body += "\n";
State::Body
}
(State::Head, "---") => State::Body,
(State::Head, _) => {
self.head += line;
self.head += "\n";
State::Head
}
}
}
}