use anyhow::Result;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::Client;
pub struct API {
pub client: Client,
}
impl API {
pub fn new(client: Client) -> Self {
Self { client }
}
}
pub trait Request: Serialize + Send + Sync {}
#[derive(Error, Debug)]
pub enum ApiError {
#[error("Telegram error: {0}")]
AppError(String),
#[error("Client error: {0}")]
ClientError(String),
#[error("No result")]
NoResult,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ApiResponse<T> {
pub ok: bool,
pub description: Option<String>,
pub result: Option<T>,
}
#[allow(clippy::should_implement_trait)]
impl<'de, T: Deserialize<'de>> ApiResponse<T> {
pub fn from_str(data: &'de str) -> Result<Self> {
let response: ApiResponse<T> = serde_json::from_str(data)?;
Ok(response)
}
}
impl<T> ApiResponse<T> {
#[allow(non_snake_case)]
pub fn Ok(result: T) -> Self {
Self {
ok: true,
description: None,
result: Some(result),
}
}
#[allow(non_snake_case)]
pub fn Err(description: impl Into<String>) -> Self {
Self {
ok: false,
description: Some(description.into()),
result: None,
}
}
pub fn is_ok(&self) -> bool {
self.ok
}
pub fn result(&self) -> Result<&T> {
if !self.ok {
return Err(ApiError::AppError(
self.description
.clone()
.unwrap_or("No error description".to_string()),
)
.into());
}
if self.result.is_none() {
return Err(ApiError::NoResult.into());
}
Ok(self.result.as_ref().unwrap())
}
}