Skip to main content

betfair_types/
shared.rs

1use serde::{Deserialize, Deserializer};
2use serde_json::Value;
3
4#[derive(Debug, Deserialize)]
5pub struct SuccessResponse {
6    pub token: redact::Secret<String>,
7    pub product: redact::Secret<String>,
8}
9
10#[derive(Debug)]
11pub struct Response(pub Result<SuccessResponse, ErrorValues>);
12
13impl AsRef<Result<SuccessResponse, ErrorValues>> for Response {
14    fn as_ref(&self) -> &Result<SuccessResponse, ErrorValues> {
15        &self.0
16    }
17}
18
19impl core::ops::Deref for Response {
20    type Target = Result<SuccessResponse, ErrorValues>;
21
22    fn deref(&self) -> &Self::Target {
23        &self.0
24    }
25}
26
27impl core::ops::DerefMut for Response {
28    fn deref_mut(&mut self) -> &mut Self::Target {
29        &mut self.0
30    }
31}
32
33impl<'de> Deserialize<'de> for Response {
34    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
35    where
36        D: Deserializer<'de>,
37    {
38        let value = Value::deserialize(deserializer)?;
39
40        // Check if it's a success response
41        if let Some(status) = value.get("status").and_then(|v| v.as_str()) {
42            match status {
43                "SUCCESS" => {
44                    let success_response = SuccessResponse {
45                        token: redact::Secret::new(
46                            value
47                                .get("token")
48                                .and_then(|v| v.as_str())
49                                .ok_or_else(|| serde::de::Error::custom("invalid response"))?
50                                .to_owned(),
51                        ),
52                        product: redact::Secret::new(
53                            value
54                                .get("product")
55                                .and_then(|v| v.as_str())
56                                .ok_or_else(|| serde::de::Error::custom("invalid response"))?
57                                .to_owned(),
58                        ),
59                    };
60                    return Ok(Self(Ok(success_response)));
61                }
62                "FAIL" => {
63                    if let Some(error) = value.get("error") {
64                        let login_error =
65                            ErrorValues::deserialize(error).map_err(serde::de::Error::custom)?;
66                        return Ok(Self(Err(login_error)));
67                    }
68                }
69                _ => {}
70            }
71        }
72
73        Err(serde::de::Error::custom("invalid response"))
74    }
75}
76#[derive(Debug, Deserialize)]
77pub enum StatusValues {
78    #[serde(rename = "SUCCESS")]
79    Success,
80    #[serde(rename = "FAIL")]
81    Failure,
82}
83
84#[derive(Debug, Deserialize)]
85pub enum ErrorValues {
86    #[serde(rename = "INPUT_VALIDATION_ERROR")]
87    InputValidation,
88    #[serde(rename = "INVALID_SESSION_INFORMATION")]
89    InvalidSessionInformation,
90    #[serde(rename = "NO_SESSION")]
91    NoSession,
92}