extern crate serde_yaml;
pub use self::error::{Error, Result};
use std::collections::BTreeMap;
use document::{Document, Header};
mod error;
const HEADER_SEPARATOR: &'static str = "---\n";
pub fn parse_document(content: &str) -> Result<Document> {
let mut content = content;
let header = if content.contains(HEADER_SEPARATOR) {
let mut content_split = content.splitn(2, HEADER_SEPARATOR);
let header_string = content_split.next().unwrap_or("");
content = content_split.next().unwrap_or("");
parse_header(header_string)?
} else {
BTreeMap::new()
};
Ok(Document::new(header, content))
}
fn parse_header(s: &str) -> Result<Header> {
Ok(serde_yaml::from_str(s)?)
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use document::Document;
use parser::{parse_document, parse_header, Error};
use parser::yaml_rust::Yaml;
#[test]
fn test_parse_invalid_header_key() {
assert_eq!(
parse_header("a"),
Err(Error::InvalidHeaderFormat("a".to_owned()))
);
assert_eq!(
parse_header("a "),
Err(Error::InvalidHeaderFormat("a ".to_owned()))
);
assert_eq!(
parse_header(": "),
Err(Error::InvalidHeaderKey(Yaml::Null))
);
assert_eq!(
parse_header(": \n"),
Err(Error::InvalidHeaderKey(Yaml::Null))
);
assert_eq!(
parse_header("title:sometitle"),
Err(Error::InvalidHeaderFormat("title:sometitle".to_owned()))
);
assert_eq!(
parse_header("1234: sometitle"),
Err(Error::InvalidHeaderKey(Yaml::Integer(1234)))
);
}
#[test]
fn test_parse_invalid_header_value() {
assert_eq!(
parse_header("key: "),
Err(Error::InvalidHeaderValue(Yaml::Null))
);
assert_eq!(
parse_header("key: \n"),
Err(Error::InvalidHeaderValue(Yaml::Null))
);
assert_eq!(
parse_header("key: 1234"),
Err(Error::InvalidHeaderValue(Yaml::Integer(1234)))
);
}
#[test]
fn test_parse_header() {
let map = {
let mut map = HashMap::new();
map.insert("title".to_owned(), "sometitle".to_owned());
map.insert("date".to_owned(), "2014-01-01".to_owned());
Ok(map)
};
assert_eq!(&parse_header("title: sometitle\ndate: 2014-01-01"), &map);
assert_eq!(&parse_header("title: sometitle\ndate: 2014-01-01\n"), &map);
}
#[test]
fn test_parse_empty_document() {
assert_eq!(parse_document(""), Ok(Document::new(HashMap::new(), "")));
}
#[test]
fn test_parse_document_empty_header_and_body() {
assert_eq!(parse_document("---\n"), Ok(Document::new(HashMap::new(), "")));
assert_eq!(parse_document("\n---\n"), Ok(Document::new(HashMap::new(), "")));
assert_eq!(parse_document(" ---\n"), Ok(Document::new(HashMap::new(), "")));
}
#[test]
fn test_parse_document_empty_header() {
assert_eq!(parse_document("---\nsome random content"), Ok(Document::new(HashMap::new(), "some random content")));
assert_eq!(parse_document("\n---\nsome random content"), Ok(Document::new(HashMap::new(), "some random content")));
assert_eq!(parse_document(" ---\nsome random content"), Ok(Document::new(HashMap::new(), "some random content")));
}
#[test]
fn test_parse_document_empty_body() {
let header = {
let mut header = HashMap::new();
header.insert("title".to_owned(), "my title".to_owned());
header
};
assert_eq!(parse_document("title: my title\n---\n"), Ok(Document::new(header, "")));
}
#[test]
fn test_parse_document() {
assert!(parse_document("title: sometitle\ndate: 2014-01-01\n---\n\nthis is a post.").is_ok());
let header = {
let mut header = HashMap::new();
header.insert("title".to_owned(), "sometitle".to_owned());
header.insert("date".to_owned(), "2014-01-01".to_owned());
header
};
let post = Document::new(header, "this is a post.\nwith multiple lines!");
assert_eq!(parse_document("title: sometitle\ndate: 2014-01-01\n---\nthis is a post.\nwith multiple lines!"), Ok(post));
}
}