use core::fmt;
use serde::{Deserialize, Serialize};
use serde_json::json;
use crate::{builder, DeepL, Error, Language};
#[derive(Debug, Copy, Clone, Serialize)]
pub enum SplitSentences {
#[serde(rename = "0")]
None,
#[serde(rename = "1")]
Default,
#[serde(rename = "lowercase")]
NoNewlines,
}
#[derive(Debug, Copy, Clone, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Formality {
Default,
More,
Less,
PreferMore,
PreferLess,
}
impl fmt::Display for Formality {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::Default => "default",
Self::More => "more",
Self::Less => "less",
Self::PreferMore => "prefer_more",
Self::PreferLess => "prefer_less",
};
s.fmt(f)
}
}
#[derive(Debug, Copy, Clone, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum TagHandling {
Xml,
Html,
}
#[derive(Debug, Deserialize)]
pub struct Translation {
pub detected_source_language: String,
pub text: String,
}
#[derive(Debug, Deserialize)]
pub struct TranslateTextResult {
pub translations: Vec<Translation>,
}
builder! {
Text {
@must{
target_lang: Language,
};
@optional{
source_lang: Language,
split_sentences: SplitSentences,
preserve_formatting: bool,
formality: Formality,
glossary_id: String,
tag_handling: TagHandling,
non_splitting_tags: Vec<String>,
outline_detection: bool,
splitting_tags: Vec<String>,
ignore_tags: Vec<String>,
text: Vec<String>,
};
}
}
impl DeepL {
pub fn translate(&self, opt: TextOptions) -> Result<TranslateTextResult, Error> {
let url = format!("{}/translate", self.url);
let obj = match opt.text.as_ref() {
None => return Err(Error::Api("text field must not be empty".to_string())),
Some(text) => {
if text.is_empty() || text.first().unwrap().is_empty() {
return Err(Error::Api("text field must not be empty".to_string()));
}
json!(opt)
}
};
let resp = self.post(url).json(&obj).send().map_err(Error::Reqwest)?;
if !resp.status().is_success() {
return Err(Error::Response(
resp.status(),
resp.text().unwrap_or_default(),
));
}
Ok(resp.json()?)
}
}