use core::{ffi::c_uchar, slice, str};
use milo_parser::Parser;
use crate::helpers::context;
pub fn extract_payload(parser: &Parser, from: usize, size: usize) -> (*const c_uchar, impl Fn()) {
let context = unsafe { Box::from_raw(parser.context as *mut context::Context) };
let (ptr, len, cap) = Vec::into_raw_parts(context.input.as_bytes().into());
let _ = Box::into_raw(context);
(
if size > 0 {
unsafe { ptr.add(from) }
} else {
std::ptr::null()
},
move || {
unsafe { Vec::from_raw_parts(ptr, len, cap) };
},
)
}
#[allow(unused)]
pub fn format_event(name: &str) -> String { format!("\"{}\"", name).to_string() }
#[allow(unused)]
pub fn append_output(parser: &Parser, message: String, from: usize, size: usize) {
let (data, cleanup) = extract_payload(parser, from, size);
let formatted = format!(
"{{ {}, \"data\": {} }}\n",
message,
if !data.is_null() {
format!("\"{}\"", unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(data, size))
})
} else {
"null".into()
},
);
print!("{}", formatted);
let mut context = unsafe { Box::from_raw(parser.context as *mut context::Context) };
context.output.push_str(formatted.as_str());
let _ = Box::into_raw(context);
cleanup();
}
#[allow(unused)]
pub fn event(parser: &Parser, name: &str, from: usize, size: usize) {
append_output(
parser,
format!("\"pos\": {}, \"event\": \"{}\"", from, name),
from,
size,
);
}
#[allow(unused)]
pub fn show_span(parser: &Parser, name: &str, from: usize, size: usize) {
if name == "method" || name == "url" || name == "protocol" || name == "version" {
let (data, cleanup) = extract_payload(parser, from, size);
let mut context = unsafe { Box::from_raw(parser.context as *mut context::Context) };
let value = unsafe { String::from_utf8_unchecked(slice::from_raw_parts(data, size).into()) };
cleanup();
match name {
"method" => {
context.method = value;
}
"url" => {
context.url = value;
}
"protocol" => {
context.protocol = value;
}
"version" => {
context.version = value;
}
_ => {}
}
let _ = Box::into_raw(context);
}
event(parser, name, from, size);
}