From 1fa2b2767c53e694c3913deb4493443814b1c500 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 9 May 2023 22:27:04 +0800 Subject: [PATCH] fix: return types in ffi --- build.rs | 2 +- src/lib.rs | 52 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/build.rs b/build.rs index 4d6d395..95f59af 100644 --- a/build.rs +++ b/build.rs @@ -8,7 +8,7 @@ fn main() { let mut build = cc::Build::new(); build .file("./deps/ada.cpp") - .file("./deps/ada.h") + .include("./deps/ada.h") .include("./deps/ada_c.h"); let compile_target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS"); diff --git a/src/lib.rs b/src/lib.rs index 7a8ce46..b1b4500 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ use std::ptr; + use thiserror::Error; pub mod ffi { @@ -16,8 +17,8 @@ pub mod ffi { pub length: usize, } - impl AsRef for ada_string { - fn as_ref(&self) -> &str { + impl ada_string { + pub fn as_str(self) -> &'static str { unsafe { let slice = std::slice::from_raw_parts(self.data.cast(), self.length); std::str::from_utf8_unchecked(slice) @@ -61,7 +62,7 @@ pub mod ffi { pub fn ada_get_url_components(url: *mut ada_url) -> ada_url_components; // Getters - pub fn ada_get_origin(url: *mut ada_url) -> ada_owned_string; + pub fn ada_get_origin(url: *mut ada_url) -> *mut ada_owned_string; pub fn ada_get_href(url: *mut ada_url) -> ada_string; pub fn ada_get_username(url: *mut ada_url) -> ada_string; pub fn ada_get_password(url: *mut ada_url) -> ada_string; @@ -112,10 +113,12 @@ pub struct Url { impl Drop for Url { fn drop(&mut self) { - unsafe { - if let Some(origin) = self.origin { + if let Some(origin) = self.origin { + unsafe { ffi::ada_free_owned_string(origin); } + } + unsafe { ffi::ada_free(self.url); } } @@ -126,62 +129,63 @@ impl Url { unsafe { ffi::ada_can_parse( input.as_ptr().cast(), - base.unwrap_or_else(ptr::null()).as_ptr().cast(), + base.map(|b| b.as_ptr()).unwrap_or(ptr::null_mut()).cast(), ) } } pub fn origin(&mut self) -> &str { unsafe { - self.origin = ffi::ada_get_origin(self.url); - return self.origin.as_ref(); + self.origin = Some(ffi::ada_get_origin(self.url)); + self.origin.map(|o| (*o).as_ref()).unwrap_or("") } } pub fn href(&self) -> &str { - unsafe { ffi::ada_get_href(self.url).as_ref() } + unsafe { ffi::ada_get_href(self.url) }.as_str() } pub fn username(&self) -> &str { - unsafe { ffi::ada_get_username(self.url).as_ref() } + unsafe { ffi::ada_get_username(self.url) }.as_str() } pub fn password(&self) -> &str { - unsafe { ffi::ada_get_password(self.url).as_ref() } + unsafe { ffi::ada_get_password(self.url) }.as_str() } pub fn port(&self) -> &str { - unsafe { ffi::ada_get_port(self.url).as_ref() } + unsafe { ffi::ada_get_port(self.url) }.as_str() } pub fn hash(&self) -> &str { - unsafe { ffi::ada_get_hash(self.url).as_ref() } + unsafe { ffi::ada_get_hash(self.url) }.as_str() } pub fn host(&self) -> &str { - unsafe { ffi::ada_get_host(self.url).as_ref() } + unsafe { ffi::ada_get_host(self.url) }.as_str() } pub fn hostname(&self) -> &str { - unsafe { ffi::ada_get_hostname(self.url).as_ref() } + unsafe { ffi::ada_get_hostname(self.url) }.as_str() } pub fn pathname(&self) -> &str { - unsafe { ffi::ada_get_pathname(self.url).as_ref() } + unsafe { ffi::ada_get_pathname(self.url) }.as_str() } pub fn search(&self) -> &str { - unsafe { ffi::ada_get_search(self.url).as_ref() } + unsafe { ffi::ada_get_search(self.url) }.as_str() } pub fn protocol(&self) -> &str { - unsafe { ffi::ada_get_protocol(self.url).as_ref() } + unsafe { ffi::ada_get_protocol(self.url) }.as_str() } } pub fn parse>(url: U) -> Result { + let url_with_0_terminate = std::ffi::CString::new(url.as_ref()).unwrap(); unsafe { - let mut url_aggregator = ffi::ada_parse(url.as_ref().as_ptr().cast()); + let url_aggregator = ffi::ada_parse(url_with_0_terminate.as_ptr()); if ffi::ada_is_valid(url_aggregator) { Ok(Url { @@ -193,3 +197,13 @@ pub fn parse>(url: U) -> Result { } } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn should_parse_simple_url() { + assert!(parse("https://google.com").is_ok()); + } +}