use hocon_rs::Value;
use crate::collision_kind::CollisionKind;
fn parse_single_collision_kind(s: &str) -> Result<CollisionKind, String> {
let trimmed = s.trim();
match trimmed {
"Self" => Ok(CollisionKind::SELF),
"SameKind" => Ok(CollisionKind::SAME_KIND),
"Other" => Ok(CollisionKind::OTHER),
_ => Err(format!(
"Unknown CollisionKind: '{}'. Expected 'Self', 'SameKind', or 'Other'",
trimmed
)),
}
}
pub fn parse_collision_kind(value: &Value) -> Result<CollisionKind, String> {
match value {
Value::String(s) => {
let parts: Vec<&str> = s.split('|').collect();
let mut result = CollisionKind::empty();
for part in parts {
let flag = parse_single_collision_kind(part)?;
result |= flag;
}
Ok(result)
}
_ => Err(format!(
"CollisionKind parser expects a string (e.g., 'Self' or 'Self | Other'), got: {:?}",
value
)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use hocon_rs::Config;
#[test]
fn test_parse_self() {
let hocon_str = r#"kind = "Self""#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value).unwrap();
assert_eq!(result, CollisionKind::SELF);
}
#[test]
fn test_parse_same_kind() {
let hocon_str = r#"kind = "SameKind""#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value).unwrap();
assert_eq!(result, CollisionKind::SAME_KIND);
}
#[test]
fn test_parse_other() {
let hocon_str = r#"kind = "Other""#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value).unwrap();
assert_eq!(result, CollisionKind::OTHER);
}
#[test]
fn test_parse_unquoted_string() {
let hocon_str = r#"kind = Self"#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value).unwrap();
assert_eq!(result, CollisionKind::SELF);
}
#[test]
fn test_parse_pipe_two_flags() {
let hocon_str = r#"kind = "Self | Other""#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value).unwrap();
assert_eq!(result, CollisionKind::SELF | CollisionKind::OTHER);
assert!(result.contains(CollisionKind::SELF));
assert!(result.contains(CollisionKind::OTHER));
assert!(!result.contains(CollisionKind::SAME_KIND));
}
#[test]
fn test_parse_pipe_all_flags() {
let hocon_str = r#"kind = "Self | SameKind | Other""#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value).unwrap();
assert!(result.contains(CollisionKind::SELF));
assert!(result.contains(CollisionKind::SAME_KIND));
assert!(result.contains(CollisionKind::OTHER));
}
#[test]
fn test_parse_unknown_collision_kind() {
let hocon_str = r#"kind = "UnknownKind""#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value);
assert!(result.is_err());
if let Err(err) = result {
assert!(err.contains("Unknown CollisionKind"));
}
}
#[test]
fn test_parse_invalid_type() {
let hocon_str = r#"kind = 123"#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value);
assert!(result.is_err());
if let Err(err) = result {
assert!(err.contains("expects a string"));
}
}
#[test]
fn test_parse_pipe_with_spaces() {
let hocon_str = r#"kind = "Self|SameKind""#;
let parsed: Value = Config::parse_str(hocon_str, None).unwrap();
let value = parsed.as_object().unwrap().get("kind").unwrap();
let result = parse_collision_kind(value).unwrap();
assert!(result.contains(CollisionKind::SELF));
assert!(result.contains(CollisionKind::SAME_KIND));
}
}