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
//! # twee_parser
//!
//! The [Story] and [Passage] structs describe a Twine story.
//! They can be constructed by the user, or parsed using the parse_* functions.
//! A [Story] can then be modified and serialized again using the serialize_* functions.
pub use serde_json;
use serde_json::{Value, Map};
/// An in-memory representaion of a Twine story.
#[derive(Debug, Clone)]
pub struct Story {
/// The name of the story.
pub title: String,
/// The list of [Passage]s.
pub passages: Vec<Passage>,
/// The metadata.
/// Please refer to the [specification](https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md#story-data)
/// for standard fields.
/// To be searializable to HTML, the values have to be strings, except tags, which are supported specifically.
pub meta: Map<String, Value>,
}
/// Representation of a passage in a [Story].
#[derive(Debug, Clone)]
pub struct Passage {
/// The name of the passage.
pub name: String,
/// The passage tags. Cannot contain spaces.
pub tags: Vec<String>,
/// The passage metadata.
pub meta: Map<String, Value>,
/// The text content of the passage.
pub content: String,
}
/// Possible parsing errors.
#[derive(Debug)]
pub enum Error {
/// The xmltree library couldn't parse the data, or it doesn't have the right format.
#[cfg(feature = "html")]
HTMLParseError(ParseError),
/// No <tw-storydata> tag was found.
#[cfg(feature = "html")]
HTMLStoryDataNotFound,
}
/// Possible warnings during parsing.
/// Per specification, the parser is quite generous and generates many things as warnings instead of errors.
#[derive(Debug, Clone)]
pub enum Warning {
/// The story metadata wasn't a valid JSON object.
StoryMetadataMalformed,
/// The story's title is missing.
StoryTitleMissing,
/// The passage metadata wasn't a valid inline JSON object.
/// The argument is the passage name.
PassageMetadataMalformed(String),
/// The passage tags weren't closed.
/// The argument is the passage name.
PassageTagsMalformed(String),
/// 2 passages with the same name were found.
/// The argument is the passage name.
PassageDuplicated(String),
/// A passage is missing it's name.
PassageNameMissing,
}
mod twee3;
pub use twee3::*;
#[cfg(feature = "html")]
mod html;
#[cfg(feature = "html")]
pub use html::*;
#[cfg(feature = "html")]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_twee() {
let story = parse_twee3(include_str!("../test-data/Test Story.twee")).unwrap();
assert!(story.1.len() == 0, "{:?}", story.1);
}
}