Skip to content

Commit 52b4a85

Browse files
committed
feat: introduce ada_url::Idna methods
1 parent b418bec commit 52b4a85

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

src/idna.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use crate::ffi;
2+
3+
/// IDNA struct implements the to_ascii and to_unicode functions from the Unicode Technical
4+
/// Standard supporting a wide range of systems. It is suitable for URL parsing.
5+
/// For more information, [read the specification](https://www.unicode.org/reports/tr46/#ToUnicode)
6+
pub struct Idna {}
7+
8+
impl Idna {
9+
/// Process international domains according to the UTS #46 standard.
10+
/// Returns empty string if the input is invalid.
11+
///
12+
/// For more information, [read the specification](https://www.unicode.org/reports/tr46/#ToUnicode)
13+
///
14+
/// ```
15+
/// use ada_url::Idna;
16+
/// assert_eq!(Idna::unicode("xn--meagefactory-m9a.ca"), "meßagefactory.ca");
17+
/// ```
18+
pub fn unicode(input: &str) -> &str {
19+
unsafe {
20+
let out = ffi::ada_idna_to_unicode(input.as_ptr().cast(), input.len());
21+
let slice = std::slice::from_raw_parts(out.data.cast(), out.length);
22+
std::str::from_utf8_unchecked(slice)
23+
}
24+
}
25+
26+
/// Process international domains according to the UTS #46 standard.
27+
/// Returns empty string if the input is invalid.
28+
///
29+
/// For more information, [read the specification](https://www.unicode.org/reports/tr46/#ToASCII)
30+
///
31+
/// ```
32+
/// use ada_url::Idna;
33+
/// assert_eq!(Idna::ascii("meßagefactory.ca"), "xn--meagefactory-m9a.ca");
34+
/// ```
35+
pub fn ascii(input: &str) -> &str {
36+
unsafe {
37+
let out = ffi::ada_idna_to_ascii(input.as_ptr().cast(), input.len());
38+
let slice = std::slice::from_raw_parts(out.data.cast(), out.length);
39+
std::str::from_utf8_unchecked(slice)
40+
}
41+
}
42+
}
43+
44+
#[cfg(test)]
45+
mod tests {
46+
use crate::idna::*;
47+
48+
#[test]
49+
fn unicode_should_work() {
50+
assert_eq!(Idna::unicode("xn--meagefactory-m9a.ca"), "meßagefactory.ca");
51+
}
52+
53+
#[test]
54+
fn ascii_should_work() {
55+
assert_eq!(Idna::ascii("meßagefactory.ca"), "xn--meagefactory-m9a.ca");
56+
}
57+
}

src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@
2020
//! CURL ▏ 1471 ns/URL █████████████████████████
2121
//! ```
2222
23+
mod idna;
24+
2325
use thiserror::Error;
2426

27+
pub use idna::Idna;
28+
2529
pub mod ffi {
2630
use std::ffi::c_char;
2731

@@ -128,6 +132,10 @@ pub mod ffi {
128132
pub fn ada_has_password(url: *mut ada_url) -> bool;
129133
pub fn ada_has_hash(url: *mut ada_url) -> bool;
130134
pub fn ada_has_search(url: *mut ada_url) -> bool;
135+
136+
// IDNA methods
137+
pub fn ada_idna_to_unicode(input: *const c_char, length: usize) -> ada_owned_string;
138+
pub fn ada_idna_to_ascii(input: *const c_char, length: usize) -> ada_owned_string;
131139
}
132140
}
133141

0 commit comments

Comments
 (0)