hiroz_schema/
type_description.rs1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize, Default)]
13pub struct TypeDescriptionMsg {
14 pub type_description: TypeDescription,
16 pub referenced_type_descriptions: Vec<TypeDescription>,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize, Default)]
24pub struct TypeDescription {
25 pub type_name: String,
27 pub fields: Vec<FieldDescription>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct FieldDescription {
36 pub name: String,
38 #[serde(rename = "type")]
40 pub field_type: FieldTypeDescription,
41 #[serde(default)]
43 pub default_value: String,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize, Default)]
50pub struct FieldTypeDescription {
51 pub type_id: u8,
53 pub capacity: u64,
55 pub string_capacity: u64,
57 pub nested_type_name: String,
59}
60
61impl FieldTypeDescription {
62 pub fn primitive(type_id: u8) -> Self {
64 Self {
65 type_id,
66 capacity: 0,
67 string_capacity: 0,
68 nested_type_name: String::new(),
69 }
70 }
71
72 pub fn nested(type_id: u8, nested_type_name: impl Into<String>) -> Self {
74 Self {
75 type_id,
76 capacity: 0,
77 string_capacity: 0,
78 nested_type_name: nested_type_name.into(),
79 }
80 }
81
82 pub fn array(type_id: u8, capacity: u64) -> Self {
84 Self {
85 type_id,
86 capacity,
87 string_capacity: 0,
88 nested_type_name: String::new(),
89 }
90 }
91
92 pub fn nested_array(type_id: u8, capacity: u64, nested_type_name: impl Into<String>) -> Self {
94 Self {
95 type_id,
96 capacity,
97 string_capacity: 0,
98 nested_type_name: nested_type_name.into(),
99 }
100 }
101}
102
103#[derive(Serialize)]
105pub struct FieldDescriptionForHash<'a> {
106 pub name: &'a str,
108 #[serde(rename = "type")]
110 pub field_type: &'a FieldTypeDescription,
111}
112
113#[derive(Serialize)]
115pub struct TypeDescriptionForHash<'a> {
116 pub type_name: &'a str,
118 pub fields: Vec<FieldDescriptionForHash<'a>>,
120}
121
122#[derive(Serialize)]
124pub struct TypeDescriptionMsgForHash<'a> {
125 pub type_description: TypeDescriptionForHash<'a>,
127 pub referenced_type_descriptions: Vec<TypeDescriptionForHash<'a>>,
129}
130
131pub fn to_hash_version(msg: &TypeDescriptionMsg) -> TypeDescriptionMsgForHash<'_> {
133 TypeDescriptionMsgForHash {
134 type_description: TypeDescriptionForHash {
135 type_name: &msg.type_description.type_name,
136 fields: msg
137 .type_description
138 .fields
139 .iter()
140 .map(|f| FieldDescriptionForHash {
141 name: &f.name,
142 field_type: &f.field_type,
143 })
144 .collect(),
145 },
146 referenced_type_descriptions: msg
147 .referenced_type_descriptions
148 .iter()
149 .map(|td| TypeDescriptionForHash {
150 type_name: &td.type_name,
151 fields: td
152 .fields
153 .iter()
154 .map(|f| FieldDescriptionForHash {
155 name: &f.name,
156 field_type: &f.field_type,
157 })
158 .collect(),
159 })
160 .collect(),
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167
168 #[test]
169 fn test_type_description_serialization() {
170 let td = TypeDescription {
171 type_name: "std_msgs/msg/String".to_string(),
172 fields: vec![FieldDescription {
173 name: "data".to_string(),
174 field_type: FieldTypeDescription::primitive(17), default_value: String::new(),
176 }],
177 };
178
179 let json = serde_json::to_string(&td).unwrap();
180 assert!(json.contains("std_msgs/msg/String"));
181 assert!(json.contains("data"));
182 }
183
184 #[test]
185 fn test_field_type_description_builders() {
186 let prim = FieldTypeDescription::primitive(6); assert_eq!(prim.type_id, 6);
188 assert_eq!(prim.capacity, 0);
189 assert!(prim.nested_type_name.is_empty());
190
191 let nested = FieldTypeDescription::nested(1, "geometry_msgs/msg/Point");
192 assert_eq!(nested.type_id, 1);
193 assert_eq!(nested.nested_type_name, "geometry_msgs/msg/Point");
194
195 let arr = FieldTypeDescription::array(54, 10); assert_eq!(arr.type_id, 54);
197 assert_eq!(arr.capacity, 10);
198 }
199}