diff --git a/Cargo.lock b/Cargo.lock index 146e353..5498801 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2298,12 +2298,6 @@ dependencies = [ "redox_syscall 0.4.1", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -2782,7 +2776,8 @@ dependencies = [ "bevy_xpbd_3d", "fastrand", "regex", - "yaml-rust", + "serde", + "serde_yaml", ] [[package]] @@ -3273,6 +3268,19 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -3680,6 +3688,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "uuid" version = "1.7.0" @@ -4471,15 +4485,6 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index a910364..069faed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,8 @@ bevy = { version = "0.13.1", default-features = false, features = ["jpeg", "bevy bevy_xpbd_3d = { version = "0.4.2", default-features = false, features = ["3d", "f64", "parry-f64", "parallel", "async-collider"] } bevy_embedded_assets = "0.10.2" fastrand = "2.0.2" -yaml-rust = "0.4" +serde = "1.0" +serde_yaml = "0.9" [features] dev = ["bevy/dynamic_linking", "bevy/file_watcher"] diff --git a/src/chat.rs b/src/chat.rs index 3ada57f..e880883 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1,6 +1,6 @@ -extern crate yaml_rust; use bevy::prelude::*; -use yaml_rust::{Yaml, YamlLoader}; +use serde_yaml::Value; +use serde::Deserialize; use crate::{audio, hud, settings, world}; pub const CHATS: &[&str] = &[ @@ -67,14 +67,29 @@ pub struct Choice { // This is the only place where any YAML interaction should be happening. #[derive(Resource)] -pub struct ChatDB(Vec); +pub struct ChatDB(Vec); impl ChatDB { pub fn load_from_str(&mut self, yaml_string: &str) -> Result<(), ()> { - if let Ok(mut yaml_data) = YamlLoader::load_from_str(yaml_string) { - self.0.append(&mut yaml_data); - return Ok(()); + let mut count = 0; + for document in serde_yaml::Deserializer::from_str(yaml_string) { + match Value::deserialize(document) { + Ok(yaml_data) => { + if let Value::Sequence(yaml_sequence) = yaml_data { + self.0.push(Value::Sequence(yaml_sequence)); + count += 1; + } + else { + error!("Could not load YAML: {:?}", yaml_data); + } + } + Err(error) => { + dbg!(error); + return Err(()); + } + } } - return Err(()); + info!("Loaded {count} conversations"); + return Ok(()); } pub fn get_chat_by_id(&self, id: &String) -> Result { @@ -95,11 +110,11 @@ impl ChatDB { return Err(format!("No chat with the conversation ID `{id}` was found.")); } - fn search_choice(&self, yaml: &Yaml) -> Option { + fn search_choice(&self, yaml: Option<&Value>) -> Option { let non_choice_tokens = NON_CHOICE_TOKENS.to_vec(); - if let Some(hash) = yaml.as_hash() { + if let Some(Value::Mapping(hash)) = yaml { for key in hash.keys() { - if let Yaml::String(key) = key { + if let Value::String(key) = key { if non_choice_tokens.contains(&key.as_str()) { continue; } @@ -121,13 +136,16 @@ impl ChatDB { position[index] += 1; } - fn at(&self, id: usize, position: Vec) -> Option { + fn at(&self, id: usize, position: &Vec) -> Option<&Value> { + if let Some(Value::Sequence(seq)) = self.0.get(id) { + return Some(&seq[position[0]]); // TODO: panic + } return None; } pub fn advance_chat(&self, chat: &mut Chat, event: &mut EventWriter) { event.send(ChatEvent::DespawnAllChoices); - let conv = &self.0[chat.id].as_vec(); + let conv = &self.0.get(chat.id); if conv.is_none() { return; } @@ -140,7 +158,7 @@ impl ChatDB { event.send(ChatEvent::DespawnAllChats); return; } - else if let Some(_) = self.search_choice(&conv[chat.position[0]]) { + else if let Some(_) = self.search_choice(self.at(chat.id, &chat.position)) { is_skipping_through = true; } else if let Some(message) = conv[chat.position[0]].as_str() { @@ -152,10 +170,10 @@ impl ChatDB { self.pointer_lookahead(&mut pos); let mut key: usize = 0; loop { - if is_skipping_through || pos[0] >= conv.len() { + if is_skipping_through /*|| pos[0] >= conv.len()*/ { // TODO: out of bounds checking break; } - if let Some(choice) = self.search_choice(&conv[pos[0]]) { + if let Some(choice) = self.search_choice(self.at(chat.id, &pos)) { event.send(ChatEvent::SpawnChoice(choice, key)); key += 1; }