1
1
use anyhow:: { Result , ensure} ;
2
+ use once_cell:: sync:: Lazy ;
2
3
use scraper:: { Html , Selector } ;
3
4
use serde:: { Deserialize , Serialize } ;
4
5
@@ -45,6 +46,26 @@ pub enum TranslationData {
45
46
ToEnglish ( ToEnglish ) ,
46
47
}
47
48
49
+ macro_rules! selector {
50
+ ( $css: expr) => {
51
+ Lazy :: new( || Selector :: parse( $css) . expect( concat!( "Invalid selector: " , $css) ) )
52
+ } ;
53
+ }
54
+
55
+ #[ rustfmt:: skip]
56
+ mod selectors {
57
+ use super :: * ;
58
+
59
+ pub static PRONUNCIATION_SELECTOR : Lazy < Selector > = selector ! ( ".phone_con .per-phone .phonetic" ) ;
60
+ pub static MEANINGS_SELECTOR : Lazy < Selector > = selector ! ( ".trans-container .basic .word-exp" ) ;
61
+ pub static DEFINITIONS_SELECTOR : Lazy < Selector > = selector ! ( ".trans" ) ;
62
+ pub static PART_OF_SPEECH_SELECTOR : Lazy < Selector > = selector ! ( ".pos" ) ;
63
+ pub static EXAMPLE_SELECTOR : Lazy < Selector > = selector ! ( ".trans-container .mcols-layout .col2" ) ;
64
+ pub static EN_SELECTOR : Lazy < Selector > = selector ! ( ".sen-eng" ) ;
65
+ pub static ZH_SELECTOR : Lazy < Selector > = selector ! ( ".sen-ch" ) ;
66
+ pub static TO_ENGLISH_TRANSLATION_SELECTOR : Lazy < Selector > = selector ! ( ".trans-container .basic .col2 .point" ) ;
67
+ }
68
+
48
69
/// Parses English, returns Chinese
49
70
///
50
71
/// # Errors
@@ -59,11 +80,11 @@ pub fn to_chinese(input_text: &str, html: &str) -> Result<ToChinese> {
59
80
..Default :: default ( )
60
81
} ;
61
82
62
- // Pronunciation
63
- let pronunciation_selector = Selector :: parse ( ".phone_con .per-phone .phonetic" )
64
- . map_err ( |e| anyhow :: anyhow! ( "Selector parse error: {}" , e ) ) ? ;
65
-
66
- for ( i , element ) in document . select ( & pronunciation_selector ) . take ( 2 ) . enumerate ( ) {
83
+ for ( i , element ) in document
84
+ . select ( & selectors :: PRONUNCIATION_SELECTOR )
85
+ . take ( 2 )
86
+ . enumerate ( )
87
+ {
67
88
let text = element
68
89
. text ( )
69
90
. collect :: < String > ( )
@@ -80,22 +101,14 @@ pub fn to_chinese(input_text: &str, html: &str) -> Result<ToChinese> {
80
101
}
81
102
}
82
103
83
- // Translations
84
- let meanings_selector = Selector :: parse ( ".trans-container .basic .word-exp" )
85
- . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
86
- let definitions_selector =
87
- Selector :: parse ( ".trans" ) . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
88
- let part_of_speech_selector =
89
- Selector :: parse ( ".pos" ) . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
90
-
91
- for element in document. select ( & meanings_selector) {
104
+ for element in document. select ( & selectors:: MEANINGS_SELECTOR ) {
92
105
let part_of_speech = element
93
- . select ( & part_of_speech_selector )
106
+ . select ( & selectors :: PART_OF_SPEECH_SELECTOR )
94
107
. next ( )
95
108
. map ( |e| e. text ( ) . collect :: < String > ( ) . trim ( ) . to_owned ( ) ) ;
96
109
97
110
let definitions: Vec < String > = element
98
- . select ( & definitions_selector )
111
+ . select ( & selectors :: DEFINITIONS_SELECTOR )
99
112
. next ( )
100
113
. map ( |e| {
101
114
e. text ( )
@@ -116,22 +129,15 @@ pub fn to_chinese(input_text: &str, html: &str) -> Result<ToChinese> {
116
129
}
117
130
118
131
// Example sentences
119
- let example_selector = Selector :: parse ( ".trans-container .mcols-layout .col2" )
120
- . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
121
- let en_selector =
122
- Selector :: parse ( ".sen-eng" ) . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
123
- let zh_selector =
124
- Selector :: parse ( ".sen-ch" ) . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
125
-
126
- for element in document. select ( & example_selector) {
132
+ for element in document. select ( & selectors:: EXAMPLE_SELECTOR ) {
127
133
let en = element
128
- . select ( & en_selector )
134
+ . select ( & selectors :: EN_SELECTOR )
129
135
. next ( )
130
136
. map ( |e| e. text ( ) . collect :: < String > ( ) . trim ( ) . to_owned ( ) )
131
137
. unwrap_or_default ( ) ;
132
138
133
139
let zh = element
134
- . select ( & zh_selector )
140
+ . select ( & selectors :: ZH_SELECTOR )
135
141
. next ( )
136
142
. map ( |e| e. text ( ) . collect :: < String > ( ) . trim ( ) . to_owned ( ) )
137
143
. unwrap_or_default ( ) ;
@@ -167,32 +173,24 @@ pub fn to_english(input_text: &str, html: &str) -> Result<ToEnglish> {
167
173
} ;
168
174
169
175
// Meanings
170
- let translation_selector = Selector :: parse ( ".trans-container .basic .col2 .point" )
171
- . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
172
- for element in document. select ( & translation_selector) {
176
+ for element in document. select ( & selectors:: TO_ENGLISH_TRANSLATION_SELECTOR ) {
173
177
let text = element. text ( ) . collect :: < String > ( ) . trim ( ) . to_owned ( ) ;
174
178
if !text. is_empty ( ) {
175
179
result. meanings . push ( text) ;
176
180
}
177
181
}
178
182
179
183
// Example sentences
180
- let example_selector = Selector :: parse ( ".trans-container .mcols-layout .col2" )
181
- . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
182
- let en_selector =
183
- Selector :: parse ( ".sen-eng" ) . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
184
- let zh_selector =
185
- Selector :: parse ( ".sen-ch" ) . map_err ( |e| anyhow:: anyhow!( "Selector parse error: {}" , e) ) ?;
186
-
187
- for element in document. select ( & example_selector) {
184
+
185
+ for element in document. select ( & selectors:: EXAMPLE_SELECTOR ) {
188
186
let en = element
189
- . select ( & en_selector )
187
+ . select ( & selectors :: EN_SELECTOR )
190
188
. next ( )
191
189
. map ( |el| el. text ( ) . collect :: < String > ( ) . trim ( ) . to_owned ( ) )
192
190
. unwrap_or_default ( ) ;
193
191
194
192
let zh = element
195
- . select ( & zh_selector )
193
+ . select ( & selectors :: ZH_SELECTOR )
196
194
. next ( )
197
195
. map ( |el| el. text ( ) . collect :: < String > ( ) . trim ( ) . to_owned ( ) )
198
196
. unwrap_or_default ( ) ;
0 commit comments