use serde::{Deserialize, Serialize};
use std::{future::Future, pin::Pin};
use thiserror::Error;
pub mod document;
pub mod glossary;
pub mod languages;
pub mod translate;
pub mod usage;
#[derive(Debug, Error)]
pub enum Error {
#[error("invalid response: {0}")]
InvalidResponse(String),
#[error("request fail: {0}")]
RequestFail(String),
#[error("fail to read file {0}: {1}")]
ReadFileError(String, tokio::io::Error),
#[error(
"trying to download a document using a non-existing document ID or the wrong document key"
)]
NonExistDocument,
#[error("tries to download a translated document that is currently being processed and is not yet ready for download")]
TranslationNotDone,
#[error("fail to write file: {0}")]
WriteFileError(String),
}
const REPO_URL: &'static str = "https://github.com/Avimitin/deepl-rs";
type Result<T, E = Error> = std::result::Result<T, E>;
type Pollable<'poll, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'poll>>;
#[macro_export]
macro_rules! impl_requester {
(
$name:ident {
@required{
$($must_field:ident: $must_type:ty,)+
};
@optional{
$($opt_field:ident: $opt_type:ty,)*
};
} -> $fut_ret:ty;
) => {
use paste::paste;
use $crate::{DeepLApi, Error};
paste! {
#[doc = "Builder type for `" $name "`"]
pub struct $name<'a> {
client: &'a DeepLApi,
$($must_field: $must_type,)+
$($opt_field: Option<$opt_type>,)*
}
impl<'a> $name<'a> {
pub fn new(client: &'a DeepLApi, $($must_field: $must_type,)+) -> Self {
Self {
client,
$($must_field,)+
$($opt_field: None,)*
}
}
$(
#[doc = "Setter for `" $opt_field "`"]
pub fn $opt_field(&mut self, $opt_field: $opt_type) -> &mut Self {
self.$opt_field = Some($opt_field);
self
}
)*
}
}
};
}
#[derive(Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Formality {
Default,
More,
Less,
PreferMore,
PreferLess,
}
impl AsRef<str> for Formality {
fn as_ref(&self) -> &str {
match self {
Self::Default => "default",
Self::More => "more",
Self::Less => "less",
Self::PreferMore => "prefer_more",
Self::PreferLess => "prefer_less",
}
}
}
impl std::fmt::Display for Formality {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_ref())
}
}
#[derive(Deserialize)]
struct DeepLErrorResp {
message: String,
}
async fn extract_deepl_error<T>(res: reqwest::Response) -> Result<T> {
let resp = res
.json::<DeepLErrorResp>()
.await
.map_err(|err| Error::InvalidResponse(format!("invalid error response: {err}")))?;
Err(Error::RequestFail(resp.message))
}