extern crate reqwest;
#[cfg(test)]
mod tests {
#[test]
fn test() {
crate::translate(crate::Yandex{},"J'aime les biscuits. Et toi".to_string(),crate::Langage::FR,crate::Langage::EN,|x| {
assert_eq!("I love the biscuits. And you",x.unwrap());
});
crate::translate(crate::Google{},"J'aime les biscuits. Et toi".to_string(),crate::Langage::FR,crate::Langage::EN,|x| {
assert_eq!("I like cookies. And you",x.unwrap());
});
crate::translate(crate::Google{},"J'aime les biscuits. Et toi".to_string(),crate::Langage::FR,crate::Langage::ES,|x| {
assert_eq!("Me gustan las galletas Y tu",x.unwrap());
});
crate::detect(crate::Yandex{},"J'aime les biscuits et vous".to_string(), |x| {
assert_eq!(crate::Langage::FR,x.unwrap());
});
std::thread::sleep(std::time::Duration::from_secs(5));
}
}
pub fn yandex() -> Yandex {
Yandex{}
}
pub fn google() -> Yandex {
Yandex{}
}
fn post_connect(url: &str,body: String) -> Option<String> {
match reqwest::Client::new().post(url)
.body(body)
.send() {
Ok(mut e) => {
match e.text() {
Ok(e1) => {
Some(e1)
},
_ => {
None
}
}
},
Err(o) => {
panic!("{}",o);
None
},
_ => {
None
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum Langage {
EN,
FR,
DE,
NL,
ES,
IT,
RU
}
pub struct Google;
pub struct Yandex;
impl EDetect for Yandex {
fn detect(&self,text: String) -> Option<Langage> {
let hj = format!("https://translate.yandex.net/api/v1.5/tr.json/detect?key=trnsl.1.1.20190116T152422Z.a2fee223a3bc5eba.42ea6ba7d5338c7c0132eec6fb5374232029fb9d&text={}", text.replace(" ","%20"));
match post_connect(&hj,"".to_string()) {
Some(i) => {
let mut h = false;
if !i.contains("\"lang\":\"") {
return None;
}
for j in i.split("\"lang\":\"") {
if !h {
h = true;
continue;
}
if !i.contains("\"}") {
return None;
}
for w in j.split("\"}") {
return string_to_langage(w.to_string());
}
return None;
}
return None;
},
_ => {
return None;
}
}
}
}
impl std::cmp::PartialEq<Langage> for Langage {
fn eq(&self, other: &Langage) -> bool {
match (self, other) {
(Langage::EN,Langage::EN) => true,
(Langage::FR,Langage::FR) => true,
(Langage::DE,Langage::DE) => true,
(Langage::RU,Langage::RU) => true,
(Langage::NL,Langage::NL) => true,
(Langage::ES,Langage::ES) => true,
(Langage::IT,Langage::IT) => true,
(_, _) => false,
}
}
}
impl ETranslate for Yandex {
fn translate(&self,text: String,_in: Langage,_out: Langage) -> Option<String> {
let hj = format!("https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20190116T152422Z.a2fee223a3bc5eba.42ea6ba7d5338c7c0132eec6fb5374232029fb9d&text={}&lang={}", text.replace(" ","%20"), format!("{:?}-{:?}", _in, _out).to_lowercase());
match post_connect(&hj,"".to_string()) {
Some(i) => {
let mut h = false;
if !i.contains("\",\"text\":[\"") {
return None;
}
for j in i.split("\",\"text\":[\"") {
if !h {
h = true;
continue;
}
if !i.contains("\"]}") {
return None;
}
for w in j.split("\"]}") {
return Some(w.to_string());
}
return None;
}
None
},
_ => None
}
}
}
impl ETranslate for Google {
fn translate(&self,text: String,_in: Langage,_out: Langage) -> Option<String> {
let ol = [("sl", format!("{:?}",_in)), ("tl", format!("{:?}",_out)), ("q", text)];
match reqwest::Client::new().post("https://translate.google.com/translate_a/single?client=at&dt=t&dt=ld&dt=qca&dt=rm&dt=bd&dj=1&hl=fr-FR&ie=UTF-8&oe=UTF-8&inputm=2&otf=2&iid=1dd3b944-fa62-4b55-b330-74909a99969e")
.header("User-Agent","AndroidTranslate/5.3.0.RC02.130475354-53000263 5.1 phone TRANSLATE_OPM5_TEST_1".to_string())
.form(&ol)
.send() {
Ok(mut e) => {
match e.text() {
Ok(i) => {
if !i.contains("{\"trans\":\"") {
return None;
}
let mut a = "".to_string();
let mut h = false;
for j in i.split("{\"trans\":\"") {
if !h {
h = true;
continue;
}
for m in j.split("\",\"orig\":\"") {
a = format!("{}{}",a,m);
break;
}
}
Some(a)
},
_ => None
}
},
_ => None
}
}
}
pub trait ETranslate {
fn translate(&self,text: String,_in: Langage,_out: Langage) -> Option<String>;
}
pub trait EDetect {
fn detect(&self,text: String) -> Option<Langage>;
}
pub fn translate<T,Q>(tr: T,text: String,_in: Langage,_out: Langage,end: Q)
where T: Send + 'static + ETranslate,
Q: Send + 'static + FnOnce(Option<String>){
std::thread::spawn(move || {
let mut newtext = "".to_string();
for (_i, c) in text.chars().enumerate() {
newtext = format!("{}{}",newtext,c);
}
end(tr.translate(newtext,_in,_out));
});
}
pub fn detect<T,Q>(tr: T,text: String,end: Q)
where T: Send + 'static + EDetect,
Q: Send + 'static + FnOnce(Option<Langage>){
std::thread::spawn(move || {
let mut newtext = "".to_string();
for (_i, c) in text.chars().enumerate() {
newtext = format!("{}{}",newtext,c);
}
end(tr.detect(newtext));
});
}
impl std::fmt::Display for Langage {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub fn string_to_langage(st: String) -> Option<Langage> {
let fg: &str = &(st.to_lowercase());
match fg {
"en" => Some(Langage::EN),
"fr" => Some(Langage::FR),
"de" => Some(Langage::DE),
"es" => Some(Langage::ES),
"nl" => Some(Langage::NL),
"it" => Some(Langage::IT),
"ru" => Some(Langage::RU),
_ => None
}
}