1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
//! Data types of a story. use crate::{error::utils::MetaData, line::Variable}; use std::collections::HashMap; #[cfg(feature = "serde_support")] use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq)] /// Single line of text in a story, ready to display. pub struct Line { /// Text to display. /// /// The text is ready to be printed as-is, without the addition of more characters. /// It been processed to remove extraneous whitespaces and contains a newline character /// at the end of the line unless the line was glued to the next. pub text: String, /// Tags set to the line. pub tags: Vec<String>, } #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde_support", derive(Deserialize, Serialize))] /// Choice presented to the user. pub struct Choice { /// Line of text to represent the choice with. /// /// The text is ready to be printed as-is. It is trimmed of whitespace from both ends /// and contains no newline character at the end. pub text: String, /// Tags associated with the choice. pub tags: Vec<String>, /// Internal index of choice in set. pub(crate) index: usize, } #[derive(Debug)] /// Result from following a `Story`. /// /// # Examples /// ``` /// # use inkling::{read_story_from_string, Prompt}; /// let content = "\ /// Professor Lidenbrock had barely a spattering of water left in his flask. /// * Axel got the last of it. /// * He pressed on, desperately hoping to find water soon. /// "; /// /// let mut story = read_story_from_string(content).unwrap(); /// let mut line_buffer = Vec::new(); /// /// story.start().unwrap(); /// /// match story.resume(&mut line_buffer).unwrap() { /// Prompt::Choice(choice_set) => { /// println!("Choose:"); /// for (i, choice) in choice_set.iter().enumerate() { /// println!("{}. {}", i + 1, choice.text); /// } /// }, /// Prompt::Done => { /* the story reached its end */ }, /// } /// ``` pub enum Prompt { /// The story reached an end. Done, /// A choice was encountered. Choice(Vec<Choice>), } impl Prompt { /// If a set of choices was returned, retrieve them without having to match. /// /// # Examples /// ``` /// # use inkling::{read_story_from_string, Prompt}; /// let content = "\ /// Professor Lidenbrock had barely a spattering of water left in his flask. /// * Axel got the last of it. /// * He pressed on, desperately hoping to find water soon. /// "; /// /// let mut story = read_story_from_string(content).unwrap(); /// let mut line_buffer = Vec::new(); /// /// story.start().unwrap(); /// /// if let Some(choices) = story.resume(&mut line_buffer).unwrap().get_choices() { /// /* do what you want */ /// } /// ``` pub fn get_choices(&self) -> Option<Vec<Choice>> { match self { Prompt::Choice(choices) => Some(choices.clone()), _ => None, } } } /// Convenience type to indicate when a buffer of `Line` objects is being manipulated. pub type LineBuffer = Vec<Line>; /// Convenience type for a set of global variables. pub type VariableSet = HashMap<String, VariableInfo>; #[derive(Clone, Debug)] #[cfg_attr(feature = "serde_support", derive(Deserialize, Serialize))] /// Information about a global variable in the story. pub struct VariableInfo { /// Variable data. pub variable: Variable, /// Information about the origin of the variable in the story file or text. pub meta_data: MetaData, } #[cfg(test)] impl VariableInfo { pub fn new<T: Into<Variable>>(variable: T, line_index: usize) -> Self { VariableInfo { variable: variable.into(), meta_data: line_index.into(), } } }