sdformat_rs/
deserialize.rs

1use num_traits::Zero;
2use serde::Deserialize;
3use std::str::FromStr;
4
5macro_rules! value_node {
6    ( $name:ident, $t:ty ) => {
7        #[derive(Debug, Deserialize, Default, Clone)]
8        pub struct $name {
9            #[serde(rename = "$value")]
10            pub value: $t,
11        }
12    };
13}
14
15value_node!(Mass, f64);
16value_node!(Ixx, f64);
17value_node!(Ixy, f64);
18value_node!(Ixz, f64);
19value_node!(Iyy, f64);
20value_node!(Iyz, f64);
21value_node!(Izz, f64);
22value_node!(Radius, f64);
23value_node!(Length, f64);
24value_node!(Name, String);
25value_node!(Uri, String);
26value_node!(Damping, f64);
27value_node!(Friction, f64);
28value_node!(Lower, f64);
29value_node!(Upper, f64);
30value_node!(UseParentModelFrame, bool);
31value_node!(Parent, String);
32value_node!(Child, String);
33
34pub fn string_to_array<T, const N: usize>(s: &str) -> Option<[T; N]>
35where
36    T: Zero + FromStr + Copy,
37{
38    let vec = s
39        .split(' ')
40        .filter_map(|x| x.parse::<T>().ok())
41        .collect::<Vec<_>>();
42    if vec.len() != N {
43        return None;
44    }
45    let mut arr = [T::zero(); N];
46    arr.copy_from_slice(&vec);
47    Some(arr)
48}
49
50mod sdf_fvec6 {
51    use serde::{self, Deserialize, Deserializer};
52    pub fn deserialize<'a, D>(deserializer: D) -> Result<[f64; 6], D::Error>
53    where
54        D: Deserializer<'a>,
55    {
56        let s = String::deserialize(deserializer)?;
57        let some_arr = crate::string_to_array::<f64, 6>(&s);
58        if let Some(arr) = some_arr {
59            Ok(arr)
60        } else {
61            return Err(serde::de::Error::custom(format!(
62                "failed to parse float array in {}",
63                s
64            )));
65        }
66    }
67}
68
69mod sdf_fvec3 {
70    use serde::{self, Deserialize, Deserializer};
71    pub fn deserialize<'a, D>(deserializer: D) -> Result<[f64; 3], D::Error>
72    where
73        D: Deserializer<'a>,
74    {
75        let s = String::deserialize(deserializer)?;
76        let some_arr = crate::string_to_array::<f64, 3>(&s);
77        if let Some(arr) = some_arr {
78            Ok(arr)
79        } else {
80            return Err(serde::de::Error::custom(format!(
81                "failed to parse float array in {}",
82                s
83            )));
84        }
85    }
86}
87
88mod sdf_ivec3 {
89    use serde::{self, Deserialize, Deserializer};
90    pub fn deserialize<'a, D>(deserializer: D) -> Result<[u32; 3], D::Error>
91    where
92        D: Deserializer<'a>,
93    {
94        let s = String::deserialize(deserializer)?;
95        let some_arr = crate::string_to_array::<u32, 3>(&s);
96        if let Some(arr) = some_arr {
97            Ok(arr)
98        } else {
99            return Err(serde::de::Error::custom(format!(
100                "failed to parse u32 array in {}",
101                s
102            )));
103        }
104    }
105}
106
107#[derive(Debug, Deserialize, Clone)]
108pub struct Pose {
109    #[serde(rename = "$value", with = "sdf_fvec6")]
110    pub value: [f64; 6],
111}
112
113impl Default for Pose {
114    fn default() -> Pose {
115        Pose { value: [0f64; 6] }
116    }
117}
118
119#[derive(Debug, Deserialize, Clone)]
120pub struct Size {
121    #[serde(rename = "$value", with = "sdf_fvec3")]
122    pub value: [f64; 3],
123}
124
125#[derive(Debug, Deserialize, Clone)]
126pub struct Xyz {
127    #[serde(rename = "$value", with = "sdf_ivec3")]
128    pub value: [u32; 3],
129}
130
131#[derive(Debug, Deserialize, Clone)]
132pub struct Inertia {
133    pub ixx: Ixx,
134    pub ixy: Ixy,
135    pub ixz: Ixz,
136    pub iyy: Iyy,
137    pub iyz: Iyz,
138    pub izz: Izz,
139}
140
141#[derive(Debug, Deserialize, Clone)]
142pub struct Inertial {
143    pub pose: Pose,
144    pub inertia: Inertia,
145    pub mass: Mass,
146}
147
148#[derive(Debug, Deserialize, Clone)]
149#[serde(rename_all = "lowercase")]
150pub enum Geometry {
151    Box { size: Size },
152    Cylinder { radius: Radius, length: Length },
153}
154
155impl Default for Geometry {
156    fn default() -> Geometry {
157        Geometry::Box {
158            size: Size {
159                value: [0.0f64, 0.0, 0.0],
160            },
161        }
162    }
163}
164
165#[derive(Debug, Deserialize, Default, Clone)]
166pub struct Collision {
167    pub name: String,
168    pub pose: Pose,
169    pub geometry: Geometry,
170}
171
172#[derive(Debug, Deserialize, Default, Clone)]
173pub struct Script {
174    pub uri: Uri,
175    pub name: Name,
176}
177
178#[derive(Debug, Deserialize, Default, Clone)]
179pub struct Material {
180    pub script: Script,
181}
182
183#[derive(Debug, Deserialize, Default, Clone)]
184pub struct Visual {
185    pub name: String,
186    pub pose: Pose,
187    pub geometry: Geometry,
188    pub material: Material,
189}
190
191#[derive(Debug, Deserialize, Clone)]
192pub struct Link {
193    #[serde(default)]
194    pub pose: Pose,
195    pub inertial: Option<Inertial>,
196    #[serde(rename = "collision", default)]
197    pub collisions: Vec<Collision>,
198    #[serde(rename = "visual", default)]
199    pub visuals: Vec<Visual>,
200}
201
202#[derive(Debug, Deserialize, Clone)]
203pub struct Dynamics {
204    pub damping: Damping,
205    pub friction: Friction,
206}
207
208#[derive(Debug, Deserialize, Clone)]
209pub struct Limit {
210    pub lower: Lower,
211    pub upper: Upper,
212}
213
214#[derive(Debug, Deserialize, Clone)]
215pub struct Axis {
216    pub dynamics: Dynamics,
217    pub limit: Option<Limit>,
218    pub xyz: Xyz,
219    pub use_parent_model_frame: UseParentModelFrame,
220}
221
222#[derive(Debug, Deserialize, Clone)]
223pub struct Joint {
224    pub name: String,
225    #[serde(rename = "type")]
226    pub joint_type: String,
227    pub parent: Parent,
228    pub child: Child,
229    pub axis: Axis,
230}
231
232#[derive(Debug, Deserialize, Clone)]
233pub struct Model {
234    pub name: String,
235    #[serde(rename = "link", default)]
236    pub links: Vec<Link>,
237    #[serde(rename = "joint", default)]
238    pub joints: Vec<Joint>,
239}