use std::{fmt::Debug, sync::Arc};
use async_lock::RwLock;
use log::{error, info};
use serde::Deserialize;
use crate::api::{
context::BotXApiContext,
result::{BotXApiError, BotXApiResult},
v2::token::api::token,
};
use std::future::Future;
pub async fn retry_with_auth<Fut, TResponse, TError, TRequest: Fn() -> Fut>(
context: &Arc<RwLock<BotXApiContext>>,
request: TRequest,
) -> Result<TResponse, BotXApiError<TError>>
where
Fut: Future<Output = BotXApiResult<TResponse, TError>>,
{
let response = (request)().await;
let Err(err) = response else {
return response
};
if !err.is_unauthorized() {
return Result::<TResponse, BotXApiError<TError>>::Err(err);
}
info!("Действие токена истекло, презапрашиваем");
let mut context_write_lock = context.write().await;
let token_response = token(&mut *context_write_lock).await;
let Ok(token_result) = token_response else {
error!("Не удалось повторить запрос с переавторизацией");
return Result::<TResponse, BotXApiError<TError>>::Err(err);
};
context_write_lock.auth_token = Some(token_result.token);
(request)().await
}