use std::fmt::{Debug, Formatter};
use utilz::test_per_file;
use texttale::{story, ExpectTextTale, StoryElement, TextTale};
struct Player<T: TextTale> {
name: String,
age: u8,
gender: String,
race: String,
tale: T,
}
impl<T: TextTale> Player<T> {
fn new(tale: T) -> Self {
Self {
name: "Link".to_owned(),
gender: "unspecified".to_owned(),
age: 18,
race: "Hylian".to_owned(),
tale,
}
}
}
impl<T: TextTale> Debug for Player<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Player")
.field("name", &self.name)
.field("age", &self.age)
.field("gender", &self.gender)
.field("race", &self.race)
.finish()
}
}
story! {
self cmd,
bootstrap by Player<T>;
"Welcome to the texttale library.
help: ....... Print this help menu.
character: .. Configure your character for this texttale.
begin: ...... Start off on your journey with the given character.
";
"help" => {
StoryElement::PrintHelp
}
"character" => {
self.character();
StoryElement::PrintHelp
}
"begin" => {
self.steady_state();
StoryElement::Return
}
}
story! {
self cmd,
character by Player<T>;
"Craft your character.
help: .... Print this help menu.
name: .... Set your character's name.
age: ..... Set your character's age.
gender: .. Set your character's gender.
race: .... Set your character's race.
print: ... Print your character.
save: .... Commit changes to the configuration and return to previous menu.
";
"name" => {
self.name = cmd[1..].to_vec().join(" ");
StoryElement::Continue
}
"gender" => {
self.gender = cmd[1..].to_vec().join(" ");
StoryElement::Continue
}
"race" => {
self.race = cmd[1..].to_vec().join(" ");
StoryElement::Continue
}
"age" => {
if cmd.len() != 2 {
writeln!(self.tale, "USAGE: age [age]").unwrap();
} else {
match cmd[1].parse::<u8>() {
Ok(age) => {
self.age = age;
},
Err(err) => {
writeln!(self.tale, "invalid age: {}", err).unwrap();
},
};
}
StoryElement::Continue
}
"print" => {
let debug = format!("{:#?}", self);
writeln!(self.tale, "{}", debug).unwrap();
StoryElement::Continue
}
"save" => {
StoryElement::Return
}
}
story! {
self cmd,
steady_state by Player<T>;
"Welcome to adventure mode.
It's quite boring, but this simple quest is enough to test the texttale library.
help: ....... Print this help menu.
character: .. Configure your character for this texttale.
end: ........ Unceremoniously end this adventure.
";
"help" => {
StoryElement::PrintHelp
}
"character" => {
self.character();
StoryElement::PrintHelp
}
"end" => {
StoryElement::Return
}
}
fn tell_tale(_file: &str, _line: u32, script: &str) {
let tale = ExpectTextTale::new(script, "> ").expect("could parse script");
let mut player = Player::new(tale);
player.bootstrap();
}
test_per_file! {
tell_tale {
empty_00 => "scripts/00.empty",
motd_01 => "scripts/01.motd",
help_02 => "scripts/02.help",
character_03 => "scripts/03.character",
begin_04 => "scripts/04.begin",
}
}