betfair_xml_parser/
common.rs

1//! Common elements of the XML files
2use serde::{Deserialize, Serialize};
3
4/// Valid values - used to represent an enum
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
6#[serde(rename_all = "camelCase")]
7pub struct ValidValues {
8    /// Vector of possible values
9    #[serde(rename = "$value")]
10    pub items: Vec<Value>,
11}
12
13/// A value of a valid value
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
15#[serde(rename_all = "camelCase")]
16pub struct Value {
17    /// The id of the value
18    pub id: Option<String>,
19    /// The name of the value
20    pub name: String,
21    /// The description of the value
22    pub description: Description,
23}
24
25/// The description tag
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
27pub struct Description {
28    /// The value of the description
29    #[serde(rename = "$value")]
30    pub value: Option<String>,
31}
32
33/// The parameter tag
34#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
35pub struct Parameter {
36    /// Whether the parameter is mandatory
37    pub mandatory: Option<bool>,
38    /// The name of the parameter
39    pub name: String,
40    /// The type of the parameter
41    pub r#type: String,
42    /// Vector of possible values enclosed within the parameter
43    #[serde(rename = "$value")]
44    pub items: Vec<ParameterItem>,
45}
46
47/// A child item of the <parameter> tag
48#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
49#[serde(rename_all = "camelCase")]
50pub enum ParameterItem {
51    /// The description tag
52    Description(Description),
53    /// The valid values tag
54    ValidValues(ValidValues),
55}
56
57#[cfg(test)]
58mod tests {
59    use rstest::rstest;
60    use serde_xml_rs::from_str;
61
62    use super::*;
63
64    #[rstest]
65    fn parameter_test() {
66        let xml = r#"
67        <parameter mandatory="false" name="total" type="double">
68            <description>Set a limit on total (matched + unmatched) bet exposure on market group</description>
69        </parameter>
70        "#;
71
72        let parameter = from_str::<Parameter>(xml);
73        match parameter {
74            Ok(req) => {
75                assert_eq!(
76                    req,
77                    Parameter {
78                        mandatory: Some(false),
79                        name: "total".to_owned(),
80                        r#type: "double".to_owned(),
81                        items: vec![ParameterItem::Description(Description {
82                            value: Some(
83                                "Set a limit on total (matched + unmatched) bet exposure on market group"
84                                    .to_owned()
85                            )
86                        })]
87                    }
88                );
89            }
90            Err(err) => {
91                log::error!("Failed to parse XML: {err}");
92            }
93        }
94    }
95
96    #[rstest]
97    fn parameter_test_2() {
98        let xml = r#"
99        <parameter name="errorCode" type="string">
100            <description>the unique code for this error</description>
101            <validValues>
102                <value id="1" name="TOO_MUCH_DATA">
103                    <description>The operation requested too much data</description>
104                </value>
105                <value id="2" name="INVALID_INPUT_DATA">
106                    <description>Invalid input data</description>
107                </value>
108            </validValues>
109        </parameter>
110        "#;
111
112        let parameter = from_str::<Parameter>(xml);
113        match parameter {
114            Ok(req) => {
115                assert_eq!(
116                    req,
117                    Parameter {
118                        mandatory: None,
119                        name: "errorCode".to_owned(),
120                        r#type: "string".to_owned(),
121                        items: vec![
122                            ParameterItem::Description(Description {
123                                value: Some("the unique code for this error".to_owned())
124                            }),
125                            ParameterItem::ValidValues(ValidValues {
126                                items: vec![
127                                    Value {
128                                        id: Some("1".to_owned()),
129                                        name: "TOO_MUCH_DATA".to_owned(),
130                                        description: Description {
131                                            value: Some(
132                                                "The operation requested too much data".to_owned()
133                                            )
134                                        }
135                                    },
136                                    Value {
137                                        id: Some("2".to_owned()),
138                                        name: "INVALID_INPUT_DATA".to_owned(),
139                                        description: Description {
140                                            value: Some("Invalid input data".to_owned())
141                                        }
142                                    }
143                                ]
144                            })
145                        ]
146                    }
147                );
148            }
149            Err(err) => {
150                log::error!("Failed to parse XML: {err}");
151            }
152        }
153    }
154}