Код ниже - это начало небольшой библиотеки, которую я пишу, чтобы поговорить с веб-API.Пользователи библиотеки будут создавать экземпляр клиента MyClient
и получать к нему доступ через веб-API.Здесь я пытаюсь получить токен доступа от API, прежде чем отправлять запросы на него.
В get_new_access()
Я могу сделать запрос и получить ответ JSON.Затем я пытаюсь использовать serde для преобразования ответа в Access
структуру, и именно здесь начинаются проблемы.
Я создал библиотечную ошибку enum MyError
, которая может представлять десериализацию JSON иreqwest ошибки, которые могут возникнуть в пределах get_new_access()
.Однако, когда я иду на компиляцию, я получаю the trait serde::Deserialize<'_> is not implemented for MyError
.Насколько я понимаю, это происходит потому, что в случае, если я получаю одну из вышеупомянутых ошибок, serde не знает, как ее десериализовать в структуру Access
.Конечно, я вообще не хочу, чтобы это делалось, поэтому у меня вопрос: что мне делать?
Я смотрел на различные примеры десериализации serde, но все они, похоже, предполагают, что ониработает в основной функции, которая может возвращать только ошибку serde.Если я поставлю #[derive(Deserialize)]
выше объявления MyError
, я получу ту же ошибку, но вместо этого она перейдет на reqwest::Error
и serde_json::Error
.
use std::error;
use std::fmt;
extern crate chrono;
extern crate reqwest;
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
use chrono::prelude::*;
use reqwest::Client;
pub struct MyClient {
access: Access,
token_expires: DateTime<Utc>,
}
#[derive(Deserialize, Debug)]
struct Access {
access_token: String,
expires_in: i64,
token_type: String,
}
fn main() {
let sc: MyClient = MyClient::new();
println!("{:?}", &sc.access);
}
impl MyClient {
pub fn new() -> MyClient {
let a: Access = MyClient::get_new_access().expect("Couldn't get Access");
let e: DateTime<Utc> = chrono::Utc::now(); //TODO
MyClient {
access: a,
token_expires: e,
}
}
fn get_new_access() -> Result<Access, MyError> {
let params = ["test"];
let client = Client::new();
let json = client
.post(&[""].concat())
.form(¶ms)
.send()?
.text()
.expect("Couldn't get JSON Response");
println!("{}", &json);
serde_json::from_str(&json)?
//let a = Access {access_token: "Test".to_string(), expires_in: 3600, token_type: "Test".to_string() };
//serde_json::from_str(&json)?
}
}
#[derive(Debug)]
pub enum MyError {
WebRequestError(reqwest::Error),
ParseError(serde_json::Error),
}
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "eRROR")
}
}
impl error::Error for MyError {
fn description(&self) -> &str {
"API internal error"
}
fn cause(&self) -> Option<&error::Error> {
// Generic error, underlying cause isn't tracked.
None
}
}
impl From<serde_json::Error> for MyError {
fn from(e: serde_json::Error) -> Self {
MyError::ParseError(e)
}
}
impl From<reqwest::Error> for MyError {
fn from(e: reqwest::Error) -> Self {
MyError::WebRequestError(e)
}
}
ссылка на игровую площадку здесь .