use std::{fmt::Display, ops::Deref, string::FromUtf8Error};
mod handler;
pub fn get_config() -> Result<String, FromUtf8Error> {
String::from_utf8(handler::get_config())
}
pub fn enable_feature(feature: crate::Feature) -> i32 {
handler::enable_feature(feature.0)
}
pub mod log {
pub enum Level {
Debug = -1,
Info = 0,
Warn = 1,
Error = 2,
None = 3,
}
use super::handler;
pub fn write(level: Level, message: &str) {
if message.is_empty() {
return;
}
handler::log(level as i32, message.as_bytes());
}
pub fn enabled(level: Level) -> bool {
handler::log_enabled(level as i32)
}
}
static KIND_REQ: i32 = 0;
static KIND_RES: i32 = 1;
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Bytes(Box<[u8]>);
impl Bytes {
pub fn as_str(&self) -> &str {
std::str::from_utf8(&self.0).unwrap_or_default()
}
}
impl Deref for Bytes {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
impl Display for Bytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl From<&str> for Bytes {
fn from(value: &str) -> Self {
Self(value.as_bytes().to_vec().into_boxed_slice())
}
}
pub struct Header {
kind: i32,
}
impl Header {
pub fn names(&self) -> Vec<Bytes> {
handler::header_names(self.kind)
.iter()
.map(|h| Bytes(h.clone()))
.collect()
}
pub fn values(&self, name: &Bytes) -> Vec<Bytes> {
handler::header_values(self.kind, name)
.iter()
.map(|h| Bytes(h.clone()))
.collect()
}
pub fn set(&self, name: &Bytes, value: &Bytes) {
handler::set_header(self.kind, name, value);
}
pub fn add(&self, name: &Bytes, value: &Bytes) {
handler::add_header_value(self.kind, name, value);
}
pub fn remove(&self, name: &Bytes) {
handler::remove_header(self.kind, name);
}
}
pub struct Body {
kind: i32,
}
impl Body {
pub fn read(&self) -> Bytes {
Bytes(handler::body(self.kind).unwrap_or_default())
}
pub fn write(&self, body: &Bytes) {
handler::write_body(self.kind, body);
}
}
pub struct Request {
header: Header,
body: Body,
}
impl Default for Request {
fn default() -> Self {
Self::new()
}
}
impl Request {
pub fn new() -> Self {
Self {
header: Header { kind: KIND_REQ },
body: Body { kind: KIND_REQ },
}
}
pub fn source_addr(&self) -> Bytes {
Bytes(handler::source_addr().unwrap_or_default())
}
pub fn version(&self) -> Bytes {
Bytes(handler::version().unwrap_or_default())
}
pub fn method(&self) -> Bytes {
Bytes(handler::method().unwrap_or_default())
}
pub fn set_method(&self, method: &Bytes) {
handler::set_method(method);
}
pub fn uri(&self) -> Bytes {
Bytes(handler::uri().unwrap_or_default())
}
pub fn set_uri(&self, uri: &Bytes) {
handler::set_uri(uri);
}
pub fn header(&self) -> &Header {
&self.header
}
pub fn body(&self) -> &Body {
&self.body
}
}
pub struct Response {
header: Header,
body: Body,
}
impl Default for Response {
fn default() -> Self {
Self::new()
}
}
impl Response {
pub fn new() -> Self {
Self {
header: Header { kind: KIND_RES },
body: Body { kind: KIND_RES },
}
}
pub fn status(&self) -> i32 {
handler::status_code()
}
pub fn set_status(&self, code: i32) {
handler::set_status_code(code);
}
pub fn header(&self) -> &Header {
&self.header
}
pub fn body(&self) -> &Body {
&self.body
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bytes_empty() {
let b = Bytes(b"".to_vec().into_boxed_slice());
assert_eq!(b.is_empty(), true);
}
#[test]
fn test_bytes_eq() {
let b = Bytes(b"test".to_vec().into_boxed_slice());
assert_eq!(b, Bytes::from("test"));
}
}