1use serde::Deserialize;
2use thiserror::Error;
3
4use std::{
5 time::{Duration, SystemTime},
6 error::Error as StdError,
7};
8
9pub fn acquire_access_token(
11 api_key: &str,
12 secret_key: &str,
13) -> Result<(String, SystemTime), Box<dyn StdError>> {
14 let before_acquire = SystemTime::now();
15 let result = ureq::post("https://aip.baidubce.com/oauth/2.0/token")
16 .set("Content-Type", "application/x-www-form-urlencoded")
17 .query("grant_type", "client_credentials")
18 .query("client_id", api_key)
19 .query("client_secret", secret_key)
20 .call()?
21 .into_string()?;
22
23 let token: Result<Token, serde_json::Error> = serde_json::from_str(&result);
24
25 if let Ok(token) = token {
26 let access_token = token.access_token;
27 let expires_time = before_acquire + Duration::from_secs(token.expires_in);
28
29 Ok((access_token, expires_time))
30 } else {
31 let error: VerifyError = serde_json::from_str(&result).unwrap();
32 Result::Err(error.into())
33 }
34}
35
36#[derive(Deserialize)]
37struct Token {
38 access_token: String,
40 expires_in: u64,
42}
43
44#[derive(Error, Deserialize, Debug)]
45enum VerifyError {
46 #[error("{0}")]
47 error(String),
48 #[error("{0}")]
49 error_description(String),
50}