use hocon_rs::Value;
use crate::lc_action::LcAction;
use crate::lc_entity_type::LcEntityType;
use crate::lc_single_action_config::{LcSingleActionConfig, LcConfigRaw};
use crate::parser::lc_config_parser::{parse_lc_config, parse_lc_config_raw};
pub fn parse_lc_config_list_raw(value: &Value) -> Result<Vec<LcConfigRaw>, String> {
match value {
Value::Array(array) => {
let mut configs = Vec::with_capacity(array.len());
for (index, item) in array.iter().enumerate() {
let config = parse_lc_config_raw(item)
.map_err(|e| format!("Failed to parse LcaConfig at index {}: {}", index, e))?;
configs.push(config);
}
Ok(configs)
}
_ => Err(format!(
"LcaConfig list parser expects an array, got: {:?}",
value
)),
}
}
pub fn parse_lc_config_list<T, F>(
value: &Value,
parse_effect: &F,
) -> Result<Vec<LcSingleActionConfig<T>>, String>
where
T: LcEntityType,
F: Fn(&Value) -> Result<Box<dyn LcAction<T>>, String>,
{
match value {
Value::Array(array) => {
let mut configs = Vec::with_capacity(array.len());
for (index, item) in array.iter().enumerate() {
let config = parse_lc_config(item, parse_effect)
.map_err(|e| format!("Failed to parse LcaConfig at index {}: {}", index, e))?;
configs.push(config);
}
Ok(configs)
}
_ => Err(format!(
"LcaConfig list parser expects an array, got: {:?}",
value
)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::collision_kind::CollisionKind;
use hocon_rs::Config;
#[test]
fn test_parse_empty_array() {
let hocon_str = r#"list = []"#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("list").unwrap();
let result = parse_lc_config_list_raw(value).unwrap();
assert_eq!(result.len(), 0);
}
#[test]
fn test_parse_simple_format_only_raw() {
let hocon_str = r#"
list = [
{ DealDamage: 10 }
{ DealDamage: 20 }
{ DealDamage: 30 }
]
"#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("list").unwrap();
let result = parse_lc_config_list_raw(value).unwrap();
assert_eq!(result.len(), 3);
assert_eq!(result[0].collision, CollisionKind::OTHER);
assert_eq!(result[1].collision, CollisionKind::OTHER);
assert_eq!(result[2].collision, CollisionKind::OTHER);
}
#[test]
fn test_parse_full_format_only_raw() {
let hocon_str = r#"
list = [
{ lca: { DealDamage: 10 }, collision: "Self" }
{ lca: { DealDamage: 20 }, collision: "SameKind" }
{ lca: { DealDamage: 30 }, collision: "Other" }
]
"#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("list").unwrap();
let result = parse_lc_config_list_raw(value).unwrap();
assert_eq!(result.len(), 3);
assert_eq!(result[0].collision, CollisionKind::SELF);
assert_eq!(result[1].collision, CollisionKind::SAME_KIND);
assert_eq!(result[2].collision, CollisionKind::OTHER);
}
#[test]
fn test_parse_mixed_formats_raw() {
let hocon_str = r#"
list = [
{ DealDamage: 10 }
{ lca: { DealDamage: 20 }, collision: "Self" }
{ DealDamage: 30 }
{ lca: { DealDamage: 40 }, collision: "SameKind" }
{ DealDamage: 50 }
]
"#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("list").unwrap();
let result = parse_lc_config_list_raw(value).unwrap();
assert_eq!(result.len(), 5);
assert_eq!(result[0].collision, CollisionKind::OTHER);
assert_eq!(result[1].collision, CollisionKind::SELF);
assert_eq!(result[2].collision, CollisionKind::OTHER);
assert_eq!(result[3].collision, CollisionKind::SAME_KIND);
assert_eq!(result[4].collision, CollisionKind::OTHER);
}
#[test]
fn test_parse_not_an_array() {
let hocon_str = r#"{ DealDamage: 10 }"#;
let value: Value = Config::parse_str(hocon_str, None).unwrap();
let result = parse_lc_config_list_raw(&value);
assert!(result.is_err());
if let Err(err) = result {
assert!(err.contains("expects an array"));
}
}
}