Skip to main content

sim_lib_scene/
citizen.rs

1use sim_citizen_derive::Citizen;
2use sim_kernel::{Expr, Result, Symbol};
3
4use crate::node;
5
6/// A validated Scene wrapped as a runtime Citizen object.
7#[derive(Clone, Debug, PartialEq, Citizen)]
8#[citizen(symbol = "scene/Scene", version = 1)]
9pub struct SceneDescriptor {
10    #[citizen(with = "scene_expr")]
11    scene: Expr,
12}
13
14impl SceneDescriptor {
15    /// Builds a descriptor from a Scene expression, validating it.
16    ///
17    /// # Errors
18    ///
19    /// Returns an error when `scene` is not a well-formed Scene expression.
20    pub fn from_expr(scene: Expr) -> Result<Self> {
21        scene_expr::decode(&scene)?;
22        Ok(Self { scene })
23    }
24
25    /// Returns the underlying Scene expression.
26    pub fn as_expr(&self) -> &Expr {
27        &self.scene
28    }
29}
30
31impl Default for SceneDescriptor {
32    fn default() -> Self {
33        Self::from_expr(node(
34            "text",
35            vec![("text", Expr::String("citizen scene".to_owned()))],
36        ))
37        .expect("default scene descriptor should be valid")
38    }
39}
40
41/// Returns the class symbol for the Scene descriptor Citizen.
42pub fn scene_descriptor_class_symbol() -> Symbol {
43    Symbol::qualified("scene", "Scene")
44}
45
46pub(crate) mod scene_expr {
47    use sim_kernel::{Error, Expr, Result};
48
49    use crate::validate_scene;
50
51    pub fn encode(expr: &Expr) -> Expr {
52        expr.clone()
53    }
54
55    pub fn decode(expr: &Expr) -> Result<Expr> {
56        validate_scene(expr).map_err(|error| Error::Eval(format!("malformed scene: {error}")))?;
57        Ok(expr.clone())
58    }
59}