1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// Named light-grouping schema.
use alloc::string::String;
use alloc::vec::Vec;
/// A named grouping of lights.
///
/// Use `preset` to expand a built-in setup into named
/// [DirectionalLight](#directionallight)/[PointLight](#pointlight) assets
/// (`<rig_name>_<light_name>`), or declare lights directly and list their names
/// in `lights`.
///
/// **Library presets:**
///
/// ```rust
/// # use concinnity_asset::LightRig;
/// LightRig {
/// preset: "rig_outdoor_sun_fill".into(),
/// ..Default::default()
/// };
/// ```
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
#[serde(default)]
pub struct LightRig {
/// Name of a built-in or file-backed preset (e.g. "rig_outdoor_sun_fill").
/// When set, `lights` is ignored.
pub preset: String,
/// Names of existing [DirectionalLight](#directionallight) or
/// [PointLight](#pointlight) assets to include in this rig. Ignored when
/// `preset` is set.
pub lights: Vec<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_blank_rig_groups_nothing() {
let r = LightRig::default();
assert!(r.preset.is_empty());
assert!(r.lights.is_empty());
}
#[test]
fn an_inline_rig_lists_the_lights_it_groups() {
let r: LightRig = serde_json::from_str(r#"{"lights":["sun","fill"]}"#).unwrap();
assert_eq!(r.lights, ["sun", "fill"]);
assert!(r.preset.is_empty());
}
#[test]
fn a_preset_rig_leaves_the_light_list_empty() {
let r: LightRig = serde_json::from_str(r#"{"preset":"rig_outdoor_sun_fill"}"#).unwrap();
assert_eq!(r.preset, "rig_outdoor_sun_fill");
assert!(r.lights.is_empty());
let bytes = postcard::to_allocvec(&r).unwrap();
let back: LightRig = postcard::from_bytes(&bytes).unwrap();
assert_eq!(back.preset, "rig_outdoor_sun_fill");
assert!(back.lights.is_empty());
}
}