diff options
Diffstat (limited to 'internals/src/bind/idna.rs')
-rw-r--r-- | internals/src/bind/idna.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/internals/src/bind/idna.rs b/internals/src/bind/idna.rs new file mode 100644 index 0000000..7b82d69 --- /dev/null +++ b/internals/src/bind/idna.rs @@ -0,0 +1,73 @@ +use soft_ascii_string::SoftAsciiString; +use idna; + +use ::error::{EncodingError, EncodingErrorKind}; + + +/// uses puny code on given domain to return a ascii representation +/// +/// # Implementation Detail +/// this function uses `idna::domain_to_ascii`, see the +/// `idna` crates documentation fore more details on how +/// exactly all edgecase are handled +/// +/// # Note +/// that this function does not validate the domain, e.g. +/// if you puny code the domain `"this seems\0so;wrong"` it +/// will return `Ok("this seems\0so;wrong")` +/// +pub fn puny_code_domain<R: AsRef<str>>(domain: R) + -> Result<SoftAsciiString, EncodingError> +{ + _puny_code_domain(domain.as_ref()) +} + +fn _puny_code_domain(domain: &str) + -> Result<SoftAsciiString, EncodingError> +{ + match idna::domain_to_ascii(domain) { + Ok(asciified) => { + //SAFE: well we converted it to ascii, so it's ascii + Ok(SoftAsciiString::from_unchecked(asciified)) + }, + Err(_non_informative_err) => { + Err(EncodingErrorKind::NotEncodable { encoding: "punycode" }.into()) + } + } +} + + +#[cfg(test)] +mod test { + use idna; + use super::puny_code_domain; + + #[test] + fn idna_does_not_validate() { + let domain = "this seems\0so;wrong"; + assert_eq!( + domain.to_owned(), + assert_ok!( idna::domain_to_ascii(domain) ) + ); + } + + #[test] + fn nop_puny_code() { + let domain = "is_ascii.notadomain"; + + let encoded = assert_ok!( puny_code_domain( domain ) ); + assert_eq!( + &*encoded, + "is_ascii.notadomain" + ); + } + #[test] + fn puny_code_ascii_mail() { + let domain = "nöt_ascii.ü"; + let encoded = assert_ok!( puny_code_domain(domain) ); + assert_eq!( + &*encoded, + "xn--nt_ascii-n4a.xn--tda" + ); + } +}
\ No newline at end of file |