Skip to content

Commit 1191bc6

Browse files
committed
capi: expose mapping rules
1 parent 15fa950 commit 1191bc6

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed

src/capi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ pub use c_slice::{CSlice, CSliceMut};
99

1010
pub mod encoding;
1111
pub mod version;
12+
13+
#[cfg(feature = "rest-mappings")]
14+
pub mod mapping_rule;

src/capi/mapping_rule.rs

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
use std::prelude::v1::*;
2+
3+
use core::mem::ManuallyDrop;
4+
use std::os::raw::{c_char, c_int};
5+
6+
use super::c_slice::CSlice;
7+
use super::ffi_cow::FFICow;
8+
9+
use crate::http::mapping_rule::{Method, RestRule};
10+
11+
#[no_mangle]
12+
pub unsafe extern "C" fn rest_rule_new(
13+
method: *const c_char,
14+
path_n_qs: *const c_char,
15+
) -> *const RestRule {
16+
let method_s = if let Some(c_slice) = CSlice::new(method, 0) {
17+
c_slice.as_cow()
18+
} else {
19+
return core::ptr::null();
20+
};
21+
let path_n_qs = if let Some(c_slice) = CSlice::new(path_n_qs, 0) {
22+
c_slice.as_cow()
23+
} else {
24+
return core::ptr::null();
25+
};
26+
27+
let method = Method::from(method_s.as_ref());
28+
29+
let rule = match RestRule::new(method, path_n_qs) {
30+
Ok(rr) => rr,
31+
Err(_) => return core::ptr::null(),
32+
};
33+
34+
Box::into_raw(Box::new(rule)) as *const _
35+
}
36+
37+
#[no_mangle]
38+
pub unsafe extern "C" fn rest_rule_with_path_n_qs(
39+
method: *const c_char,
40+
path: *const c_char,
41+
qs: *const c_char,
42+
) -> *const RestRule {
43+
let method_s = if let Some(c_slice) = CSlice::new(method, 0) {
44+
c_slice.as_cow()
45+
} else {
46+
return core::ptr::null();
47+
};
48+
let path = if let Some(c_slice) = CSlice::new(path, 0) {
49+
c_slice.as_cow()
50+
} else {
51+
return core::ptr::null();
52+
};
53+
54+
let qs = if let Some(c_slice) = CSlice::new(qs, 0) {
55+
c_slice.as_cow().into()
56+
} else {
57+
None
58+
};
59+
60+
let method = Method::from(method_s.as_ref());
61+
62+
let rule = match RestRule::with_path_n_qs(method, path, qs) {
63+
Ok(rr) => rr,
64+
Err(_) => return core::ptr::null(),
65+
};
66+
67+
Box::into_raw(Box::new(rule)) as *const _
68+
}
69+
70+
#[no_mangle]
71+
pub unsafe extern "C" fn rest_rule_free(rule: *const RestRule) {
72+
if rule.is_null() {
73+
return;
74+
}
75+
76+
let _ = unsafe { Box::<RestRule>::from_raw(rule as *mut _) };
77+
}
78+
79+
#[no_mangle]
80+
pub unsafe extern "C" fn rest_rule_matches(
81+
rule: *const RestRule,
82+
method: *const c_char,
83+
path_qs: *const c_char,
84+
) -> c_int {
85+
if rule.is_null() {
86+
return c_int::from(-1);
87+
}
88+
89+
let method_s = if let Some(c_slice) = CSlice::new(method, 0) {
90+
c_slice.as_cow()
91+
} else {
92+
return c_int::from(-1);
93+
};
94+
let path_qs = if let Some(c_slice) = CSlice::new(path_qs, 0) {
95+
c_slice.as_cow()
96+
} else {
97+
return c_int::from(-1);
98+
};
99+
100+
let rule = unsafe { std::ptr::read::<RestRule>(rule) };
101+
let rule = ManuallyDrop::new(rule);
102+
103+
let method = Method::from(method_s.as_ref());
104+
105+
if rule.matches(&method, path_qs) {
106+
c_int::from(1)
107+
} else {
108+
c_int::from(0)
109+
}
110+
}
111+
112+
#[no_mangle]
113+
pub unsafe extern "C" fn rest_rule_matches_path_n_qs(
114+
rule: *const RestRule,
115+
method: *const c_char,
116+
path: *const c_char,
117+
qs: *const c_char,
118+
) -> c_int {
119+
if rule.is_null() {
120+
return c_int::from(-1);
121+
}
122+
123+
let method_s = if let Some(c_slice) = CSlice::new(method, 0) {
124+
c_slice.as_cow()
125+
} else {
126+
return c_int::from(-1);
127+
};
128+
let path = if let Some(c_slice) = CSlice::new(path, 0) {
129+
c_slice.as_cow()
130+
} else {
131+
return c_int::from(-1);
132+
};
133+
let qs = if let Some(c_slice) = CSlice::new(qs, 0) {
134+
c_slice.as_cow().into()
135+
} else {
136+
None
137+
};
138+
139+
let rule = unsafe { std::ptr::read::<RestRule>(rule) };
140+
let rule = ManuallyDrop::new(rule);
141+
142+
let method = Method::from(method_s.as_ref());
143+
144+
if &method == rule.method() && rule.matches_path_n_qs(path, qs) {
145+
c_int::from(1)
146+
} else {
147+
c_int::from(0)
148+
}
149+
}
150+
151+
#[no_mangle]
152+
pub unsafe extern "C" fn rest_rule_matches_request_line(
153+
rule: *const RestRule,
154+
http_request_line: *const c_char,
155+
) -> c_int {
156+
if rule.is_null() {
157+
return c_int::from(-1);
158+
}
159+
160+
let http_request_line = if let Some(c_slice) = CSlice::new(http_request_line, 0) {
161+
c_slice.as_cow()
162+
} else {
163+
return c_int::from(-1);
164+
};
165+
166+
let rule = unsafe { std::ptr::read::<RestRule>(rule) };
167+
let rule = ManuallyDrop::new(rule);
168+
169+
match rule.matches_request_line(http_request_line) {
170+
Ok(b) => {
171+
if b {
172+
c_int::from(1)
173+
} else {
174+
c_int::from(0)
175+
}
176+
}
177+
Err(_) => c_int::from(-1),
178+
}
179+
}
180+
181+
#[no_mangle]
182+
pub unsafe extern "C" fn rest_rule_method(rule: *const RestRule) -> *const FFICow {
183+
if rule.is_null() {
184+
return core::ptr::null();
185+
}
186+
let rule = unsafe { std::ptr::read::<RestRule>(rule) };
187+
let rule = ManuallyDrop::new(rule);
188+
189+
let method = FFICow::from(rule.method().as_str());
190+
191+
Box::into_raw(Box::new(method)) as *const _
192+
}

0 commit comments

Comments
 (0)