11//https://docs.rs/crate/translation-api-cn/latest/source/src/baidu.rs
22
3+ use crate :: error:: Error ;
4+ use crate :: languages:: Language ;
5+ use crate :: translators:: translator_structure:: {
6+ TranslationOutput , TranslationVecOutput , TranslatorNoContext ,
7+ } ;
8+ use async_trait:: async_trait;
39use reqwest:: Client ;
410use serde:: { Deserialize , Serialize } ;
511use serde_json:: Value ;
12+ use std:: str:: FromStr ;
613
714#[ allow( dead_code) ]
8- struct BaiduApiTranslator {
15+ pub struct BaiduApiTranslator {
916 url : String ,
17+ app_id : String ,
18+ key : String ,
1019}
1120
12- #[ allow( dead_code) ]
13- impl BaiduApiTranslator {
14- pub fn new ( ) -> Self {
15- Self {
16- url : "https://fanyi-api.baidu.com/api/trans/vip/translate" . to_string ( ) ,
17- }
18- }
19-
20- pub async fn translate (
21+ #[ async_trait]
22+ impl TranslatorNoContext for BaiduApiTranslator {
23+ async fn translate (
2124 & self ,
2225 client : & Client ,
2326 query : & str ,
24- from : & str ,
25- to : & str ,
26- key : & str ,
27- appid : & str ,
28- ) {
29- let form = Form :: new ( appid, query, "0" , key, from, to) ;
30- let resp = client
27+ from : Option < Language > ,
28+ to : & Language ,
29+ ) -> Result < TranslationOutput , Error > {
30+ let form = Form :: new (
31+ & self . app_id ,
32+ query,
33+ "0" ,
34+ & self . key ,
35+ & from
36+ . map ( |v| v. to_baidu_str ( ) )
37+ . unwrap_or_else ( || Ok ( "auto" . to_string ( ) ) ) ?,
38+ & to. to_baidu_str ( ) ?,
39+ ) ;
40+ let resp: Response = client
3141 . post ( & self . url )
3242 . form ( & form)
3343 . send ( )
3444 . await
35- . unwrap ( )
36- . text ( )
45+ . map_err ( Error :: fetch ) ?
46+ . json ( )
3747 . await
38- . unwrap ( ) ;
39- print ! ( "{}" , resp) ;
48+ . map_err ( Error :: fetch) ?;
49+ let resp = match resp {
50+ Response :: Ok ( v) => v,
51+ Response :: Err ( v) => return Err ( Error :: baidu_error ( v) ) ,
52+ } ;
53+ Ok ( TranslationOutput {
54+ text : resp
55+ . trans_result
56+ . iter ( )
57+ . map ( |v| v. dst . to_string ( ) )
58+ . collect :: < Vec < _ > > ( )
59+ . join ( "\n " ) ,
60+ lang : Language :: from_str ( & resp. from ) . unwrap_or ( Language :: Unknown ) ,
61+ } )
62+ }
63+
64+ async fn translate_vec (
65+ & self ,
66+ client : & Client ,
67+ query : & [ String ] ,
68+ from : Option < Language > ,
69+ to : & Language ,
70+ ) -> Result < TranslationVecOutput , Error > {
71+ let v = self . translate ( client, & query. join ( "\n " ) , from, to) . await ?;
72+ Ok ( TranslationVecOutput {
73+ text : v. text . split ( '\n' ) . map ( |v| v. to_string ( ) ) . collect ( ) ,
74+ lang : v. lang ,
75+ } )
76+ }
77+ }
78+
79+ #[ allow( dead_code) ]
80+ impl BaiduApiTranslator {
81+ pub fn new ( app_id : & str , key : & str ) -> Self {
82+ Self {
83+ url : "https://fanyi-api.baidu.com/api/trans/vip/translate" . to_string ( ) ,
84+ app_id : app_id. to_string ( ) ,
85+ key : key. to_string ( ) ,
86+ }
4087 }
4188}
4289
@@ -67,30 +114,25 @@ impl Form {
67114}
68115
69116/// Response information. Either return the translation result, or return an error message.
70- #[ derive( Debug , Deserialize ) ]
117+ #[ derive( Deserialize ) ]
71118#[ serde( untagged) ]
72- pub enum Response {
73- Ok {
74- from : String ,
75- to : String ,
76- /// Multiple translated texts separated by `\n` in the original text.
77- #[ serde( rename = "trans_result" ) ]
78- res : Vec < Value > ,
79- } ,
80- Err ( Error ) ,
119+ enum Response {
120+ Ok ( TranslationResponse ) ,
121+ Err ( BaiduApiError ) ,
81122}
82123
83124/// Error handling / error code
84125#[ derive( Debug , Clone , Deserialize ) ]
85- pub struct Error {
126+ pub struct BaiduApiError {
86127 #[ serde( rename = "error_code" ) ]
87128 pub code : String ,
88129 #[ serde( rename = "error_msg" ) ]
89130 pub msg : String ,
131+ pub data : Option < Value > ,
90132}
91133
92- impl std:: error:: Error for Error { }
93- impl std:: fmt:: Display for Error {
134+ impl std:: error:: Error for BaiduApiError { }
135+ impl std:: fmt:: Display for BaiduApiError {
94136 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
95137 write ! ( f,
96138 "Error code: `{}`\n Error message: `{}`\n Error meaning: {}\n The above content is returned by Baidu translation API" ,
@@ -100,7 +142,7 @@ impl std::fmt::Display for Error {
100142 }
101143}
102144
103- impl Error {
145+ impl BaiduApiError {
104146 ///Reference: [Error Code List](https://fanyi-api.baidu.com/doc/21)
105147 pub fn solution ( & self ) -> & str {
106148 match self . code . as_bytes ( ) {
@@ -123,3 +165,18 @@ impl Error {
123165 }
124166 }
125167}
168+
169+ #[ derive( Deserialize ) ]
170+ #[ allow( dead_code) ]
171+ struct Sentence {
172+ pub src : String ,
173+ pub dst : String ,
174+ }
175+
176+ #[ derive( Deserialize ) ]
177+ #[ allow( dead_code) ]
178+ struct TranslationResponse {
179+ pub from : String ,
180+ pub to : String ,
181+ pub trans_result : Vec < Sentence > ,
182+ }
0 commit comments