@@ -353,6 +353,90 @@ fn processing(domain: &str, flags: Flags, errors: &mut Vec<Error>) -> String {
353
353
validated
354
354
}
355
355
356
+ #[ derive( Clone , Copy ) ]
357
+ pub struct Config {
358
+ flags : Flags ,
359
+ }
360
+
361
+ impl From < Flags > for Config {
362
+ #[ inline]
363
+ fn from ( flags : Flags ) -> Self {
364
+ Self { flags }
365
+ }
366
+ }
367
+
368
+ impl Config {
369
+ #[ inline]
370
+ pub fn use_std3_ascii_rules ( mut self , value : bool ) -> Self {
371
+ self . flags . use_std3_ascii_rules = value;
372
+ self
373
+ }
374
+
375
+ #[ inline]
376
+ pub fn transitional_processing ( mut self , value : bool ) -> Self {
377
+ self . flags . transitional_processing = value;
378
+ self
379
+ }
380
+
381
+ #[ inline]
382
+ pub fn verify_dns_length ( mut self , value : bool ) -> Self {
383
+ self . flags . verify_dns_length = value;
384
+ self
385
+ }
386
+
387
+ /// http://www.unicode.org/reports/tr46/#ToASCII
388
+ pub fn to_ascii ( self , domain : & str ) -> Result < String , Errors > {
389
+ let mut errors = Vec :: new ( ) ;
390
+ let mut result = String :: new ( ) ;
391
+ let mut first = true ;
392
+ for label in processing ( domain, self . flags , & mut errors) . split ( '.' ) {
393
+ if !first {
394
+ result. push ( '.' ) ;
395
+ }
396
+ first = false ;
397
+ if label. is_ascii ( ) {
398
+ result. push_str ( label) ;
399
+ } else {
400
+ match punycode:: encode_str ( label) {
401
+ Some ( x) => {
402
+ result. push_str ( PUNYCODE_PREFIX ) ;
403
+ result. push_str ( & x) ;
404
+ } ,
405
+ None => errors. push ( Error :: PunycodeError )
406
+ }
407
+ }
408
+ }
409
+
410
+ if self . flags . verify_dns_length {
411
+ let domain = if result. ends_with ( "." ) { & result[ ..result. len ( ) -1 ] } else { & * result } ;
412
+ if domain. len ( ) < 1 || domain. split ( '.' ) . any ( |label| label. len ( ) < 1 ) {
413
+ errors. push ( Error :: TooShortForDns )
414
+ }
415
+ if domain. len ( ) > 253 || domain. split ( '.' ) . any ( |label| label. len ( ) > 63 ) {
416
+ errors. push ( Error :: TooLongForDns )
417
+ }
418
+ }
419
+ if errors. is_empty ( ) {
420
+ Ok ( result)
421
+ } else {
422
+ Err ( Errors ( errors) )
423
+ }
424
+ }
425
+
426
+ /// http://www.unicode.org/reports/tr46/#ToUnicode
427
+ pub fn to_unicode ( self , domain : & str ) -> ( String , Result < ( ) , Errors > ) {
428
+ let mut errors = Vec :: new ( ) ;
429
+ let domain = processing ( domain, self . flags , & mut errors) ;
430
+ let errors = if errors. is_empty ( ) {
431
+ Ok ( ( ) )
432
+ } else {
433
+ Err ( Errors ( errors) )
434
+ } ;
435
+ ( domain, errors)
436
+ }
437
+
438
+ }
439
+
356
440
#[ derive( Copy , Clone ) ]
357
441
pub struct Flags {
358
442
pub use_std3_ascii_rules : bool ,
@@ -380,54 +464,13 @@ pub struct Errors(Vec<Error>);
380
464
381
465
/// http://www.unicode.org/reports/tr46/#ToASCII
382
466
pub fn to_ascii ( domain : & str , flags : Flags ) -> Result < String , Errors > {
383
- let mut errors = Vec :: new ( ) ;
384
- let mut result = String :: new ( ) ;
385
- let mut first = true ;
386
- for label in processing ( domain, flags, & mut errors) . split ( '.' ) {
387
- if !first {
388
- result. push ( '.' ) ;
389
- }
390
- first = false ;
391
- if label. is_ascii ( ) {
392
- result. push_str ( label) ;
393
- } else {
394
- match punycode:: encode_str ( label) {
395
- Some ( x) => {
396
- result. push_str ( PUNYCODE_PREFIX ) ;
397
- result. push_str ( & x) ;
398
- } ,
399
- None => errors. push ( Error :: PunycodeError )
400
- }
401
- }
402
- }
403
-
404
- if flags. verify_dns_length {
405
- let domain = if result. ends_with ( "." ) { & result[ ..result. len ( ) -1 ] } else { & * result } ;
406
- if domain. len ( ) < 1 || domain. split ( '.' ) . any ( |label| label. len ( ) < 1 ) {
407
- errors. push ( Error :: TooShortForDns )
408
- }
409
- if domain. len ( ) > 253 || domain. split ( '.' ) . any ( |label| label. len ( ) > 63 ) {
410
- errors. push ( Error :: TooLongForDns )
411
- }
412
- }
413
- if errors. is_empty ( ) {
414
- Ok ( result)
415
- } else {
416
- Err ( Errors ( errors) )
417
- }
467
+ Config :: from ( flags) . to_ascii ( domain)
418
468
}
419
469
420
470
/// http://www.unicode.org/reports/tr46/#ToUnicode
421
471
///
422
472
/// Only `use_std3_ascii_rules` is used in `flags`.
423
473
pub fn to_unicode ( domain : & str , mut flags : Flags ) -> ( String , Result < ( ) , Errors > ) {
424
474
flags. transitional_processing = false ;
425
- let mut errors = Vec :: new ( ) ;
426
- let domain = processing ( domain, flags, & mut errors) ;
427
- let errors = if errors. is_empty ( ) {
428
- Ok ( ( ) )
429
- } else {
430
- Err ( Errors ( errors) )
431
- } ;
432
- ( domain, errors)
475
+ Config :: from ( flags) . to_unicode ( domain)
433
476
}
0 commit comments