airlabs_client/
response.rs

1use std::marker::PhantomData;
2use std::time;
3
4use super::*;
5
6#[derive(Debug)]
7pub enum ResponseType<T, U> {
8    Regular(T),
9    Free(U),
10}
11
12impl<T, U> ResponseType<T, U> {
13    pub fn regular(self) -> Option<T> {
14        match self {
15            Self::Regular(value) => Some(value),
16            Self::Free(_) => None,
17        }
18    }
19
20    pub fn free(self) -> Option<U> {
21        match self {
22            Self::Regular(_) => None,
23            Self::Free(value) => Some(value),
24        }
25    }
26}
27
28#[derive(Clone, Debug)]
29pub struct Response<R> {
30    raw: String,
31    duration: time::Duration,
32    phantom: PhantomData<R>,
33}
34
35impl<R> Response<R>
36where
37    R: api::AirLabsRequest,
38{
39    pub fn new(raw: impl ToString, duration: time::Duration) -> Self {
40        let raw = raw.to_string();
41        let phantom = PhantomData;
42        Self {
43            raw,
44            duration,
45            phantom,
46        }
47    }
48
49    pub fn duration(&self) -> time::Duration {
50        self.duration
51    }
52
53    pub fn raw(&self) -> &str {
54        &self.raw
55    }
56
57    pub fn json(&self) -> json::Result<json::Value> {
58        json::from_str(&self.raw)
59    }
60
61    pub fn is_free(&self) -> json::Result<bool> {
62        let response = self.json()?;
63        let free = response["request"]["key"]["type"]
64            .as_str()
65            .is_some_and(|text| text == "free");
66        Ok(free)
67    }
68
69    pub fn api_response(
70        &self,
71    ) -> json::Result<api::Response<ResponseType<R::Response, R::ResponseFree>>> {
72        let response = self.json()?;
73        let free = response["request"]["key"]["type"]
74            .as_str()
75            .is_some_and(|text| text == "free");
76        let response = if free {
77            json::from_value::<api::Response<R::ResponseFree>>(response)?.map(ResponseType::Free)
78        } else {
79            json::from_value::<api::Response<R::Response>>(response)?.map(ResponseType::Regular)
80        };
81        Ok(response)
82    }
83}
84
85#[cfg(test)]
86mod tests;