parade-rs 2.0.0

Rust rewrite of Parade - an experimental interactive-fiction playground / filesystem / operating system?
Documentation
use dialoguer::Input;

use parade_rs::{
    action::{
        ActionResult,
        interface::{run_action, status_info},
        parse::Action,
    },
    tree::{Node, Tree},
    vessel::{Article, Vessel, vessel_text},
};

fn main() {
    let mut world: Tree<String, Vessel> = Tree::new();
    let root_key = "universe".to_string();
    world
        .add(
            root_key.clone(),
            Node::new(
                Vessel::new(
                    Some(Article::The),
                    Some("The universe is vast.".to_string()),
                    None,
                ),
                root_key.clone(),
            ),
        )
        .unwrap();
    let library_key = "library".to_string();
    world
        .add(
            library_key.clone(),
            Node::new(
                Vessel::new(
                    Some(Article::The),
                    Some("The library is filled with books.".to_string()),
                    None,
                ),
                root_key.clone(),
            ),
        )
        .unwrap();
    let mut user_key = "ghost".to_string();
    world
        .add(
            user_key.clone(),
            Node::new(Vessel::default(), library_key.clone()),
        )
        .unwrap();
    let mut editor_stack: Vec<String> = Vec::new();

    println!("Welcome to parade! Type \"help\" for help, or \"exit\" to exit.");
    let mut init = true;
    loop {
        match if init {
            init = false;

            ActionResult::ShowStatus
        } else {
            match Action::parse(
                &Input::<String>::new()
                    .allow_empty(true)
                    .interact_text()
                    .unwrap(),
            ) {
                Ok(action) => {
                    run_action(&mut user_key, &mut world, action, &mut editor_stack).unwrap()
                }
                Err(e) => ActionResult::UserError(format!("{e}")),
            }
        } {
            ActionResult::ShowStatus => println!("{}", status_info(&world, &user_key).unwrap()),
            ActionResult::Exit => {
                if editor_stack.pop().is_none() {
                    break;
                }
            }
            ActionResult::Programming(name, article) => {
                println!("You are now programming {}.", vessel_text(&name, &article));
            }
            ActionResult::StillProgramming | ActionResult::StillProgrammingButExit => {}
            ActionResult::DoneProgramming => println!("You finish programming."),
            ActionResult::UserError(text) | ActionResult::DebugText(text) => {
                println!("{text}\n{}", status_info(&world, &user_key).unwrap());
            }
            ActionResult::ResponseText(text) => println!("{text}\n"),
            ActionResult::HelpText(text) => {
                println!("{text}\n{}", status_info(&world, &user_key).unwrap());
            }
            ActionResult::Saved => {
                println!("Saved.\n{}", status_info(&world, &user_key).unwrap());
            }
            ActionResult::Loaded => {
                println!("Loaded.\n{}", status_info(&world, &user_key).unwrap());
            }
            ActionResult::SaveError(error) => println!(
                "Error saving state: {error}\n{}",
                status_info(&world, &user_key).unwrap()
            ),
            ActionResult::LoadError(error) => println!(
                "Error loading state: {error}\n{}",
                status_info(&world, &user_key).unwrap()
            ),
        }
    }
    println!("Bye!");
}