diff --git a/crates/runtime/src/dialogue.rs b/crates/runtime/src/dialogue.rs index 2d72c9e2..4e9d94bd 100644 --- a/crates/runtime/src/dialogue.rs +++ b/crates/runtime/src/dialogue.rs @@ -3,6 +3,7 @@ use crate::markup::{DialogueTextProcessor, LineParser, MarkupParseError}; use crate::prelude::*; use log::error; +use std::collections::HashMap; use std::fmt::Debug; use thiserror::Error; use yarnspinner_core::prelude::*; @@ -312,6 +313,22 @@ impl Dialogue { .map(|node| node.tags) } + /// Returns the headers for the node `node_name`. + /// + /// The headers are all the key-value pairs defined in the node's source code + /// including the `tags` and `title` headers. + /// + /// Returns [`None`] if the node is not present in the program. + #[must_use] + pub fn get_headers_for_node(&self, node_name: &str) -> Option> { + self.get_node_logging_errors(node_name).map(|node| { + node.headers + .iter() + .map(|header| (header.key.clone(), header.value.clone())) + .collect() + }) + } + /// Gets a value indicating whether a specified node exists in the [`Program`]. #[must_use] pub fn node_exists(&self, node_name: &str) -> bool { diff --git a/crates/yarnspinner/tests/dialogue_tests.rs b/crates/yarnspinner/tests/dialogue_tests.rs index f659bd70..5f214850 100644 --- a/crates/yarnspinner/tests/dialogue_tests.rs +++ b/crates/yarnspinner/tests/dialogue_tests.rs @@ -3,6 +3,7 @@ //! ## Implementation notes //! `TestDumpingCode` was not ported because `GetByteCode` is not used by a user directly and thus was not implemented at all. +use std::collections::HashMap; use test_base::prelude::*; use yarnspinner::compiler::*; use yarnspinner::runtime::*; @@ -162,6 +163,27 @@ fn test_getting_tags() { assert_eq!(tags, vec!["rawText"]); } +#[test] +fn test_getting_headers() { + let path = test_data_path().join("Example.yarn"); + let mut test_base = TestBase::new(); + + let result = Compiler::new().read_file(path).compile().unwrap(); + + test_base = test_base.with_program(result.program.unwrap()); + let dialogue = &test_base.dialogue; + + let headers = dialogue.get_headers_for_node("LearnMore").unwrap(); + + let mut expected_headers = HashMap::new(); + expected_headers.insert("title".to_string(), "LearnMore".to_string()); + expected_headers.insert("tags".to_string(), "rawText".to_string()); + expected_headers.insert("colorID".to_string(), "0".to_string()); + expected_headers.insert("position".to_string(), "763,472".to_string()); + + assert_eq!(headers, expected_headers); +} + /// ## Implementation note /// Corresponds to `TestPrepareForLine` #[test]