Skip to content

Commit

Permalink
Streamed Json Parser
Browse files Browse the repository at this point in the history
  • Loading branch information
bladecoder committed Jul 17, 2024
1 parent b2939a1 commit 402caa0
Show file tree
Hide file tree
Showing 15 changed files with 1,070 additions and 74 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ jobs:
run: cargo fmt -- --check

- name: Test
run: cargo test
run: |
cargo test
cargo test --features stream-json-parser
4 changes: 2 additions & 2 deletions cli-player/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "binkplayer"
version = "1.0.3"
version = "1.1.0"
description = """
Console player for compiled .json Ink story files.
"""
Expand All @@ -16,7 +16,7 @@ path = "src/main.rs"

[dependencies]
anyhow = "1.0.75"
bladeink = { path = "../lib", "version" = "1.0.3" }
bladeink = { path = "../lib", "version" = "1.1.0" }
clap = { "version" = "4.4.6", features = ["derive"] }
rand = "0.8.5"

Expand Down
4 changes: 3 additions & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bladeink"
version = "1.0.3"
version = "1.1.0"
authors = ["Rafael Garcia <bladecoder@gmail.com>"]
description = """
This is a Rust port of inkle's ink, a scripting language for writing interactive narrative.
Expand All @@ -23,7 +23,9 @@ strum = { version = "0.26.3", features = ["derive"] }
as-any = "0.3.0"
rand = "0.8.5"
instant = "0.1.12"
stringreader = "0.1.1"

[features]
stream-json-parser = []
stdweb = ["instant/stdweb"]
wasm-bindgen = ["instant/wasm-bindgen"]
2 changes: 1 addition & 1 deletion lib/src/callstack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde_json::{json, Map};

use crate::{
container::Container,
json_read, json_write,
json::{json_read, json_write},
object::Object,
path::Path,
pointer::{self, Pointer},
Expand Down
2 changes: 1 addition & 1 deletion lib/src/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
callstack::{CallStack, Thread},
choice::Choice,
container::Container,
json_read, json_write,
json::{json_read, json_write},
object::RTObject,
story_error::StoryError,
};
Expand Down
85 changes: 79 additions & 6 deletions lib/src/json_read.rs → lib/src/json/json_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,88 @@ use std::{collections::HashMap, rc::Rc};
use serde_json::Map;

use crate::{
choice::Choice, choice_point::ChoicePoint, container::Container,
control_command::ControlCommand, divert::Divert, glue::Glue, ink_list::InkList,
ink_list_item::InkListItem, list_definition::ListDefinition,
list_definitions_origin::ListDefinitionsOrigin, native_function_call::NativeFunctionCall,
object::RTObject, path::Path, push_pop::PushPopType, story_error::StoryError, tag::Tag,
value::Value, variable_assigment::VariableAssignment, variable_reference::VariableReference,
choice::Choice,
choice_point::ChoicePoint,
container::Container,
control_command::ControlCommand,
divert::Divert,
glue::Glue,
ink_list::InkList,
ink_list_item::InkListItem,
list_definition::ListDefinition,
list_definitions_origin::ListDefinitionsOrigin,
native_function_call::NativeFunctionCall,
object::RTObject,
path::Path,
push_pop::PushPopType,
story::{INK_VERSION_CURRENT, INK_VERSION_MINIMUM_COMPATIBLE},
story_error::StoryError,
tag::Tag,
value::Value,
variable_assigment::VariableAssignment,
variable_reference::VariableReference,
void::Void,
};

pub fn load_from_string(
s: &str,
) -> Result<(i32, Rc<Container>, Rc<ListDefinitionsOrigin>), StoryError> {
let json: serde_json::Value = match serde_json::from_str(s) {
Ok(value) => value,
Err(_) => return Err(StoryError::BadJson("Story not in JSON format.".to_owned())),
};

let version_opt = json.get("inkVersion");

if version_opt.is_none() || !version_opt.unwrap().is_number() {
return Err(StoryError::BadJson(
"ink version number not found. Are you sure it's a valid .ink.json file?".to_owned(),
));
}

let version: i32 = version_opt.unwrap().as_i64().unwrap().try_into().unwrap();

if version > INK_VERSION_CURRENT {
return Err(StoryError::BadJson(
"Version of ink used to build story was newer than the current version of the engine"
.to_owned(),
));
} else if version < INK_VERSION_MINIMUM_COMPATIBLE {
return Err(StoryError::BadJson("Version of ink used to build story is too old to be loaded by this version of the engine".to_owned()));
}

let root_token = match json.get("root") {
Some(value) => value,
None => {
return Err(StoryError::BadJson(
"Root node for ink not found. Are you sure it's a valid .ink.json file?".to_owned(),
))
}
};

let list_definitions = match json.get("listDefs") {
Some(def) => Rc::new(jtoken_to_list_definitions(def)?),
None => return Err(StoryError::BadJson(
"List Definitions node for ink not found. Are you sure it's a valid .ink.json file?"
.to_owned(),
)),
};

let main_content_container = jtoken_to_runtime_object(root_token, None)?;

let main_content_container = main_content_container.into_any().downcast::<Container>();

if main_content_container.is_err() {
return Err(StoryError::BadJson(
"Root node for ink is not a container?".to_owned(),
));
};

let main_content_container = main_content_container.unwrap(); // unwrap: checked for err above

Ok((version, main_content_container, list_definitions))
}

pub fn jtoken_to_runtime_object(
token: &serde_json::Value,
name: Option<String>,
Expand Down
Loading

0 comments on commit 402caa0

Please sign in to comment.