use serde::Deserialize;
use super::{Error, Result};
use crate::{builder, DeepL, Language};
#[derive(Copy, Clone)]
pub enum SplitSentences {
None,
Default,
NoNewlines,
}
#[derive(Copy, Clone)]
pub enum Formality {
Default,
More,
Less,
PreferMore,
PreferLess,
}
#[derive(Copy, Clone)]
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>,
}
impl AsRef<str> for SplitSentences {
fn as_ref(&self) -> &str {
match self {
Self::None => "0",
Self::Default => "1",
Self::NoNewlines => "nonewlines",
}
}
}
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::str::FromStr for Formality {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let fm = match s {
"more" => Self::More,
"less" => Self::Less,
"prefer_more" => Self::PreferMore,
"prefer_less" => Self::PreferLess,
_ => Self::Default,
};
Ok(fm)
}
}
impl AsRef<str> for TagHandling {
fn as_ref(&self) -> &str {
match self {
Self::Xml => "xml",
Self::Html => "html",
}
}
}
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: String,
outline_detection: bool,
splitting_tags: String,
ignore_tags: String,
};
}
}
impl TextOptions {
fn into_form(self) -> Vec<(&'static str, String)> {
let mut form = vec![];
form.push(("target_lang", self.target_lang.to_string()));
if let Some(src) = self.source_lang {
form.push(("source_lang", src.as_ref().to_string()));
}
if let Some(ss) = self.split_sentences {
form.push(("split_sentences", ss.as_ref().to_string()));
}
if let Some(pf) = self.preserve_formatting {
if pf {
form.push(("preserve_formatting", "1".to_string()));
}
}
if let Some(fm) = self.formality {
form.push(("formality", fm.as_ref().to_string()));
}
if let Some(g) = self.glossary_id {
form.push(("glossary_id", g));
}
if let Some(th) = self.tag_handling {
form.push(("tag_handling", th.as_ref().to_string()));
}
if let Some(non) = self.non_splitting_tags {
form.push(("non_splitting_tags", non));
}
if let Some(od) = self.outline_detection {
if !od {
form.push(("outline_detection", "0".to_string()));
}
}
if let Some(sp) = self.splitting_tags {
form.push(("splitting_tags", sp));
}
if let Some(ig) = self.ignore_tags {
form.push(("ignore_tags", ig));
}
form
}
}
impl DeepL {
pub fn translate(&self, opt: TextOptions, text: Vec<String>) -> Result<TranslateTextResult> {
if text.is_empty() || text[0].is_empty() {
return Err(Error::Client("empty text parameter".to_string()));
}
let url = format!("{}/translate", self.url);
let mut params = opt.into_form();
for t in text {
params.push(("text", t));
}
let resp = self
.post(url)
.form(¶ms)
.send()
.map_err(Error::Reqwest)?;
if !resp.status().is_success() {
return super::convert(resp);
}
resp.json().map_err(|_| Error::Deserialize)
}
}