1use crate::error::ParseError;
7use crate::messages::{DataFieldDef, FieldDef, GroupDef, MessageDef};
8use crate::types::{
9 ByteOrder, CompositeDef, CompositeField, EnumDef, EnumValue, Presence, PrimitiveDef,
10 PrimitiveType, Schema, SetChoice, SetDef, TypeDef,
11};
12use quick_xml::Reader;
13use quick_xml::events::{BytesStart, Event};
14
15pub fn parse_schema(xml: &str) -> Result<Schema, ParseError> {
26 let mut reader = Reader::from_str(xml);
27 reader.config_mut().trim_text(true);
28
29 let mut schema: Option<Schema> = None;
30 let mut buf = Vec::new();
31
32 loop {
33 match reader.read_event_into(&mut buf) {
34 Ok(Event::Start(ref e)) => {
35 let name_bytes = e.name().as_ref().to_vec();
36 let name = std::str::from_utf8(&name_bytes)?;
37 match name {
38 "messageSchema" | "sbe:messageSchema" => {
39 schema = Some(parse_message_schema(e)?);
40 }
41 "types" if schema.is_some() => {
42 parse_types(&mut reader, schema.as_mut().unwrap())?;
43 }
44 "message" | "sbe:message" if schema.is_some() => {
45 let msg = parse_message(&mut reader, e, schema.as_ref().unwrap())?;
46 schema.as_mut().unwrap().messages.push(msg);
47 }
48 _ => {}
49 }
50 }
51 Ok(Event::Eof) => break,
52 Err(e) => return Err(ParseError::Xml(e)),
53 _ => {}
54 }
55 buf.clear();
56 }
57
58 schema.ok_or_else(|| ParseError::InvalidStructure {
59 message: "No messageSchema element found".to_string(),
60 })
61}
62
63fn parse_message_schema(e: &BytesStart<'_>) -> Result<Schema, ParseError> {
65 let mut package = String::new();
66 let mut id: u16 = 0;
67 let mut version: u16 = 0;
68 let mut semantic_version = String::new();
69 let mut description = None;
70 let mut byte_order = ByteOrder::LittleEndian;
71 let mut header_type = "messageHeader".to_string();
72
73 for attr in e.attributes().flatten() {
74 let key = std::str::from_utf8(attr.key.as_ref())?;
75 let value = std::str::from_utf8(&attr.value)?;
76
77 match key {
78 "package" => package = value.to_string(),
79 "id" => {
80 id = value
81 .parse()
82 .map_err(|_| ParseError::invalid_attr("messageSchema", "id", value))?
83 }
84 "version" => {
85 version = value
86 .parse()
87 .map_err(|_| ParseError::invalid_attr("messageSchema", "version", value))?
88 }
89 "semanticVersion" => semantic_version = value.to_string(),
90 "description" => description = Some(value.to_string()),
91 "byteOrder" => {
92 byte_order = ByteOrder::parse(value)
93 .ok_or_else(|| ParseError::invalid_attr("messageSchema", "byteOrder", value))?
94 }
95 "headerType" => header_type = value.to_string(),
96 _ => {}
97 }
98 }
99
100 let mut schema = Schema::new(package, id, version);
101 schema.semantic_version = semantic_version;
102 schema.description = description;
103 schema.byte_order = byte_order;
104 schema.header_type = header_type;
105
106 Ok(schema)
107}
108
109fn parse_types(reader: &mut Reader<&[u8]>, schema: &mut Schema) -> Result<(), ParseError> {
111 let mut buf = Vec::new();
112 let mut depth = 1;
113
114 loop {
115 match reader.read_event_into(&mut buf) {
116 Ok(Event::Start(ref e)) => {
117 depth += 1;
118 let name_bytes = e.name().as_ref().to_vec();
119 let name = std::str::from_utf8(&name_bytes)?;
120 match name {
121 "type" => {
122 let type_def = parse_primitive_type(reader, e)?;
123 schema.add_type(TypeDef::Primitive(type_def));
124 depth -= 1; }
126 "composite" => {
127 let composite = parse_composite(reader, e)?;
128 schema.add_type(TypeDef::Composite(composite));
129 depth -= 1;
130 }
131 "enum" => {
132 let enum_def = parse_enum(reader, e)?;
133 schema.add_type(TypeDef::Enum(enum_def));
134 depth -= 1;
135 }
136 "set" => {
137 let set_def = parse_set(reader, e)?;
138 schema.add_type(TypeDef::Set(set_def));
139 depth -= 1;
140 }
141 _ => {}
142 }
143 }
144 Ok(Event::Empty(ref e)) => {
145 let name_bytes = e.name().as_ref().to_vec();
146 let name = std::str::from_utf8(&name_bytes)?;
147 if name == "type" {
148 let type_def = parse_primitive_type_empty(e)?;
149 schema.add_type(TypeDef::Primitive(type_def));
150 }
151 }
152 Ok(Event::End(_)) => {
153 depth -= 1;
154 if depth == 0 {
155 break;
156 }
157 }
158 Ok(Event::Eof) => break,
159 Err(e) => return Err(ParseError::Xml(e)),
160 _ => {}
161 }
162 buf.clear();
163 }
164
165 Ok(())
166}
167
168fn parse_primitive_type(
170 reader: &mut Reader<&[u8]>,
171 e: &BytesStart<'_>,
172) -> Result<PrimitiveDef, ParseError> {
173 let mut type_def = parse_primitive_type_empty(e)?;
174 let mut buf = Vec::new();
175
176 loop {
178 match reader.read_event_into(&mut buf) {
179 Ok(Event::Text(ref t)) => {
180 let text = std::str::from_utf8(t.as_ref())?.trim();
181 if !text.is_empty() {
182 type_def.constant_value = Some(text.to_string());
183 }
184 }
185 Ok(Event::End(_)) => break,
186 Ok(Event::Eof) => break,
187 Err(e) => return Err(ParseError::Xml(e)),
188 _ => {}
189 }
190 buf.clear();
191 }
192
193 Ok(type_def)
194}
195
196fn parse_primitive_type_empty(e: &BytesStart<'_>) -> Result<PrimitiveDef, ParseError> {
198 let mut name = String::new();
199 let mut primitive_type: Option<PrimitiveType> = None;
200 let mut length: Option<usize> = None;
201 let mut null_value = None;
202 let mut min_value = None;
203 let mut max_value = None;
204 let mut character_encoding = None;
205 let mut semantic_type = None;
206 let mut description = None;
207
208 for attr in e.attributes().flatten() {
209 let key = std::str::from_utf8(attr.key.as_ref())?;
210 let value = std::str::from_utf8(&attr.value)?;
211
212 match key {
213 "name" => name = value.to_string(),
214 "primitiveType" => {
215 primitive_type = Some(
216 PrimitiveType::from_sbe_name(value)
217 .ok_or_else(|| ParseError::invalid_attr("type", "primitiveType", value))?,
218 )
219 }
220 "length" => {
221 length = Some(
222 value
223 .parse()
224 .map_err(|_| ParseError::invalid_attr("type", "length", value))?,
225 )
226 }
227 "nullValue" => null_value = Some(value.to_string()),
228 "minValue" => min_value = Some(value.to_string()),
229 "maxValue" => max_value = Some(value.to_string()),
230 "characterEncoding" => character_encoding = Some(value.to_string()),
231 "semanticType" => semantic_type = Some(value.to_string()),
232 "description" => description = Some(value.to_string()),
233 _ => {}
234 }
235 }
236
237 let primitive_type =
238 primitive_type.ok_or_else(|| ParseError::missing_attr("type", "primitiveType"))?;
239
240 let mut type_def = PrimitiveDef::new(name, primitive_type);
241 type_def.length = length;
242 type_def.null_value = null_value;
243 type_def.min_value = min_value;
244 type_def.max_value = max_value;
245 type_def.character_encoding = character_encoding;
246 type_def.semantic_type = semantic_type;
247 type_def.description = description;
248
249 Ok(type_def)
250}
251
252fn parse_composite(
254 reader: &mut Reader<&[u8]>,
255 e: &BytesStart<'_>,
256) -> Result<CompositeDef, ParseError> {
257 let mut name = String::new();
258 let mut description = None;
259 let mut semantic_type = None;
260
261 for attr in e.attributes().flatten() {
262 let key = std::str::from_utf8(attr.key.as_ref())?;
263 let value = std::str::from_utf8(&attr.value)?;
264
265 match key {
266 "name" => name = value.to_string(),
267 "description" => description = Some(value.to_string()),
268 "semanticType" => semantic_type = Some(value.to_string()),
269 _ => {}
270 }
271 }
272
273 let mut composite = CompositeDef::new(name);
274 composite.description = description;
275 composite.semantic_type = semantic_type;
276
277 let mut buf = Vec::new();
278 let mut current_offset = 0;
279
280 loop {
281 match reader.read_event_into(&mut buf) {
282 Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) => {
283 let name_bytes = e.name().as_ref().to_vec();
284 let tag_name = std::str::from_utf8(&name_bytes)?;
285 if tag_name == "type" {
286 let field = parse_composite_field(e, current_offset)?;
287 current_offset += field.encoded_length;
288 composite.add_field(field);
289 }
290 }
291 Ok(Event::End(_)) => break,
292 Ok(Event::Eof) => break,
293 Err(e) => return Err(ParseError::Xml(e)),
294 _ => {}
295 }
296 buf.clear();
297 }
298
299 Ok(composite)
300}
301
302fn parse_composite_field(
304 e: &BytesStart<'_>,
305 default_offset: usize,
306) -> Result<CompositeField, ParseError> {
307 let mut name = String::new();
308 let mut primitive_type: Option<PrimitiveType> = None;
309 let mut offset = None;
310 let mut semantic_type = None;
311 let mut description = None;
312 let constant_value = None;
313
314 for attr in e.attributes().flatten() {
315 let key = std::str::from_utf8(attr.key.as_ref())?;
316 let value = std::str::from_utf8(&attr.value)?;
317
318 match key {
319 "name" => name = value.to_string(),
320 "primitiveType" => {
321 primitive_type = Some(
322 PrimitiveType::from_sbe_name(value)
323 .ok_or_else(|| ParseError::invalid_attr("type", "primitiveType", value))?,
324 )
325 }
326 "offset" => {
327 offset = Some(
328 value
329 .parse()
330 .map_err(|_| ParseError::invalid_attr("type", "offset", value))?,
331 )
332 }
333 "semanticType" => semantic_type = Some(value.to_string()),
334 "description" => description = Some(value.to_string()),
335 "presence" if value == "constant" => {}
336 _ => {}
337 }
338 }
339
340 let prim = primitive_type.ok_or_else(|| ParseError::missing_attr("type", "primitiveType"))?;
341 let type_name = prim.sbe_name().to_string();
342 let encoded_length = prim.size();
343
344 let mut field = CompositeField::new(name, type_name, encoded_length);
345 field.primitive_type = Some(prim);
346 field.offset = offset.or(Some(default_offset));
347 field.semantic_type = semantic_type;
348 field.description = description;
349 field.constant_value = constant_value;
350
351 Ok(field)
352}
353
354fn parse_enum(reader: &mut Reader<&[u8]>, e: &BytesStart<'_>) -> Result<EnumDef, ParseError> {
356 let mut name = String::new();
357 let mut encoding_type: Option<PrimitiveType> = None;
358 let mut null_value = None;
359 let mut description = None;
360
361 for attr in e.attributes().flatten() {
362 let key = std::str::from_utf8(attr.key.as_ref())?;
363 let value = std::str::from_utf8(&attr.value)?;
364
365 match key {
366 "name" => name = value.to_string(),
367 "encodingType" => {
368 encoding_type = Some(
369 PrimitiveType::from_sbe_name(value)
370 .ok_or_else(|| ParseError::invalid_attr("enum", "encodingType", value))?,
371 )
372 }
373 "nullValue" => null_value = Some(value.to_string()),
374 "description" => description = Some(value.to_string()),
375 _ => {}
376 }
377 }
378
379 let encoding_type =
380 encoding_type.ok_or_else(|| ParseError::missing_attr("enum", "encodingType"))?;
381
382 let mut enum_def = EnumDef::new(name, encoding_type);
383 enum_def.null_value = null_value;
384 enum_def.description = description;
385
386 let mut buf = Vec::new();
387
388 loop {
389 match reader.read_event_into(&mut buf) {
390 Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) => {
391 let name_bytes = e.name().as_ref().to_vec();
392 let tag_name = std::str::from_utf8(&name_bytes)?;
393 if tag_name == "validValue" {
394 let value = parse_enum_value(reader, e)?;
395 enum_def.add_value(value);
396 }
397 }
398 Ok(Event::End(_)) => break,
399 Ok(Event::Eof) => break,
400 Err(e) => return Err(ParseError::Xml(e)),
401 _ => {}
402 }
403 buf.clear();
404 }
405
406 Ok(enum_def)
407}
408
409fn parse_enum_value(
411 reader: &mut Reader<&[u8]>,
412 e: &BytesStart<'_>,
413) -> Result<EnumValue, ParseError> {
414 let mut name = String::new();
415 let mut description = None;
416 let mut since_version = None;
417 let mut deprecated = None;
418
419 for attr in e.attributes().flatten() {
420 let key = std::str::from_utf8(attr.key.as_ref())?;
421 let value = std::str::from_utf8(&attr.value)?;
422
423 match key {
424 "name" => name = value.to_string(),
425 "description" => description = Some(value.to_string()),
426 "sinceVersion" => since_version = value.parse().ok(),
427 "deprecated" => deprecated = value.parse().ok(),
428 _ => {}
429 }
430 }
431
432 let mut buf = Vec::new();
434 let mut value_str = String::new();
435
436 loop {
437 match reader.read_event_into(&mut buf) {
438 Ok(Event::Text(ref t)) => {
439 value_str = std::str::from_utf8(t.as_ref())?.trim().to_string();
440 }
441 Ok(Event::End(_)) => break,
442 Ok(Event::Eof) => break,
443 Err(e) => return Err(ParseError::Xml(e)),
444 _ => {}
445 }
446 buf.clear();
447 }
448
449 let mut enum_value = EnumValue::new(name, value_str);
450 enum_value.description = description;
451 enum_value.since_version = since_version;
452 enum_value.deprecated = deprecated;
453
454 Ok(enum_value)
455}
456
457fn parse_set(reader: &mut Reader<&[u8]>, e: &BytesStart<'_>) -> Result<SetDef, ParseError> {
459 let mut name = String::new();
460 let mut encoding_type: Option<PrimitiveType> = None;
461 let mut description = None;
462
463 for attr in e.attributes().flatten() {
464 let key = std::str::from_utf8(attr.key.as_ref())?;
465 let value = std::str::from_utf8(&attr.value)?;
466
467 match key {
468 "name" => name = value.to_string(),
469 "encodingType" => {
470 encoding_type = Some(
471 PrimitiveType::from_sbe_name(value)
472 .ok_or_else(|| ParseError::invalid_attr("set", "encodingType", value))?,
473 )
474 }
475 "description" => description = Some(value.to_string()),
476 _ => {}
477 }
478 }
479
480 let encoding_type =
481 encoding_type.ok_or_else(|| ParseError::missing_attr("set", "encodingType"))?;
482
483 let mut set_def = SetDef::new(name, encoding_type);
484 set_def.description = description;
485
486 let mut buf = Vec::new();
487
488 loop {
489 match reader.read_event_into(&mut buf) {
490 Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) => {
491 let name_bytes = e.name().as_ref().to_vec();
492 let tag_name = std::str::from_utf8(&name_bytes)?;
493 if tag_name == "choice" {
494 let choice = parse_set_choice(reader, e)?;
495 set_def.add_choice(choice);
496 }
497 }
498 Ok(Event::End(_)) => break,
499 Ok(Event::Eof) => break,
500 Err(e) => return Err(ParseError::Xml(e)),
501 _ => {}
502 }
503 buf.clear();
504 }
505
506 Ok(set_def)
507}
508
509fn parse_set_choice(
511 reader: &mut Reader<&[u8]>,
512 e: &BytesStart<'_>,
513) -> Result<SetChoice, ParseError> {
514 let mut name = String::new();
515 let mut description = None;
516 let mut since_version = None;
517 let mut deprecated = None;
518
519 for attr in e.attributes().flatten() {
520 let key = std::str::from_utf8(attr.key.as_ref())?;
521 let value = std::str::from_utf8(&attr.value)?;
522
523 match key {
524 "name" => name = value.to_string(),
525 "description" => description = Some(value.to_string()),
526 "sinceVersion" => since_version = value.parse().ok(),
527 "deprecated" => deprecated = value.parse().ok(),
528 _ => {}
529 }
530 }
531
532 let mut buf = Vec::new();
534 let mut bit_position: u8 = 0;
535
536 loop {
537 match reader.read_event_into(&mut buf) {
538 Ok(Event::Text(ref t)) => {
539 let text = std::str::from_utf8(t.as_ref())?.trim();
540 bit_position = text
541 .parse()
542 .map_err(|_| ParseError::invalid_attr("choice", "value", text))?;
543 }
544 Ok(Event::End(_)) => break,
545 Ok(Event::Eof) => break,
546 Err(e) => return Err(ParseError::Xml(e)),
547 _ => {}
548 }
549 buf.clear();
550 }
551
552 let mut choice = SetChoice::new(name, bit_position);
553 choice.description = description;
554 choice.since_version = since_version;
555 choice.deprecated = deprecated;
556
557 Ok(choice)
558}
559
560fn parse_message(
562 reader: &mut Reader<&[u8]>,
563 e: &BytesStart<'_>,
564 schema: &Schema,
565) -> Result<MessageDef, ParseError> {
566 let mut name = String::new();
567 let mut id: u16 = 0;
568 let mut block_length: u16 = 0;
569 let mut semantic_type = None;
570 let mut description = None;
571 let mut since_version = None;
572 let mut deprecated = None;
573
574 for attr in e.attributes().flatten() {
575 let key = std::str::from_utf8(attr.key.as_ref())?;
576 let value = std::str::from_utf8(&attr.value)?;
577
578 match key {
579 "name" => name = value.to_string(),
580 "id" => {
581 id = value
582 .parse()
583 .map_err(|_| ParseError::invalid_attr("message", "id", value))?
584 }
585 "blockLength" => {
586 block_length = value
587 .parse()
588 .map_err(|_| ParseError::invalid_attr("message", "blockLength", value))?
589 }
590 "semanticType" => semantic_type = Some(value.to_string()),
591 "description" => description = Some(value.to_string()),
592 "sinceVersion" => since_version = value.parse().ok(),
593 "deprecated" => deprecated = value.parse().ok(),
594 _ => {}
595 }
596 }
597
598 let mut msg = MessageDef::new(name, id, block_length);
599 msg.semantic_type = semantic_type;
600 msg.description = description;
601 msg.since_version = since_version;
602 msg.deprecated = deprecated;
603
604 let mut buf = Vec::new();
605
606 loop {
607 match reader.read_event_into(&mut buf) {
608 Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) => {
609 let name_bytes = e.name().as_ref().to_vec();
610 let tag_name = std::str::from_utf8(&name_bytes)?;
611
612 match tag_name {
613 "field" => {
614 let field = parse_field(e, schema)?;
615 msg.add_field(field);
616 }
617 "group" => {
618 let group = parse_group(reader, e, schema)?;
619 msg.add_group(group);
620 }
621 "data" => {
622 let data = parse_data_field(e)?;
623 msg.add_data_field(data);
624 }
625 _ => {}
626 }
627 }
628 Ok(Event::End(_)) => break,
629 Ok(Event::Eof) => break,
630 Err(e) => return Err(ParseError::Xml(e)),
631 _ => {}
632 }
633 buf.clear();
634 }
635
636 Ok(msg)
637}
638
639fn parse_field(e: &BytesStart<'_>, schema: &Schema) -> Result<FieldDef, ParseError> {
641 let mut name = String::new();
642 let mut id: u16 = 0;
643 let mut type_name = String::new();
644 let mut offset: usize = 0;
645 let mut presence = Presence::Required;
646 let mut semantic_type = None;
647 let mut description = None;
648 let mut since_version = None;
649 let mut deprecated = None;
650 let mut value_ref = None;
651
652 for attr in e.attributes().flatten() {
653 let key = std::str::from_utf8(attr.key.as_ref())?;
654 let value = std::str::from_utf8(&attr.value)?;
655
656 match key {
657 "name" => name = value.to_string(),
658 "id" => {
659 id = value
660 .parse()
661 .map_err(|_| ParseError::invalid_attr("field", "id", value))?
662 }
663 "type" => type_name = value.to_string(),
664 "offset" => {
665 offset = value
666 .parse()
667 .map_err(|_| ParseError::invalid_attr("field", "offset", value))?
668 }
669 "presence" => {
670 presence = Presence::parse(value)
671 .ok_or_else(|| ParseError::invalid_attr("field", "presence", value))?
672 }
673 "semanticType" => semantic_type = Some(value.to_string()),
674 "description" => description = Some(value.to_string()),
675 "sinceVersion" => since_version = value.parse().ok(),
676 "deprecated" => deprecated = value.parse().ok(),
677 "valueRef" => value_ref = Some(value.to_string()),
678 _ => {}
679 }
680 }
681
682 let mut field = FieldDef::new(name, id, type_name.clone(), offset);
683 field.presence = presence;
684 field.semantic_type = semantic_type;
685 field.description = description;
686 field.since_version = since_version;
687 field.deprecated = deprecated;
688 field.value_ref = value_ref;
689
690 if let Some(type_def) = schema.get_type(&type_name) {
692 field.encoded_length = type_def.encoded_length();
693 }
694
695 Ok(field)
696}
697
698fn parse_group(
700 reader: &mut Reader<&[u8]>,
701 e: &BytesStart<'_>,
702 schema: &Schema,
703) -> Result<GroupDef, ParseError> {
704 let mut name = String::new();
705 let mut id: u16 = 0;
706 let mut block_length: u16 = 0;
707 let mut dimension_type = "groupSizeEncoding".to_string();
708 let mut description = None;
709 let mut since_version = None;
710 let mut deprecated = None;
711
712 for attr in e.attributes().flatten() {
713 let key = std::str::from_utf8(attr.key.as_ref())?;
714 let value = std::str::from_utf8(&attr.value)?;
715
716 match key {
717 "name" => name = value.to_string(),
718 "id" => {
719 id = value
720 .parse()
721 .map_err(|_| ParseError::invalid_attr("group", "id", value))?
722 }
723 "blockLength" => {
724 block_length = value
725 .parse()
726 .map_err(|_| ParseError::invalid_attr("group", "blockLength", value))?
727 }
728 "dimensionType" => dimension_type = value.to_string(),
729 "description" => description = Some(value.to_string()),
730 "sinceVersion" => since_version = value.parse().ok(),
731 "deprecated" => deprecated = value.parse().ok(),
732 _ => {}
733 }
734 }
735
736 let mut group = GroupDef::new(name, id, block_length);
737 group.dimension_type = dimension_type;
738 group.description = description;
739 group.since_version = since_version;
740 group.deprecated = deprecated;
741
742 let mut buf = Vec::new();
743
744 loop {
745 match reader.read_event_into(&mut buf) {
746 Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) => {
747 let name_bytes = e.name().as_ref().to_vec();
748 let tag_name = std::str::from_utf8(&name_bytes)?;
749 match tag_name {
750 "field" => {
751 let field = parse_field(e, schema)?;
752 group.add_field(field);
753 }
754 "group" => {
755 let nested = parse_group(reader, e, schema)?;
756 group.add_nested_group(nested);
757 }
758 "data" => {
759 let data = parse_data_field(e)?;
760 group.add_data_field(data);
761 }
762 _ => {}
763 }
764 }
765 Ok(Event::End(_)) => break,
766 Ok(Event::Eof) => break,
767 Err(e) => return Err(ParseError::Xml(e)),
768 _ => {}
769 }
770 buf.clear();
771 }
772
773 Ok(group)
774}
775
776fn parse_data_field(e: &BytesStart<'_>) -> Result<DataFieldDef, ParseError> {
778 let mut name = String::new();
779 let mut id: u16 = 0;
780 let mut type_name = String::new();
781 let mut description = None;
782 let mut since_version = None;
783 let mut deprecated = None;
784
785 for attr in e.attributes().flatten() {
786 let key = std::str::from_utf8(attr.key.as_ref())?;
787 let value = std::str::from_utf8(&attr.value)?;
788
789 match key {
790 "name" => name = value.to_string(),
791 "id" => {
792 id = value
793 .parse()
794 .map_err(|_| ParseError::invalid_attr("data", "id", value))?
795 }
796 "type" => type_name = value.to_string(),
797 "description" => description = Some(value.to_string()),
798 "sinceVersion" => since_version = value.parse().ok(),
799 "deprecated" => deprecated = value.parse().ok(),
800 _ => {}
801 }
802 }
803
804 let mut data = DataFieldDef::new(name, id, type_name);
805 data.description = description;
806 data.since_version = since_version;
807 data.deprecated = deprecated;
808
809 Ok(data)
810}
811
812#[allow(dead_code)]
814fn skip_to_end(reader: &mut Reader<&[u8]>, _tag_name: &str) -> Result<(), ParseError> {
815 let mut buf = Vec::new();
816 let mut depth = 1;
817
818 loop {
819 match reader.read_event_into(&mut buf) {
820 Ok(Event::Start(_)) => depth += 1,
821 Ok(Event::End(_)) => {
822 depth -= 1;
823 if depth == 0 {
824 break;
825 }
826 }
827 Ok(Event::Eof) => break,
828 Err(e) => return Err(ParseError::Xml(e)),
829 _ => {}
830 }
831 buf.clear();
832 }
833
834 Ok(())
835}
836
837#[cfg(test)]
838mod tests {
839 use super::*;
840
841 const SIMPLE_SCHEMA: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
842<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe"
843 package="test"
844 id="1"
845 version="1"
846 semanticVersion="1.0.0"
847 byteOrder="littleEndian">
848 <types>
849 <type name="uint64" primitiveType="uint64"/>
850 <type name="Symbol" primitiveType="char" length="8"/>
851 <enum name="Side" encodingType="uint8">
852 <validValue name="Buy">1</validValue>
853 <validValue name="Sell">2</validValue>
854 </enum>
855 </types>
856 <sbe:message name="TestMessage" id="1" blockLength="16">
857 <field name="price" id="1" type="uint64" offset="0"/>
858 <field name="symbol" id="2" type="Symbol" offset="8"/>
859 </sbe:message>
860</sbe:messageSchema>"#;
861
862 #[test]
863 fn test_parse_simple_schema() {
864 let schema = parse_schema(SIMPLE_SCHEMA).expect("Failed to parse schema");
865
866 assert_eq!(schema.package, "test");
867 assert_eq!(schema.id, 1);
868 assert_eq!(schema.version, 1);
869 assert_eq!(schema.byte_order, ByteOrder::LittleEndian);
870 }
871
872 #[test]
873 fn test_parse_types() {
874 let schema = parse_schema(SIMPLE_SCHEMA).expect("Failed to parse schema");
875
876 assert!(schema.has_type("uint64"));
877 assert!(schema.has_type("Symbol"));
878 assert!(schema.has_type("Side"));
879
880 let symbol = schema.get_type("Symbol").unwrap();
881 assert!(symbol.is_primitive());
882 assert_eq!(symbol.encoded_length(), 8);
883
884 let side = schema.get_type("Side").unwrap();
885 assert!(side.is_enum());
886 }
887
888 #[test]
889 fn test_parse_message() {
890 let schema = parse_schema(SIMPLE_SCHEMA).expect("Failed to parse schema");
891
892 assert_eq!(schema.messages.len(), 1);
893 let msg = &schema.messages[0];
894 assert_eq!(msg.name, "TestMessage");
895 assert_eq!(msg.id, 1);
896 assert_eq!(msg.block_length, 16);
897 assert_eq!(msg.fields.len(), 2);
898 }
899}