1
- //! International domain names
2
- //!
3
- //! https://url.spec.whatwg.org/#idna
1
+ // Copyright 2013-2014 Valentin Gosu.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6
+ // option. This file may not be copied, modified, or distributed
7
+ // except according to those terms.
8
+
9
+ //! [*Unicode IDNA Compatibility Processing*
10
+ //! (Unicode Technical Standard #46)](http://www.unicode.org/reports/tr46/)
4
11
5
12
use self :: Mapping :: * ;
6
13
use punycode;
@@ -9,7 +16,7 @@ use unicode_normalization::UnicodeNormalization;
9
16
use unicode_normalization:: char:: is_combining_mark;
10
17
use unicode_bidi:: { BidiClass , bidi_class} ;
11
18
12
- include ! ( "idna_mapping .rs" ) ;
19
+ include ! ( "uts46_mapping_table .rs" ) ;
13
20
14
21
#[ derive( Debug ) ]
15
22
enum Mapping {
@@ -23,9 +30,9 @@ enum Mapping {
23
30
}
24
31
25
32
struct Range {
26
- pub from : char ,
27
- pub to : char ,
28
- pub mapping : Mapping ,
33
+ from : char ,
34
+ to : char ,
35
+ mapping : Mapping ,
29
36
}
30
37
31
38
fn find_char ( codepoint : char ) -> & ' static Mapping {
@@ -45,7 +52,7 @@ fn find_char(codepoint: char) -> &'static Mapping {
45
52
& TABLE [ min] . mapping
46
53
}
47
54
48
- fn map_char ( codepoint : char , flags : Uts46Flags , output : & mut String , errors : & mut Vec < Error > ) {
55
+ fn map_char ( codepoint : char , flags : Flags , output : & mut String , errors : & mut Vec < Error > ) {
49
56
match * find_char ( codepoint) {
50
57
Mapping :: Valid => output. push ( codepoint) ,
51
58
Mapping :: Ignored => { } ,
@@ -185,7 +192,7 @@ fn passes_bidi(label: &str, transitional_processing: bool) -> bool {
185
192
}
186
193
187
194
/// http://www.unicode.org/reports/tr46/#Validity_Criteria
188
- fn validate ( label : & str , flags : Uts46Flags , errors : & mut Vec < Error > ) {
195
+ fn validate ( label : & str , flags : Flags , errors : & mut Vec < Error > ) {
189
196
if label. nfc ( ) . ne ( label. chars ( ) ) {
190
197
errors. push ( Error :: ValidityCriteria ) ;
191
198
}
@@ -212,7 +219,7 @@ fn validate(label: &str, flags: Uts46Flags, errors: &mut Vec<Error>) {
212
219
}
213
220
214
221
/// http://www.unicode.org/reports/tr46/#Processing
215
- fn uts46_processing ( domain : & str , flags : Uts46Flags , errors : & mut Vec < Error > ) -> String {
222
+ fn processing ( domain : & str , flags : Flags , errors : & mut Vec < Error > ) -> String {
216
223
let mut mapped = String :: new ( ) ;
217
224
for c in domain. chars ( ) {
218
225
map_char ( c, flags, & mut mapped, errors)
@@ -226,7 +233,7 @@ fn uts46_processing(domain: &str, flags: Uts46Flags, errors: &mut Vec<Error>) ->
226
233
if label. starts_with ( "xn--" ) {
227
234
match punycode:: decode_to_string ( & label[ "xn--" . len ( ) ..] ) {
228
235
Some ( decoded_label) => {
229
- let flags = Uts46Flags { transitional_processing : false , ..flags } ;
236
+ let flags = Flags { transitional_processing : false , ..flags } ;
230
237
validate ( & decoded_label, flags, errors) ;
231
238
validated. push_str ( & decoded_label)
232
239
}
@@ -241,14 +248,14 @@ fn uts46_processing(domain: &str, flags: Uts46Flags, errors: &mut Vec<Error>) ->
241
248
}
242
249
243
250
#[ derive( Copy , Clone ) ]
244
- pub struct Uts46Flags {
251
+ pub struct Flags {
245
252
pub use_std3_ascii_rules : bool ,
246
253
pub transitional_processing : bool ,
247
254
pub verify_dns_length : bool ,
248
255
}
249
256
250
257
#[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
251
- pub enum Error {
258
+ enum Error {
252
259
PunycodeError ,
253
260
ValidityCriteria ,
254
261
DissallowedByStd3AsciiRules ,
@@ -257,11 +264,18 @@ pub enum Error {
257
264
TooLongForDns ,
258
265
}
259
266
267
+ /// Errors recorded during UTS #46 processing.
268
+ ///
269
+ /// This is opaque for now, only indicating the precense of at least one error.
270
+ /// More details may be exposed in the future.
271
+ #[ derive( Debug ) ]
272
+ pub struct Errors ( Vec < Error > ) ;
273
+
260
274
/// http://www.unicode.org/reports/tr46/#ToASCII
261
- pub fn uts46_to_ascii ( domain : & str , flags : Uts46Flags ) -> Result < String , Vec < Error > > {
275
+ pub fn to_ascii ( domain : & str , flags : Flags ) -> Result < String , Errors > {
262
276
let mut errors = Vec :: new ( ) ;
263
277
let mut result = String :: new ( ) ;
264
- for label in uts46_processing ( domain, flags, & mut errors) . split ( '.' ) {
278
+ for label in processing ( domain, flags, & mut errors) . split ( '.' ) {
265
279
if result. len ( ) > 0 {
266
280
result. push ( '.' ) ;
267
281
}
@@ -288,36 +302,21 @@ pub fn uts46_to_ascii(domain: &str, flags: Uts46Flags) -> Result<String, Vec<Err
288
302
if errors. is_empty ( ) {
289
303
Ok ( result)
290
304
} else {
291
- Err ( errors)
305
+ Err ( Errors ( errors) )
292
306
}
293
307
}
294
308
295
- /// https://url.spec.whatwg.org/#concept-domain-to-ascii
296
- pub fn domain_to_ascii ( domain : & str ) -> Result < String , Vec < Error > > {
297
- uts46_to_ascii ( domain, Uts46Flags {
298
- use_std3_ascii_rules : false ,
299
- transitional_processing : true , // XXX: switch when Firefox does
300
- verify_dns_length : false ,
301
- } )
302
- }
303
-
304
309
/// http://www.unicode.org/reports/tr46/#ToUnicode
305
310
///
306
311
/// Only `use_std3_ascii_rules` is used in `flags`.
307
- pub fn uts46_to_unicode ( domain : & str , mut flags : Uts46Flags ) -> ( String , Vec < Error > ) {
312
+ pub fn to_unicode ( domain : & str , mut flags : Flags ) -> ( String , Result < ( ) , Errors > ) {
308
313
flags. transitional_processing = false ;
309
314
let mut errors = Vec :: new ( ) ;
310
- let domain = uts46_processing ( domain, flags, & mut errors) ;
315
+ let domain = processing ( domain, flags, & mut errors) ;
316
+ let errors = if errors. is_empty ( ) {
317
+ Ok ( ( ) )
318
+ } else {
319
+ Err ( Errors ( errors) )
320
+ } ;
311
321
( domain, errors)
312
322
}
313
-
314
- /// https://url.spec.whatwg.org/#concept-domain-to-unicode
315
- pub fn domain_to_unicode ( domain : & str ) -> ( String , Vec < Error > ) {
316
- uts46_to_unicode ( domain, Uts46Flags {
317
- use_std3_ascii_rules : false ,
318
-
319
- // Unused:
320
- transitional_processing : true ,
321
- verify_dns_length : false ,
322
- } )
323
- }
0 commit comments