use serde::{Deserialize, Serialize};
use crate::{DeepL, Error};
#[derive(Copy, Clone, Debug)]
pub enum LanguageType {
Source,
Target,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct LanguageInfo {
pub language: String,
pub name: String,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_formality: Option<bool>,
}
macro_rules! impl_language {
( $($lang:ident, $upper:literal, $name:literal,)* ) => {
#[derive(Copy, Clone, Debug, PartialEq, serde::Serialize)]
#[serde(rename_all = "SCREAMING-KEBAB-CASE")]
pub enum Language {
$(
#[doc = $name]
$lang,
)*
}
impl core::str::FromStr for Language {
type Err = crate::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_uppercase().as_str() {
$(
$upper => Ok(Self::$lang),
)*
_ => Err(crate::lang::ParseLanguageError(s.to_string()))?,
}
}
}
#[allow(unused)]
impl Language {
fn as_str(&self) -> &str {
match self {
$(
Self::$lang => $upper,
)*
}
}
}
impl AsRef<str> for Language {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl core::fmt::Display for Language {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.as_ref())
}
}
}
}
#[rustfmt::skip]
impl_language!(
Ar, "AR", " Arabic",
Bg, "BG", " Bulgarian",
Cs, "CS", " Czech",
Da, "DA", " Danish",
De, "DE", " German",
El, "EL", " Greek",
En, "EN", " English",
EnGb, "EN-GB", " English Britain",
EnUs, "EN-US", " English US",
Es, "ES", " Spanish",
Es419, "ES-419", " Spanish Latin America",
Et, "ET", " Estonian",
Fi, "FI", " Finish",
Fr, "FR", " French",
Hu, "HU", " Hungarian",
Id, "ID", " Indonesian",
It, "IT", " Italian",
Ja, "JA", " Japanese",
Ko, "KO", " Korean",
Lt, "LT", " Lithuanian",
Lv, "LV", " Latvian",
Nb, "NB", " Norwegian",
Nl, "NL", " Dutch",
Pl, "PL", " Polish",
Pt, "PT", " Portuguese",
PtBr, "PT-BR", " Portuguese Brazil",
PtPt, "PT-PT", " Portuguese Europe",
Ro, "RO", " Romanian",
Ru, "RU", " Russian",
Sk, "SK", " Slovak",
Sl, "SL", " Slovenian",
Sv, "SV", " Swedish",
Tr, "TR", " Turkish",
Uk, "UK", " Ukranian",
Zh, "ZH", " Chinese",
ZhHans, "ZH-HANS", " Chinese simplified",
ZhHant, "ZH-HANT", " Chinese traditional",
);
#[derive(Debug)]
pub struct ParseLanguageError(String);
impl core::fmt::Display for ParseLanguageError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "invalid language: {}", self.0)
}
}
impl std::error::Error for ParseLanguageError {}
impl DeepL {
pub fn languages(&self, lang_type: LanguageType) -> Result<Vec<LanguageInfo>, Error> {
let url = format!("{}/languages", self.url);
let kind = match lang_type {
LanguageType::Source => "source",
LanguageType::Target => "target",
};
let q = vec![("type", kind)];
let resp = self.get(url).query(&q).send().map_err(Error::Reqwest)?;
if !resp.status().is_success() {
return Err(Error::Response(
resp.status(),
resp.text().unwrap_or_default(),
));
}
Ok(resp.json()?)
}
}