fbx_dom/objects/
limb_node.rs1use std::collections::HashMap;
4use std::convert::TryFrom;
5
6use crate::{OwnedObject, Property};
7
8use super::{FbxObjectTag, FbxTypeMismatch, fbx_object_tag};
9
10const PROP_LIMB_LENGTH: &str = "LimbLength";
11const PROP_SIZE: &str = "Size";
12
13#[derive(Debug, PartialEq)]
14pub struct LimbNode(pub OwnedObject);
15
16impl LimbNode {
17 pub fn inner(&self) -> &OwnedObject {
18 &self.0
19 }
20
21 pub fn into_inner(self) -> OwnedObject {
22 self.0
23 }
24
25 pub fn properties(&self) -> &HashMap<String, Property> {
27 &self.0.properties
28 }
29
30 pub fn property(&self, name: &str) -> Option<&Property> {
31 self.0.properties.get(name)
32 }
33
34 pub fn limb_length(&self) -> f32 {
36 match self.property(PROP_LIMB_LENGTH) {
37 Some(Property::Float(v)) => *v,
38 _ => 0.0,
39 }
40 }
41
42 pub fn size(&self) -> f32 {
44 match self.property(PROP_SIZE) {
45 Some(Property::Float(v)) => *v,
46 _ => 0.0,
47 }
48 }
49}
50
51impl TryFrom<OwnedObject> for LimbNode {
52 type Error = FbxTypeMismatch;
53
54 fn try_from(o: OwnedObject) -> Result<Self, Self::Error> {
55 match fbx_object_tag(&o) {
56 FbxObjectTag::LimbNode => Ok(LimbNode(o)),
57 _ => Err(FbxTypeMismatch::wrong_object_kind(
58 o,
59 "LimbNode".to_string(),
60 )),
61 }
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use std::collections::HashMap;
68 use std::convert::TryFrom;
69
70 use crate::objects::{NODE_ATTRIBUTE_LIMB_NODE_CLASS_NAME, NODE_ATTRIBUTE_TYPE_NAME};
71 use crate::{OwnedObject, Property};
72
73 use super::LimbNode;
74
75 #[test]
76 fn property_accessors_return_owned_object_properties() {
77 let mut properties = HashMap::new();
78 properties.insert("LimbLength".to_string(), Property::Float(10.0));
79 let o = OwnedObject {
80 object_index: 99,
81 name: "Limb".into(),
82 type_name: NODE_ATTRIBUTE_TYPE_NAME.into(),
83 class_name: NODE_ATTRIBUTE_LIMB_NODE_CLASS_NAME.into(),
84 properties,
85 attributes: HashMap::new(),
86 connected_object_ids: vec![],
87 object_property_targets: vec![],
88 pp_property_targets: HashMap::new(),
89 };
90 let limb_node = LimbNode::try_from(o).unwrap();
91 assert_eq!(
92 limb_node.property("LimbLength"),
93 Some(&Property::Float(10.0))
94 );
95 assert_eq!(limb_node.properties().len(), 1);
96 }
97
98 #[test]
99 fn typed_accessors_return_defaults_and_values() {
100 let o_default = OwnedObject {
101 object_index: 99,
102 name: "Limb".into(),
103 type_name: NODE_ATTRIBUTE_TYPE_NAME.into(),
104 class_name: NODE_ATTRIBUTE_LIMB_NODE_CLASS_NAME.into(),
105 properties: HashMap::new(),
106 attributes: HashMap::new(),
107 connected_object_ids: vec![],
108 object_property_targets: vec![],
109 pp_property_targets: HashMap::new(),
110 };
111 let limb_default = LimbNode::try_from(o_default).unwrap();
112 assert_eq!(limb_default.limb_length(), 0.0);
113 assert_eq!(limb_default.size(), 0.0);
114
115 let mut properties = HashMap::new();
116 properties.insert("LimbLength".to_string(), Property::Float(8.5));
117 properties.insert("Size".to_string(), Property::Float(2.0));
118 let o_values = OwnedObject {
119 object_index: 100,
120 name: "Limb".into(),
121 type_name: NODE_ATTRIBUTE_TYPE_NAME.into(),
122 class_name: NODE_ATTRIBUTE_LIMB_NODE_CLASS_NAME.into(),
123 properties,
124 attributes: HashMap::new(),
125 connected_object_ids: vec![],
126 object_property_targets: vec![],
127 pp_property_targets: HashMap::new(),
128 };
129 let limb_values = LimbNode::try_from(o_values).unwrap();
130 assert_eq!(limb_values.limb_length(), 8.5);
131 assert_eq!(limb_values.size(), 2.0);
132 }
133}