Parser outputs stories not books

This commit is contained in:
Dane Johnson 2022-01-24 12:35:52 -06:00
parent 12be2086b7
commit c2e59d08aa

View File

@ -2,6 +2,12 @@
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Debug, PartialEq)]
pub struct Book {
pages: HashMap<String, Page>,
current_page: Option<String>
}
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct Page { pub struct Page {
id: String, id: String,
@ -40,8 +46,8 @@ pub struct StatChange {
peg::parser! { peg::parser! {
grammar storybook_parser() for str { grammar storybook_parser() for str {
pub rule story() -> Vec<Page> pub rule story() -> Book
= blankline()* ps:page()+ eof() { ps } = blankline()* ps:page()+ eof() { Book::from(ps) }
rule page() -> Page rule page() -> Page
= h:header() b:body() f:footer() blankline()* { = h:header() b:body() f:footer() blankline()* {
Page { Page {
@ -97,17 +103,9 @@ peg::parser! {
} }
} }
// Book is a collection of pages and utilities
pub struct Book {
pages: HashMap<String, Page>,
current_page: Option<String>
}
impl Book { impl Book {
pub fn new (story: &str) -> Self { pub fn new (story: &str) -> Self {
let pages = storybook_parser::story(story).unwrap(); storybook_parser::story(story).unwrap()
Book::from(pages)
} }
pub fn find (&mut self, id: &str) { pub fn find (&mut self, id: &str) {
if self.pages.contains_key(id) { if self.pages.contains_key(id) {
@ -173,6 +171,7 @@ impl From<Vec<Page>> for Book {
// C API // C API
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub mod ffi { pub mod ffi {
use std::ffi::CStr; use std::ffi::CStr;
use std::ffi::CString; use std::ffi::CString;
@ -265,8 +264,7 @@ pub mod ffi {
CStr::from_ptr(string) CStr::from_ptr(string)
}; };
let string = string.to_str().expect("Error, input string not valid UTF-8"); let string = string.to_str().expect("Error, input string not valid UTF-8");
let pages = super::storybook_parser::story(string).expect("Error, input string could not be parsed"); let book = super::storybook_parser::story(string).expect("Error, input string could not be parsed");
let book = Book::from(pages);
let book = Box::from(book); let book = Box::from(book);
Box::into_raw(book) Box::into_raw(book)
} }
@ -388,15 +386,14 @@ THE END
"; ";
#[test] #[test]
fn storybook_parser_test() { fn storybook_parser_test() {
assert_eq!( let expected = Book {
storybook_parser::story(STORY), pages: HashMap::from([
Ok(vec![ ("START".to_string(), Page {
Page {
id: String::from("START"), id: String::from("START"),
body: String::from("One day, Dane took a really big shit."), body: String::from("One day, Dane took a really big shit."),
footer: Footer::Goto(String::from("DIALOG")) footer: Footer::Goto(String::from("DIALOG"))
}, }),
Page { ("DIALOG".to_string(), Page {
id: String::from("DIALOG"), id: String::from("DIALOG"),
body: String::from("Dane: 'Wow, that was a really big shit!'"), body: String::from("Dane: 'Wow, that was a really big shit!'"),
footer: Footer::Choices(HashMap::from([ footer: Footer::Choices(HashMap::from([
@ -422,14 +419,21 @@ THE END
}) })
}), }),
])) ]))
}, }),
Page { ("DIE".to_string(), Page {
id: String::from("DIE"), id: String::from("DIE"),
body: String::from("Then he died.\n\nFuck you, Dane!"), body: String::from("Then he died.\n\nFuck you, Dane!"),
footer: Footer::Ending, footer: Footer::Ending,
} }),
]) ]),
); current_page: None,
};
let result = Book::new(STORY);
for (key, expected_page) in expected.pages.iter() {
let result_page = result.pages.get(key).unwrap();
assert_eq!(expected_page, result_page);
}
} }
#[test] #[test]