airlabs_client/
response.rs1use 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;