use serde::{Deserialize, Serialize};
use crate::entity::WorldEntity;
use crate::identity::{CreationId, EntityId};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "snake_case")]
pub enum SemanticCategory {
Building,
Vegetation,
Furniture,
Vehicle,
Character,
Terrain,
Decoration,
Light,
Audio,
Custom(String),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct CreationDef {
pub id: CreationId,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub semantic_category: Option<SemanticCategory>,
#[serde(default)]
pub bbox_half: [f32; 3],
#[serde(default)]
#[cfg_attr(feature = "schema", schemars(extend("x-entity-ref" = "id")))]
pub entities: Vec<EntityId>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub parts: Vec<WorldEntity>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn creation_roundtrip() {
let c = CreationDef {
id: CreationId(1),
name: "campfire_setup".to_string(),
semantic_category: Some(SemanticCategory::Decoration),
bbox_half: [2.0, 1.5, 2.0],
entities: vec![EntityId(10), EntityId(11), EntityId(12)],
parts: Vec::new(),
};
let json = serde_json::to_string(&c).unwrap();
let back: CreationDef = serde_json::from_str(&json).unwrap();
assert_eq!(c, back);
}
#[test]
fn custom_category() {
let c = SemanticCategory::Custom("portal".to_string());
let json = serde_json::to_string(&c).unwrap();
let back: SemanticCategory = serde_json::from_str(&json).unwrap();
assert_eq!(c, back);
}
}