line_bot_messaging_api/
lib.rs

1pub mod api;
2mod entity;
3mod error;
4pub(crate) mod util;
5
6pub use entity::*;
7pub use error::*;
8use reqwest::{Body, Method, RequestBuilder, Url};
9use serde_json::{json, Value};
10
11pub struct LineClient {
12    pub(crate) context: LineContext,
13}
14
15impl LineClient {
16    pub fn new(token: &str) -> Self {
17        Self {
18            context: LineContext {
19                token: Some(token.to_string()),
20            },
21        }
22    }
23}
24
25struct LineContext {
26    token: Option<String>,
27}
28
29pub type LineApiResponse<T> = Result<T, LineError>;
30
31impl LineClient {
32    async fn http_response_reqwest<R>(
33        response: Result<reqwest::Response, reqwest::Error>,
34    ) -> LineApiResponse<R>
35    where
36        R: for<'de> serde::Deserialize<'de>,
37    {
38        let response = match response {
39            Ok(v) => v,
40            Err(e) => return Err(LineSystemError::new(e.to_string()).into()),
41        };
42
43        let status = response.status();
44
45        let body = match response.bytes().await {
46            Ok(v) => v.to_vec(),
47            Err(e) => {
48                return Err(LineHttpError::new(status.as_u16(), e.to_string()).into());
49            }
50        };
51
52        let http_response_body = match String::from_utf8(body) {
53            Ok(v) => v,
54            Err(e) => return Err(LineSystemError::new(e.to_string()).into()),
55        };
56
57        let value = match serde_json::from_str::<Value>(http_response_body.as_str()) {
58            Ok(v) => v,
59            Err(e) => return Err(LineSystemError::new(e.to_string()).into()),
60        };
61
62        Self::http_response_text(status.as_u16(), http_response_body, value).await
63    }
64    async fn http_response_text<R>(
65        status: u16,
66        http_response_body: String,
67        value: Value,
68    ) -> LineApiResponse<R>
69    where
70        R: for<'de> serde::Deserialize<'de>,
71    {
72        if 400 <= status {
73            if let Ok(res) = serde_json::from_value(value.clone()) {
74                return Err(LineApiError {
75                    status: status,
76                    error: res,
77                    warnings: None,
78                    http_response_body: Some(http_response_body),
79                }
80                .into());
81            }
82        }
83
84        match serde_json::from_value(value.clone()) {
85            Ok(v) => Ok(v),
86            Err(e) => {
87                if let Ok(res) = serde_json::from_value(value.clone()) {
88                    return Err(LineApiError {
89                        status: status,
90                        error: res,
91                        warnings: None,
92                        http_response_body: Some(http_response_body),
93                    }
94                    .into());
95                }
96                Err(LineSystemError::new(e.to_string()).into())
97            }
98        }
99    }
100    pub(crate) async fn http_get<P, R>(&self, url: &str, value: &P) -> LineApiResponse<R>
101    where
102        P: serde::Serialize,
103        R: for<'de> serde::Deserialize<'de>,
104    {
105        let build = builder2(
106            Url::parse(url).unwrap(),
107            Method::GET,
108            self.context.token.clone().unwrap_or_default().as_str(),
109        );
110        let request = build.body(Body::from(json!(value).to_string()));
111        LineClient::http_response_reqwest(request.send().await).await
112    }
113    pub(crate) async fn http_get_stream<P>(&self, url: &str, value: &P) -> LineApiResponse<Vec<u8>>
114    where
115        P: serde::Serialize,
116    {
117        let build = builder2(
118            Url::parse(url).unwrap(),
119            Method::GET,
120            self.context.token.clone().unwrap_or_default().as_str(),
121        );
122        let request = build.body(Body::from(json!(value).to_string()));
123
124        let a = request.send().await.unwrap();
125        let stream = a.bytes().await.unwrap();
126        Ok(stream.to_vec())
127    }
128    pub(crate) async fn http_post<P, R>(&self, url: &str, value: &P) -> LineApiResponse<R>
129    where
130        P: serde::Serialize,
131        R: for<'de> serde::Deserialize<'de>,
132    {
133        let build = builder2(
134            Url::parse(url).unwrap(),
135            Method::POST,
136            self.context.token.clone().unwrap_or_default().as_str(),
137        );
138
139        let request = build.json(&json!(value));
140        LineClient::http_response_reqwest(request.send().await).await
141    }
142    pub(crate) async fn http_put<P, R>(&self, url: &str, value: &P) -> LineApiResponse<R>
143    where
144        P: serde::Serialize,
145        R: for<'de> serde::Deserialize<'de>,
146    {
147        let build = builder2(
148            Url::parse(url).unwrap(),
149            Method::PUT,
150            self.context.token.clone().unwrap_or_default().as_str(),
151        );
152
153        let request = build.json(&json!(value));
154        LineClient::http_response_reqwest(request.send().await).await
155    }
156    pub(crate) async fn http_delete<P, R>(&self, url: &str, value: &P) -> LineApiResponse<R>
157    where
158        P: serde::Serialize,
159        R: for<'de> serde::Deserialize<'de>,
160    {
161        let build = builder2(
162            Url::parse(url).unwrap(),
163            Method::DELETE,
164            self.context.token.clone().unwrap_or_default().as_str(),
165        );
166
167        let request = build.json(&json!(value));
168        LineClient::http_response_reqwest(request.send().await).await
169    }
170    pub(crate) async fn http_post_data<R>(&self, url: &str, content: Vec<u8>) -> LineApiResponse<R>
171    where
172        R: for<'de> serde::Deserialize<'de>,
173    {
174        let req = reqwest::Client::new()
175            .post(url)
176            .header(
177                "Authorization",
178                format!("Bearer {}", self.context.token.clone().unwrap().to_string()),
179            )
180            .header("Content-Type", "image/jpeg")
181            .body(content)
182            .send()
183            .await;
184
185        Self::http_response_reqwest(req).await
186    }
187}
188
189fn builder2(url: Url, method: reqwest::Method, token: &str) -> RequestBuilder {
190    reqwest::Client::new()
191        .request(method, url)
192        .header("Authorization", format!("Bearer {}", token))
193}
194
195// fn get_error_value(value: &Value) -> Vec<String> {
196//     match value.get("error") {
197//         None => {
198//             vec![]
199//         }
200//         Some(v) => {
201//             if v.is_string() {
202//                 return match v.as_str() {
203//                     None => {
204//                         vec![]
205//                     }
206//                     Some(v) => {
207//                         vec![v.to_string()]
208//                     }
209//                 };
210//             }
211//             vec![]
212//         }
213//     }
214// }