use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt};
use reqwest::header;
use crate::{DeepL, Error, Language};
#[derive(Debug, Deserialize, Serialize)]
pub struct GlossaryLanguagePair {
pub source_lang: String,
pub target_lang: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct GlossaryLanguagePairsResult {
pub supported_languages: Vec<GlossaryLanguagePair>,
}
#[derive(Clone, Copy, Debug)]
pub enum GlossaryEntriesFormat {
Tsv,
Csv,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Glossary {
pub glossary_id: String,
pub ready: bool,
pub name: String,
pub source_lang: String,
pub target_lang: String,
pub creation_time: String,
pub entry_count: u64,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct GlossariesResult {
pub glossaries: Vec<Glossary>,
}
impl AsRef<str> for GlossaryEntriesFormat {
fn as_ref(&self) -> &str {
match self {
Self::Tsv => "tsv",
Self::Csv => "csv",
}
}
}
impl fmt::Display for GlossaryEntriesFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_ref())
}
}
impl DeepL {
pub fn glossary_languages(&self) -> Result<GlossaryLanguagePairsResult, Error> {
let url = format!("{}/glossary-language-pairs", self.url);
let resp = self.get(url).send().map_err(Error::Reqwest)?;
if !resp.status().is_success() {
return Err(Error::Response(
resp.status(),
resp.text().unwrap_or_default(),
));
}
Ok(resp.json()?)
}
pub fn glossary_new(
&self,
name: String,
source_lang: Language,
target_lang: Language,
entries: String,
fmt: GlossaryEntriesFormat,
) -> Result<Glossary, Error> {
let url = format!("{}/glossaries", self.url);
let params = HashMap::from([
("name", name),
("source_lang", source_lang.to_string()),
("target_lang", target_lang.to_string()),
("entries", entries),
("entries_format", fmt.to_string()),
]);
let resp = self
.post(url)
.form(¶ms)
.send()
.map_err(Error::Reqwest)?;
if !resp.status().is_success() {
return Err(Error::Response(
resp.status(),
resp.text().unwrap_or_default(),
));
}
Ok(resp.json()?)
}
pub fn glossaries(&self) -> Result<GlossariesResult, Error> {
let url = format!("{}/glossaries", self.url);
let resp = self.get(url).send().map_err(Error::Reqwest)?;
if !resp.status().is_success() {
return Err(Error::Response(
resp.status(),
resp.text().unwrap_or_default(),
));
}
Ok(resp.json()?)
}
pub fn glossary_info(&self, glossary_id: &str) -> Result<Glossary, Error> {
let url = format!("{}/glossaries/{}", self.url, glossary_id);
let resp = self.get(url).send().map_err(Error::Reqwest)?;
if !resp.status().is_success() {
return Err(Error::Response(
resp.status(),
resp.text().unwrap_or_default(),
));
}
Ok(resp.json()?)
}
pub fn glossary_entries(&self, glossary_id: &str) -> Result<HashMap<String, String>, Error> {
let url = format!("{}/glossaries/{}/entries", self.url, glossary_id);
let accept = header::HeaderValue::from_static("text/tab-separated-values");
let resp = self
.get(url)
.header(header::ACCEPT, accept)
.send()
.map_err(Error::Reqwest)?;
if !resp.status().is_success() {
return Err(Error::Response(
resp.status(),
resp.text().unwrap_or_default(),
));
}
let t = resp.text()?;
let raw_entries: Vec<&str> = t.split('\n').collect();
let mut map = HashMap::new();
for entry in raw_entries {
let words: Vec<&str> = entry.split('\t').collect();
if words.len() != 2 {
continue;
}
map.insert(words[0].to_string(), words[1].to_string());
}
Ok(map)
}
pub fn glossary_delete(&self, glossary_id: &str) -> Result<(), Error> {
let url = format!("{}/glossaries/{}", self.url, glossary_id);
let _ = self.delete(url).send().map_err(Error::Reqwest);
Ok(())
}
}