1use std::collections::HashMap;
2
3use quick_xml::{
4 events::{BytesDecl, BytesEnd, BytesStart, BytesText, Event},
5 Writer,
6};
7use smpte_types::Auid;
8
9use crate::{
10 definition::{
11 CharacterTypeDef, ClassDefinition, Definition, EnumerationElement, EnumerationTypeDef,
12 ExtEnumTypeDef, FixedArrayTypeDef, FloatTypeDef, IndirectTypeDef, IntegerTypeDef,
13 LensSerialFloatTypeDef, OpaqueTypeDef, PropertyDefinition, RecordMember, RecordTypeDef,
14 RenameTypeDef, SetTypeDef, StreamTypeDef, StringTypeDef, StrongReferenceTypeDef,
15 TypeDefinition, VariableArrayTypeDef, WeakReferenceTypeDef,
16 },
17 resolver::DefinitionResolver,
18 DictError,
19};
20
21const NS: &str = "http://www.smpte-ra.org/schemas/2001-1b/2013/metadict";
22
23#[derive(Debug, Default)]
27pub struct MetaDictionary {
28 pub scheme_id: String,
29 pub scheme_uri: String,
30 definitions_by_auid: HashMap<Auid, Definition>,
31 definitions_by_symbol: HashMap<String, Auid>,
32 members_of: HashMap<Auid, Vec<Auid>>,
34 subclasses_of: HashMap<Auid, Vec<Auid>>,
36}
37
38impl MetaDictionary {
39 pub fn new(scheme_uri: impl Into<String>, scheme_id: impl Into<String>) -> Self {
40 MetaDictionary {
41 scheme_uri: scheme_uri.into(),
42 scheme_id: scheme_id.into(),
43 ..Default::default()
44 }
45 }
46
47 pub fn from_xml(xml: &[u8]) -> Result<Self, DictError> {
50 let text = std::str::from_utf8(xml).map_err(|e| DictError::Xml(e.to_string()))?;
51 let doc = roxmltree::Document::parse(text).map_err(|e| DictError::Xml(e.to_string()))?;
52 let root = doc.root_element(); let scheme_id = child_text(&root, "SchemeID").unwrap_or_default();
55 let scheme_uri = child_text(&root, "SchemeURI").unwrap_or_default();
56 let mut dict = MetaDictionary::new(scheme_uri, scheme_id);
57
58 if let Some(meta_defs) = root
59 .children()
60 .find(|n| n.tag_name().name() == "MetaDefinitions")
61 {
62 for node in meta_defs.children().filter(|n| n.is_element()) {
63 if let Some(def) = parse_meta_definition(&node)
64 .map_err(|e| DictError::Xml(format!("in <{}>: {e}", node.tag_name().name())))?
65 {
66 dict.add(def)?;
67 }
68 }
69 }
70 Ok(dict)
71 }
72
73 pub fn add(&mut self, def: Definition) -> Result<(), DictError> {
76 let id = *def.identification();
77 let sym = def.symbol().to_owned();
78
79 match &def {
81 Definition::Property(p) => {
82 self.members_of.entry(p.member_of).or_default().push(id);
83 }
84 Definition::Class(c) => {
85 if let Some(parent) = c.parent_class {
86 self.subclasses_of.entry(parent).or_default().push(id);
87 }
88 }
89 Definition::Type(_) => {}
90 }
91
92 self.definitions_by_symbol.insert(sym, id);
93 self.definitions_by_auid.insert(id, def);
94 Ok(())
95 }
96
97 pub fn definition_count(&self) -> usize {
100 self.definitions_by_auid.len()
101 }
102
103 pub fn all_definitions(&self) -> impl Iterator<Item = &Definition> {
104 self.definitions_by_auid.values()
105 }
106
107 pub fn get_definition_by_symbol(&self, symbol: &str) -> Option<&Definition> {
108 self.definitions_by_symbol
109 .get(symbol)
110 .and_then(|id| self.definitions_by_auid.get(id))
111 }
112
113 pub fn to_xml(&self) -> Result<Vec<u8>, DictError> {
116 let mut buf = Vec::new();
117 let mut w = Writer::new_with_indent(&mut buf, b' ', 2);
118
119 w.write_event(Event::Decl(BytesDecl::new("1.0", Some("UTF-8"), None)))
120 .map_err(|e| DictError::Xml(e.to_string()))?;
121
122 let mut root = BytesStart::new("Extension");
123 root.push_attribute(("xmlns", NS));
124 w.write_event(Event::Start(root))
125 .map_err(|e| DictError::Xml(e.to_string()))?;
126
127 write_simple(&mut w, "SchemeID", &self.scheme_id)?;
128 write_simple(&mut w, "SchemeURI", &self.scheme_uri)?;
129
130 w.write_event(Event::Start(BytesStart::new("MetaDefinitions")))
131 .map_err(|e| DictError::Xml(e.to_string()))?;
132
133 for def in self.definitions_by_auid.values() {
134 write_definition(&mut w, def)?;
135 }
136
137 w.write_event(Event::End(BytesEnd::new("MetaDefinitions")))
138 .map_err(|e| DictError::Xml(e.to_string()))?;
139 w.write_event(Event::End(BytesEnd::new("Extension")))
140 .map_err(|e| DictError::Xml(e.to_string()))?;
141
142 Ok(buf)
143 }
144}
145
146impl DefinitionResolver for MetaDictionary {
147 fn get_definition(&self, id: &Auid) -> Option<&Definition> {
148 self.definitions_by_auid.get(id)
149 }
150 fn get_subclasses_of(&self, class: &ClassDefinition) -> Vec<Auid> {
151 self.subclasses_of
152 .get(&class.identification)
153 .cloned()
154 .unwrap_or_default()
155 }
156 fn get_members_of(&self, class: &ClassDefinition) -> Vec<Auid> {
157 self.members_of
158 .get(&class.identification)
159 .cloned()
160 .unwrap_or_default()
161 }
162}
163
164#[derive(Debug, Default)]
168pub struct MetaDictionaryCollection {
169 dictionaries: Vec<MetaDictionary>,
170 index: HashMap<Auid, usize>,
171}
172
173impl MetaDictionaryCollection {
174 pub fn new() -> Self {
175 Self::default()
176 }
177
178 pub fn add(&mut self, dict: MetaDictionary) -> Result<(), DictError> {
179 let idx = self.dictionaries.len();
180 for id in dict.definitions_by_auid.keys() {
181 self.index.entry(*id).or_insert(idx);
182 }
183 self.dictionaries.push(dict);
184 Ok(())
185 }
186
187 pub fn from_xml_slices(slices: &[&[u8]]) -> Result<Self, DictError> {
188 let mut coll = Self::new();
189 for xml in slices {
190 coll.add(MetaDictionary::from_xml(xml)?)?;
191 }
192 Ok(coll)
193 }
194
195 pub fn get_definition_by_symbol(&self, symbol: &str) -> Option<&Definition> {
196 self.dictionaries
197 .iter()
198 .find_map(|d| d.get_definition_by_symbol(symbol))
199 }
200}
201
202impl DefinitionResolver for MetaDictionaryCollection {
203 fn get_definition(&self, id: &Auid) -> Option<&Definition> {
204 self.index
205 .get(id)
206 .and_then(|&i| self.dictionaries.get(i))
207 .and_then(|d| d.definitions_by_auid.get(id))
208 }
209 fn get_subclasses_of(&self, class: &ClassDefinition) -> Vec<Auid> {
210 self.dictionaries
211 .iter()
212 .flat_map(|d| d.get_subclasses_of(class))
213 .collect()
214 }
215 fn get_members_of(&self, class: &ClassDefinition) -> Vec<Auid> {
216 self.dictionaries
217 .iter()
218 .flat_map(|d| d.get_members_of(class))
219 .collect()
220 }
221}
222
223fn child_text(node: &roxmltree::Node<'_, '_>, name: &str) -> Option<String> {
226 node.children()
227 .find(|n| n.tag_name().name() == name)
228 .and_then(|n| n.text())
229 .map(str::to_owned)
230}
231
232fn required_auid(
233 node: &roxmltree::Node<'_, '_>,
234 field: &'static str,
235 ctx: &str,
236) -> Result<Auid, DictError> {
237 let s =
238 child_text(node, field).ok_or_else(|| DictError::MissingField(field, ctx.to_owned()))?;
239 Auid::from_urn(&s).map_err(|e| DictError::Xml(format!("bad AUID in <{field}> of {ctx}: {e}")))
240}
241
242fn optional_auid(node: &roxmltree::Node<'_, '_>, field: &str) -> Result<Option<Auid>, DictError> {
243 if let Some(s) = child_text(node, field) {
244 Ok(Some(Auid::from_urn(&s).map_err(|e| {
245 DictError::Xml(format!("bad AUID in <{field}>: {e}"))
246 })?))
247 } else {
248 Ok(None)
249 }
250}
251
252fn required_str(
253 node: &roxmltree::Node<'_, '_>,
254 field: &'static str,
255 ctx: &str,
256) -> Result<String, DictError> {
257 child_text(node, field).ok_or_else(|| DictError::MissingField(field, ctx.to_owned()))
258}
259
260fn parse_bool(s: &str) -> bool {
261 s.eq_ignore_ascii_case("true")
262}
263
264fn parse_meta_definition(node: &roxmltree::Node<'_, '_>) -> Result<Option<Definition>, DictError> {
267 let tag = node.tag_name().name();
268 let id_str = match child_text(node, "Identification") {
269 Some(s) => s,
270 None => return Ok(None), };
272 let ctx = format!("{tag}:{id_str}");
273
274 let ident = Auid::from_urn(&id_str).map_err(|e| DictError::Xml(format!("{ctx}: {e}")))?;
275 let symbol = required_str(node, "Symbol", &ctx)?;
276 let _name = child_text(node, "Name").unwrap_or_default();
277
278 match tag {
279 "ClassDefinition" => {
280 let parent_class = optional_auid(node, "ParentClass")?;
281 let is_concrete = child_text(node, "IsConcrete")
282 .as_deref()
283 .map(parse_bool)
284 .unwrap_or(true);
285 Ok(Some(Definition::Class(ClassDefinition {
286 identification: ident,
287 symbol,
288 namespace: String::new(),
289 parent_class,
290 is_concrete,
291 })))
292 }
293
294 "PropertyDefinition" => {
295 let prop_type = required_auid(node, "Type", &ctx)?;
296 let member_of = required_auid(node, "MemberOf", &ctx)?;
297 let is_optional = child_text(node, "IsOptional")
298 .as_deref()
299 .map(parse_bool)
300 .unwrap_or(false);
301 let is_unique = child_text(node, "IsUniqueIdentifier")
302 .as_deref()
303 .map(parse_bool)
304 .unwrap_or(false);
305 let local_id: u16 = child_text(node, "LocalIdentification")
306 .as_deref()
307 .and_then(|s| s.parse().ok())
308 .unwrap_or(0);
309 Ok(Some(Definition::Property(PropertyDefinition {
310 identification: ident,
311 symbol,
312 namespace: String::new(),
313 member_of,
314 property_type: prop_type,
315 is_optional,
316 is_unique_identifier: is_unique,
317 local_identification: local_id,
318 })))
319 }
320
321 "TypeDefinitionInteger" => {
322 let size = child_text(node, "Size")
323 .and_then(|s| s.parse::<u8>().ok())
324 .unwrap_or(1);
325 let is_signed = child_text(node, "IsSigned")
326 .as_deref()
327 .map(parse_bool)
328 .unwrap_or(false);
329 Ok(Some(Definition::Type(TypeDefinition::Integer(
330 IntegerTypeDef {
331 identification: ident,
332 symbol,
333 namespace: String::new(),
334 size,
335 is_signed,
336 },
337 ))))
338 }
339
340 "TypeDefinitionRename" => {
341 let renamed = required_auid(node, "RenamedType", &ctx)?;
342 Ok(Some(Definition::Type(TypeDefinition::Rename(
343 RenameTypeDef {
344 identification: ident,
345 symbol,
346 namespace: String::new(),
347 renamed_type: renamed,
348 },
349 ))))
350 }
351
352 "TypeDefinitionRecord" => {
353 let members = parse_record_members(node)?;
354 Ok(Some(Definition::Type(TypeDefinition::Record(
355 RecordTypeDef {
356 identification: ident,
357 symbol,
358 namespace: String::new(),
359 members,
360 },
361 ))))
362 }
363
364 "TypeDefinitionEnumeration" => {
365 let element_type = required_auid(node, "ElementType", &ctx)?;
366 let elements = parse_enum_elements(node)?;
367 Ok(Some(Definition::Type(TypeDefinition::Enumeration(
368 EnumerationTypeDef {
369 identification: ident,
370 symbol,
371 namespace: String::new(),
372 element_type,
373 elements,
374 },
375 ))))
376 }
377
378 "TypeDefinitionExtendibleEnumeration" => {
379 let elements = parse_enum_elements(node)?;
380 Ok(Some(Definition::Type(
381 TypeDefinition::ExtendibleEnumeration(ExtEnumTypeDef {
382 identification: ident,
383 symbol,
384 namespace: String::new(),
385 elements,
386 }),
387 )))
388 }
389
390 "TypeDefinitionFixedArray" => {
391 let element_type = required_auid(node, "ElementType", &ctx)?;
392 let element_count = child_text(node, "ElementCount")
393 .and_then(|s| s.parse::<u32>().ok())
394 .unwrap_or(0);
395 Ok(Some(Definition::Type(TypeDefinition::FixedArray(
396 FixedArrayTypeDef {
397 identification: ident,
398 symbol,
399 namespace: String::new(),
400 element_type,
401 element_count,
402 },
403 ))))
404 }
405
406 "TypeDefinitionVariableArray" => {
407 let element_type = required_auid(node, "ElementType", &ctx)?;
408 Ok(Some(Definition::Type(TypeDefinition::VariableArray(
409 VariableArrayTypeDef {
410 identification: ident,
411 symbol,
412 namespace: String::new(),
413 element_type,
414 },
415 ))))
416 }
417
418 "TypeDefinitionSet" => {
419 let element_type = required_auid(node, "ElementType", &ctx)?;
420 Ok(Some(Definition::Type(TypeDefinition::Set(SetTypeDef {
421 identification: ident,
422 symbol,
423 namespace: String::new(),
424 element_type,
425 }))))
426 }
427
428 "TypeDefinitionString" => {
429 let element_type = required_auid(node, "ElementType", &ctx)?;
430 Ok(Some(Definition::Type(TypeDefinition::String(
431 StringTypeDef {
432 identification: ident,
433 symbol,
434 namespace: String::new(),
435 element_type,
436 },
437 ))))
438 }
439
440 "TypeDefinitionCharacter" => Ok(Some(Definition::Type(TypeDefinition::Character(
441 CharacterTypeDef {
442 identification: ident,
443 symbol,
444 namespace: String::new(),
445 },
446 )))),
447
448 "TypeDefinitionStream" => Ok(Some(Definition::Type(TypeDefinition::Stream(
449 StreamTypeDef {
450 identification: ident,
451 symbol,
452 namespace: String::new(),
453 },
454 )))),
455
456 "TypeDefinitionIndirect" => Ok(Some(Definition::Type(TypeDefinition::Indirect(
457 IndirectTypeDef {
458 identification: ident,
459 symbol,
460 namespace: String::new(),
461 },
462 )))),
463
464 "TypeDefinitionOpaque" => Ok(Some(Definition::Type(TypeDefinition::Opaque(
465 OpaqueTypeDef {
466 identification: ident,
467 symbol,
468 namespace: String::new(),
469 },
470 )))),
471
472 "TypeDefinitionStrongObjectReference" => {
473 let referenced = required_auid(node, "ReferencedType", &ctx)?;
474 Ok(Some(Definition::Type(TypeDefinition::StrongReference(
475 StrongReferenceTypeDef {
476 identification: ident,
477 symbol,
478 namespace: String::new(),
479 referenced_type: referenced,
480 },
481 ))))
482 }
483
484 "TypeDefinitionWeakObjectReference" => {
485 let referenced = required_auid(node, "ReferencedType", &ctx)?;
486 let target_set = parse_target_set(node)?;
487 Ok(Some(Definition::Type(TypeDefinition::WeakReference(
488 WeakReferenceTypeDef {
489 identification: ident,
490 symbol,
491 namespace: String::new(),
492 referenced_type: referenced,
493 target_set,
494 },
495 ))))
496 }
497
498 "TypeDefinitionFloat" => {
500 let size = child_text(node, "Size")
501 .and_then(|s| s.parse::<u8>().ok())
502 .unwrap_or(4);
503 Ok(Some(Definition::Type(TypeDefinition::Float(
504 FloatTypeDef {
505 identification: ident,
506 symbol,
507 namespace: String::new(),
508 size,
509 },
510 ))))
511 }
512
513 "TypeDefinitionLensSerialFloat" => Ok(Some(Definition::Type(
514 TypeDefinition::LensSerialFloat(LensSerialFloatTypeDef {
515 identification: ident,
516 symbol,
517 namespace: String::new(),
518 }),
519 ))),
520
521 _ => Ok(None), }
523}
524
525fn parse_record_members(node: &roxmltree::Node<'_, '_>) -> Result<Vec<RecordMember>, DictError> {
527 let members_node = match node.children().find(|n| n.tag_name().name() == "Members") {
528 Some(n) => n,
529 None => return Ok(vec![]),
530 };
531
532 let mut names: Vec<String> = Vec::new();
533 let mut types: Vec<String> = Vec::new();
534 for child in members_node.children().filter(|n| n.is_element()) {
535 match child.tag_name().name() {
536 "Name" => names.push(child.text().unwrap_or_default().to_owned()),
537 "Type" => types.push(child.text().unwrap_or_default().to_owned()),
538 _ => {}
539 }
540 }
541 names
542 .into_iter()
543 .zip(types)
544 .map(|(n, t)| {
545 let field_type = Auid::from_urn(&t)
546 .map_err(|e| DictError::Xml(format!("bad member type {t:?}: {e}")))?;
547 Ok(RecordMember {
548 name: n,
549 field_type,
550 })
551 })
552 .collect()
553}
554
555fn parse_enum_elements(
557 node: &roxmltree::Node<'_, '_>,
558) -> Result<Vec<EnumerationElement>, DictError> {
559 let elems_node = match node.children().find(|n| n.tag_name().name() == "Elements") {
560 Some(n) => n,
561 None => return Ok(vec![]),
562 };
563
564 let mut names: Vec<String> = Vec::new();
565 let mut values: Vec<i64> = Vec::new();
566 for child in elems_node.children().filter(|n| n.is_element()) {
567 match child.tag_name().name() {
568 "Name" => names.push(child.text().unwrap_or_default().to_owned()),
569 "Value" => {
570 let v = child
571 .text()
572 .unwrap_or("0")
573 .trim()
574 .parse::<i64>()
575 .unwrap_or(0);
576 values.push(v);
577 }
578 _ => {}
579 }
580 }
581 Ok(names
582 .into_iter()
583 .zip(values)
584 .map(|(name, value)| EnumerationElement { name, value })
585 .collect())
586}
587
588fn parse_target_set(node: &roxmltree::Node<'_, '_>) -> Result<Vec<Auid>, DictError> {
590 let ts = match node.children().find(|n| n.tag_name().name() == "TargetSet") {
591 Some(n) => n,
592 None => return Ok(vec![]),
593 };
594 ts.children()
595 .filter(|n| n.tag_name().name() == "MetaDefRef")
596 .filter_map(|n| n.text())
597 .map(|s| Auid::from_urn(s).map_err(|e| DictError::Xml(e.to_string())))
598 .collect()
599}
600
601fn write_simple<W: std::io::Write>(
604 w: &mut Writer<W>,
605 tag: &str,
606 text: &str,
607) -> Result<(), DictError> {
608 w.write_event(Event::Start(BytesStart::new(tag)))
609 .and_then(|_| w.write_event(Event::Text(BytesText::new(text))))
610 .and_then(|_| w.write_event(Event::End(BytesEnd::new(tag))))
611 .map_err(|e| DictError::Xml(e.to_string()))
612}
613
614fn write_definition<W: std::io::Write>(
615 w: &mut Writer<W>,
616 def: &Definition,
617) -> Result<(), DictError> {
618 match def {
619 Definition::Class(c) => write_class(w, c),
620 Definition::Property(p) => write_property(w, p),
621 Definition::Type(t) => write_type(w, t),
622 }
623}
624
625fn write_class<W: std::io::Write>(w: &mut Writer<W>, c: &ClassDefinition) -> Result<(), DictError> {
626 w.write_event(Event::Start(BytesStart::new("ClassDefinition")))
627 .map_err(|e| DictError::Xml(e.to_string()))?;
628 write_simple(w, "Identification", &c.identification.to_string())?;
629 write_simple(w, "Symbol", &c.symbol)?;
630 write_simple(w, "Name", "")?;
631 if let Some(p) = c.parent_class {
632 write_simple(w, "ParentClass", &p.to_string())?;
633 }
634 write_simple(
635 w,
636 "IsConcrete",
637 if c.is_concrete { "true" } else { "false" },
638 )?;
639 w.write_event(Event::End(BytesEnd::new("ClassDefinition")))
640 .map_err(|e| DictError::Xml(e.to_string()))
641}
642
643fn write_property<W: std::io::Write>(
644 w: &mut Writer<W>,
645 p: &PropertyDefinition,
646) -> Result<(), DictError> {
647 w.write_event(Event::Start(BytesStart::new("PropertyDefinition")))
648 .map_err(|e| DictError::Xml(e.to_string()))?;
649 write_simple(w, "Identification", &p.identification.to_string())?;
650 write_simple(w, "Symbol", &p.symbol)?;
651 write_simple(w, "Name", "")?;
652 write_simple(w, "Type", &p.property_type.to_string())?;
653 write_simple(
654 w,
655 "IsOptional",
656 if p.is_optional { "true" } else { "false" },
657 )?;
658 write_simple(
659 w,
660 "IsUniqueIdentifier",
661 if p.is_unique_identifier {
662 "true"
663 } else {
664 "false"
665 },
666 )?;
667 write_simple(
668 w,
669 "LocalIdentification",
670 &p.local_identification.to_string(),
671 )?;
672 write_simple(w, "MemberOf", &p.member_of.to_string())?;
673 w.write_event(Event::End(BytesEnd::new("PropertyDefinition")))
674 .map_err(|e| DictError::Xml(e.to_string()))
675}
676
677fn write_type<W: std::io::Write>(w: &mut Writer<W>, t: &TypeDefinition) -> Result<(), DictError> {
678 let (tag, id, sym): (&str, &Auid, &str) = match t {
679 TypeDefinition::Integer(d) => ("TypeDefinitionInteger", &d.identification, &d.symbol),
680 TypeDefinition::Rename(d) => ("TypeDefinitionRename", &d.identification, &d.symbol),
681 TypeDefinition::Record(d) => ("TypeDefinitionRecord", &d.identification, &d.symbol),
682 TypeDefinition::Enumeration(d) => {
683 ("TypeDefinitionEnumeration", &d.identification, &d.symbol)
684 }
685 TypeDefinition::ExtendibleEnumeration(d) => (
686 "TypeDefinitionExtendibleEnumeration",
687 &d.identification,
688 &d.symbol,
689 ),
690 TypeDefinition::FixedArray(d) => ("TypeDefinitionFixedArray", &d.identification, &d.symbol),
691 TypeDefinition::VariableArray(d) => {
692 ("TypeDefinitionVariableArray", &d.identification, &d.symbol)
693 }
694 TypeDefinition::Set(d) => ("TypeDefinitionSet", &d.identification, &d.symbol),
695 TypeDefinition::String(d) => ("TypeDefinitionString", &d.identification, &d.symbol),
696 TypeDefinition::Character(d) => ("TypeDefinitionCharacter", &d.identification, &d.symbol),
697 TypeDefinition::Stream(d) => ("TypeDefinitionStream", &d.identification, &d.symbol),
698 TypeDefinition::Indirect(d) => ("TypeDefinitionIndirect", &d.identification, &d.symbol),
699 TypeDefinition::Opaque(d) => ("TypeDefinitionOpaque", &d.identification, &d.symbol),
700 TypeDefinition::StrongReference(d) => (
701 "TypeDefinitionStrongObjectReference",
702 &d.identification,
703 &d.symbol,
704 ),
705 TypeDefinition::WeakReference(d) => (
706 "TypeDefinitionWeakObjectReference",
707 &d.identification,
708 &d.symbol,
709 ),
710 TypeDefinition::Float(d) => ("TypeDefinitionFloat", &d.identification, &d.symbol),
711 TypeDefinition::LensSerialFloat(d) => (
712 "TypeDefinitionLensSerialFloat",
713 &d.identification,
714 &d.symbol,
715 ),
716 };
717
718 w.write_event(Event::Start(BytesStart::new(tag)))
719 .map_err(|e| DictError::Xml(e.to_string()))?;
720 write_simple(w, "Identification", &id.to_string())?;
721 write_simple(w, "Symbol", sym)?;
722
723 match t {
725 TypeDefinition::Integer(d) => {
726 write_simple(w, "Size", &d.size.to_string())?;
727 write_simple(w, "IsSigned", if d.is_signed { "true" } else { "false" })?;
728 }
729 TypeDefinition::Rename(d) => {
730 write_simple(w, "RenamedType", &d.renamed_type.to_string())?;
731 }
732 TypeDefinition::Record(d) => {
733 w.write_event(Event::Start(BytesStart::new("Members")))
734 .map_err(|e| DictError::Xml(e.to_string()))?;
735 for m in &d.members {
736 write_simple(w, "Name", &m.name)?;
737 write_simple(w, "Type", &m.field_type.to_string())?;
738 }
739 w.write_event(Event::End(BytesEnd::new("Members")))
740 .map_err(|e| DictError::Xml(e.to_string()))?;
741 }
742 TypeDefinition::Enumeration(d) => {
743 write_simple(w, "ElementType", &d.element_type.to_string())?;
744 w.write_event(Event::Start(BytesStart::new("Elements")))
745 .map_err(|e| DictError::Xml(e.to_string()))?;
746 for e in &d.elements {
747 write_simple(w, "Name", &e.name)?;
748 write_simple(w, "Value", &e.value.to_string())?;
749 }
750 w.write_event(Event::End(BytesEnd::new("Elements")))
751 .map_err(|e| DictError::Xml(e.to_string()))?;
752 }
753 TypeDefinition::ExtendibleEnumeration(d) => {
754 w.write_event(Event::Start(BytesStart::new("Elements")))
755 .map_err(|e| DictError::Xml(e.to_string()))?;
756 for e in &d.elements {
757 write_simple(w, "Name", &e.name)?;
758 write_simple(w, "Value", &e.value.to_string())?;
759 }
760 w.write_event(Event::End(BytesEnd::new("Elements")))
761 .map_err(|e| DictError::Xml(e.to_string()))?;
762 }
763 TypeDefinition::FixedArray(d) => {
764 write_simple(w, "ElementCount", &d.element_count.to_string())?;
765 write_simple(w, "ElementType", &d.element_type.to_string())?;
766 }
767 TypeDefinition::VariableArray(d) => {
768 write_simple(w, "ElementType", &d.element_type.to_string())?;
769 }
770 TypeDefinition::Set(d) => {
771 write_simple(w, "ElementType", &d.element_type.to_string())?;
772 }
773 TypeDefinition::String(d) => {
774 write_simple(w, "ElementType", &d.element_type.to_string())?;
775 }
776 TypeDefinition::StrongReference(d) => {
777 write_simple(w, "ReferencedType", &d.referenced_type.to_string())?;
778 }
779 TypeDefinition::WeakReference(d) => {
780 write_simple(w, "ReferencedType", &d.referenced_type.to_string())?;
781 w.write_event(Event::Start(BytesStart::new("TargetSet")))
782 .map_err(|e| DictError::Xml(e.to_string()))?;
783 for ts in &d.target_set {
784 write_simple(w, "MetaDefRef", &ts.to_string())?;
785 }
786 w.write_event(Event::End(BytesEnd::new("TargetSet")))
787 .map_err(|e| DictError::Xml(e.to_string()))?;
788 }
789 TypeDefinition::Float(d) => {
790 write_simple(w, "Size", &d.size.to_string())?;
791 }
792 _ => {} }
794
795 w.write_event(Event::End(BytesEnd::new(tag)))
796 .map_err(|e| DictError::Xml(e.to_string()))
797}