use crate::ffi;
use crate::types::Header;
#[derive(Clone, Debug)]
pub struct CRequest {
pub method: String,
pub path: String,
pub headers: Vec<Header>,
pub body: Vec<u8>,
pub request_id: [u8; 16],
pub trace_id: [u8; 16],
}
impl CRequest {
pub fn from_ffi(req: &ffi::nwep_request) -> Self {
let method = unsafe { std::slice::from_raw_parts(req.method as *const u8, req.method_len) };
let path = unsafe { std::slice::from_raw_parts(req.path as *const u8, req.path_len) };
let headers: Vec<Header> = (0..req.header_count).map(|i| {
let h = unsafe { &*req.headers.add(i) };
let name = unsafe { std::slice::from_raw_parts(h.name, h.name_len) };
let value = unsafe { std::slice::from_raw_parts(h.value, h.value_len) };
Header {
name: String::from_utf8_lossy(name).into_owned(),
value: String::from_utf8_lossy(value).into_owned(),
}
}).collect();
let body = if req.body.is_null() || req.body_len == 0 {
Vec::new()
} else {
unsafe { std::slice::from_raw_parts(req.body, req.body_len).to_vec() }
};
CRequest {
method: String::from_utf8_lossy(method).into_owned(),
path: String::from_utf8_lossy(path).into_owned(),
headers,
body,
request_id: req.request_id,
trace_id: req.trace_id,
}
}
}
#[derive(Clone, Debug)]
pub struct CResponse {
pub status: String,
pub status_details: String,
pub headers: Vec<Header>,
pub body: Vec<u8>,
}
impl CResponse {
pub fn from_ffi(resp: &ffi::nwep_response) -> Self {
let status = unsafe { std::slice::from_raw_parts(resp.status as *const u8, resp.status_len) };
let details = if resp.status_details.is_null() || resp.status_details_len == 0 {
&[] as &[u8]
} else {
unsafe { std::slice::from_raw_parts(resp.status_details as *const u8, resp.status_details_len) }
};
let headers: Vec<Header> = (0..resp.header_count).map(|i| {
let h = unsafe { &*resp.headers.add(i) };
let name = unsafe { std::slice::from_raw_parts(h.name, h.name_len) };
let value = unsafe { std::slice::from_raw_parts(h.value, h.value_len) };
Header {
name: String::from_utf8_lossy(name).into_owned(),
value: String::from_utf8_lossy(value).into_owned(),
}
}).collect();
let body = if resp.body.is_null() || resp.body_len == 0 {
Vec::new()
} else {
unsafe { std::slice::from_raw_parts(resp.body, resp.body_len).to_vec() }
};
CResponse {
status: String::from_utf8_lossy(status).into_owned(),
status_details: String::from_utf8_lossy(details).into_owned(),
headers,
body,
}
}
pub fn is_ok(&self) -> bool {
crate::protocol::status_is_success(&self.status)
}
pub fn header(&self, name: &str) -> Option<&str> {
self.headers.iter().find(|h| h.name == name).map(|h| h.value.as_str())
}
}
#[derive(Clone, Debug)]
pub struct CNotify {
pub event: String,
pub path: String,
pub notify_id: [u8; 16],
pub has_notify_id: bool,
pub headers: Vec<Header>,
pub body: Vec<u8>,
}
impl CNotify {
pub fn from_ffi(n: &ffi::nwep_notify) -> Self {
let event = unsafe { std::slice::from_raw_parts(n.event as *const u8, n.event_len) };
let path = unsafe { std::slice::from_raw_parts(n.path as *const u8, n.path_len) };
let headers: Vec<Header> = (0..n.header_count).map(|i| {
let h = unsafe { &*n.headers.add(i) };
let name = unsafe { std::slice::from_raw_parts(h.name, h.name_len) };
let value = unsafe { std::slice::from_raw_parts(h.value, h.value_len) };
Header {
name: String::from_utf8_lossy(name).into_owned(),
value: String::from_utf8_lossy(value).into_owned(),
}
}).collect();
let body = if n.body.is_null() || n.body_len == 0 {
Vec::new()
} else {
unsafe { std::slice::from_raw_parts(n.body, n.body_len).to_vec() }
};
CNotify {
event: String::from_utf8_lossy(event).into_owned(),
path: String::from_utf8_lossy(path).into_owned(),
notify_id: n.notify_id,
has_notify_id: n.has_notify_id != 0,
headers,
body,
}
}
}