Skip to content

Commit a6c4650

Browse files
authored
fix: return types in ffi (#1)
1 parent ca49128 commit a6c4650

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn main() {
88
let mut build = cc::Build::new();
99
build
1010
.file("./deps/ada.cpp")
11-
.file("./deps/ada.h")
11+
.include("./deps/ada.h")
1212
.include("./deps/ada_c.h");
1313

1414
let compile_target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS");

src/lib.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::ptr;
2+
23
use thiserror::Error;
34

45
pub mod ffi {
@@ -16,8 +17,8 @@ pub mod ffi {
1617
pub length: usize,
1718
}
1819

19-
impl AsRef<str> for ada_string {
20-
fn as_ref(&self) -> &str {
20+
impl ada_string {
21+
pub fn as_str(self) -> &'static str {
2122
unsafe {
2223
let slice = std::slice::from_raw_parts(self.data.cast(), self.length);
2324
std::str::from_utf8_unchecked(slice)
@@ -61,7 +62,7 @@ pub mod ffi {
6162
pub fn ada_get_url_components(url: *mut ada_url) -> ada_url_components;
6263

6364
// Getters
64-
pub fn ada_get_origin(url: *mut ada_url) -> ada_owned_string;
65+
pub fn ada_get_origin(url: *mut ada_url) -> *mut ada_owned_string;
6566
pub fn ada_get_href(url: *mut ada_url) -> ada_string;
6667
pub fn ada_get_username(url: *mut ada_url) -> ada_string;
6768
pub fn ada_get_password(url: *mut ada_url) -> ada_string;
@@ -112,10 +113,12 @@ pub struct Url {
112113

113114
impl Drop for Url {
114115
fn drop(&mut self) {
115-
unsafe {
116-
if let Some(origin) = self.origin {
116+
if let Some(origin) = self.origin {
117+
unsafe {
117118
ffi::ada_free_owned_string(origin);
118119
}
120+
}
121+
unsafe {
119122
ffi::ada_free(self.url);
120123
}
121124
}
@@ -126,62 +129,63 @@ impl Url {
126129
unsafe {
127130
ffi::ada_can_parse(
128131
input.as_ptr().cast(),
129-
base.unwrap_or_else(ptr::null()).as_ptr().cast(),
132+
base.map(|b| b.as_ptr()).unwrap_or(ptr::null_mut()).cast(),
130133
)
131134
}
132135
}
133136

134137
pub fn origin(&mut self) -> &str {
135138
unsafe {
136-
self.origin = ffi::ada_get_origin(self.url);
137-
return self.origin.as_ref();
139+
self.origin = Some(ffi::ada_get_origin(self.url));
140+
self.origin.map(|o| (*o).as_ref()).unwrap_or("")
138141
}
139142
}
140143

141144
pub fn href(&self) -> &str {
142-
unsafe { ffi::ada_get_href(self.url).as_ref() }
145+
unsafe { ffi::ada_get_href(self.url) }.as_str()
143146
}
144147

145148
pub fn username(&self) -> &str {
146-
unsafe { ffi::ada_get_username(self.url).as_ref() }
149+
unsafe { ffi::ada_get_username(self.url) }.as_str()
147150
}
148151

149152
pub fn password(&self) -> &str {
150-
unsafe { ffi::ada_get_password(self.url).as_ref() }
153+
unsafe { ffi::ada_get_password(self.url) }.as_str()
151154
}
152155

153156
pub fn port(&self) -> &str {
154-
unsafe { ffi::ada_get_port(self.url).as_ref() }
157+
unsafe { ffi::ada_get_port(self.url) }.as_str()
155158
}
156159

157160
pub fn hash(&self) -> &str {
158-
unsafe { ffi::ada_get_hash(self.url).as_ref() }
161+
unsafe { ffi::ada_get_hash(self.url) }.as_str()
159162
}
160163

161164
pub fn host(&self) -> &str {
162-
unsafe { ffi::ada_get_host(self.url).as_ref() }
165+
unsafe { ffi::ada_get_host(self.url) }.as_str()
163166
}
164167

165168
pub fn hostname(&self) -> &str {
166-
unsafe { ffi::ada_get_hostname(self.url).as_ref() }
169+
unsafe { ffi::ada_get_hostname(self.url) }.as_str()
167170
}
168171

169172
pub fn pathname(&self) -> &str {
170-
unsafe { ffi::ada_get_pathname(self.url).as_ref() }
173+
unsafe { ffi::ada_get_pathname(self.url) }.as_str()
171174
}
172175

173176
pub fn search(&self) -> &str {
174-
unsafe { ffi::ada_get_search(self.url).as_ref() }
177+
unsafe { ffi::ada_get_search(self.url) }.as_str()
175178
}
176179

177180
pub fn protocol(&self) -> &str {
178-
unsafe { ffi::ada_get_protocol(self.url).as_ref() }
181+
unsafe { ffi::ada_get_protocol(self.url) }.as_str()
179182
}
180183
}
181184

182185
pub fn parse<U: AsRef<str>>(url: U) -> Result<Url, Error> {
186+
let url_with_0_terminate = std::ffi::CString::new(url.as_ref()).unwrap();
183187
unsafe {
184-
let mut url_aggregator = ffi::ada_parse(url.as_ref().as_ptr().cast());
188+
let url_aggregator = ffi::ada_parse(url_with_0_terminate.as_ptr());
185189

186190
if ffi::ada_is_valid(url_aggregator) {
187191
Ok(Url {
@@ -193,3 +197,13 @@ pub fn parse<U: AsRef<str>>(url: U) -> Result<Url, Error> {
193197
}
194198
}
195199
}
200+
201+
#[cfg(test)]
202+
mod test {
203+
use super::*;
204+
205+
#[test]
206+
fn should_parse_simple_url() {
207+
assert!(parse("https://google.com").is_ok());
208+
}
209+
}

0 commit comments

Comments
 (0)