diff --git a/src/lib.rs b/src/lib.rs index c512e98..e05232d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,9 @@ use std::collections::HashMap; #[derive(Debug, PartialEq)] pub struct Book { pages: HashMap, - current_page: Option + current_page: Option, + pub title: String, + pub attribution: String, } #[derive(Debug, PartialEq)] @@ -47,7 +49,11 @@ pub struct StatChange { peg::parser! { grammar storybook_parser() for str { pub rule story() -> Book - = blankline()* ps:page()+ eof() { Book::from(ps) } + = blankline()* t:title() a:attribution() ps:page()+ eof() { Book::from((t, a, ps)) } + rule title() -> String + = t:$((!attribution() [_])+) &attribution() { String::from(t.trim()) } + rule attribution() -> String + = ("by" / "By" ) _ a:$((!__ [_])+) __ blankline()* { String::from(a.trim()) } rule page() -> Page = h:header() b:body() f:footer() blankline()* { Page { @@ -154,13 +160,15 @@ impl Book { } } -impl From> for Book { - fn from(v: Vec) -> Book { +impl From<(String, String, Vec)> for Book { + fn from((title, attribution, v) : (String, String, Vec)) -> Book { let it = v.into_iter().map(|p| (p.id.clone(), p)); let pages = HashMap::from_iter(it); let mut book = Book { pages, current_page: None, + title, + attribution }; book.find("START"); @@ -363,6 +371,8 @@ pub mod ffi { mod tests { use super::*; const STORY: &str = r" +Dane's Big Day +By Austin Lee START One day, Dane took a really big shit. @@ -426,10 +436,15 @@ THE END footer: Footer::Ending, }), ]), + title: "Dane's Big Day".to_string(), + attribution: "Austin Lee".to_string(), current_page: None, }; let result = Book::new(STORY); + assert_eq!(expected.title, result.title); + assert_eq!(expected.attribution, result.attribution); + for (key, expected_page) in expected.pages.iter() { let result_page = result.pages.get(key).unwrap(); assert_eq!(expected_page, result_page); diff --git a/storybook-godot/src/lib.rs b/storybook-godot/src/lib.rs index 1e3b7bd..143c6bb 100644 --- a/storybook-godot/src/lib.rs +++ b/storybook-godot/src/lib.rs @@ -1,4 +1,3 @@ -use storybook; use gdnative::prelude::*; fn init(handle: InitHandle){ @@ -84,23 +83,30 @@ impl Book { storybook::Footer::Goto(_) => Footer::Goto, storybook::Footer::Choices(choices) => { Footer::Choices(choices.iter().map(|(o, c)| Choice { - option: o.clone(), + option: *o, flavor: c.flavor.clone(), - stat_check: match &c.stat_check { - Some(c) => Some(StatCheck::new(c)), - None => None, - }, - stat_change: match &c.stat_change { - Some(c) => Some(StatChange::new(c)), - None => None, - }, - + stat_check: c.stat_check.as_ref().map(StatCheck::new), + stat_change: c.stat_change.as_ref().map(StatChange::new), }).collect()) }, }, None => Footer::None, } } + #[export] + fn get_title(&self, _owner: &Reference) -> String { + match &self._book { + Some(b) => b.title.clone(), + None => String::new(), + } + } + #[export] + fn get_attribution(&self, _owner: &Reference) -> String { + match &self._book { + Some(b) => b.attribution.clone(), + None => String::new(), + } + } } impl StatCheck {