betfair_xml_parser/
data_type.rs

1//! Betfair XML file <dataType> tag parser
2use serde::{Deserialize, Serialize};
3
4use crate::common::{Description, Parameter};
5
6/// Representation of the <dataType> tag
7#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
8#[serde(rename_all = "camelCase")]
9pub struct DataType {
10    /// The name of the data type
11    pub name: String,
12    /// Vector of possible values
13    #[serde(rename = "$value")]
14    pub values: Vec<DataTypeItems>,
15}
16
17/// A child item of the <dataType> tag
18#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
19#[serde(rename_all = "camelCase")]
20#[expect(clippy::module_name_repetitions)]
21pub enum DataTypeItems {
22    /// The description of the data type
23    Description(Description),
24    /// A parameter tag of the data type
25    Parameter(Parameter),
26}
27
28#[cfg(test)]
29mod tests {
30    use rstest::rstest;
31    use serde_xml_rs::from_str;
32
33    use super::*;
34
35    #[rstest]
36    fn test_parse_data_type() {
37        let xml = r#"
38    <dataType name="RunnerCatalog">
39        <description>Information about the Runners (selections) in a market</description>
40        <parameter mandatory="true" name="selectionId" type="SelectionId">
41            <description>The unique id for the selection.</description>
42        </parameter>
43        <parameter name="runnerName" type="string" mandatory="true">
44            <description>The name of the runner</description>
45        </parameter>
46        <parameter mandatory="true" name="handicap" type="double">
47            <description>The handicap</description>
48        </parameter>
49        <parameter mandatory="true" name="sortPriority" type="i32">
50            <description>The sort priority of this runner</description>
51        </parameter>
52        <parameter name="metadata" type="map(string,string)">
53            <description>Metadata associated with the runner</description>
54        </parameter>
55    </dataType>
56
57    "#;
58
59        match from_str::<DataType>(xml) {
60            Ok(req) => {
61                assert_eq!(req.values.len(), 6);
62                assert_eq!(req.name, "RunnerCatalog");
63
64                // Check each index safely
65                assert!(
66                    req.values
67                        .first()
68                        .is_some_and(|val| matches!(val, &DataTypeItems::Description(_)))
69                );
70                assert!(
71                    req.values
72                        .get(1)
73                        .is_some_and(|val| matches!(val, &DataTypeItems::Parameter(_)))
74                );
75                assert!(
76                    req.values
77                        .get(2)
78                        .is_some_and(|val| matches!(val, &DataTypeItems::Parameter(_)))
79                );
80                assert!(
81                    req.values
82                        .get(3)
83                        .is_some_and(|val| matches!(val, &DataTypeItems::Parameter(_)))
84                );
85                assert!(
86                    req.values
87                        .get(4)
88                        .is_some_and(|val| matches!(val, &DataTypeItems::Parameter(_)))
89                );
90                assert!(
91                    req.values
92                        .get(5)
93                        .is_some_and(|val| matches!(val, &DataTypeItems::Parameter(_)))
94                );
95            }
96            Err(err) => {
97                log::error!("Failed to parse XML: {err}");
98            }
99        }
100    }
101}