use std::io::{Read, Write};
use rmp::decode::{read_u8, read_u16, read_u32, read_u64, read_i8, read_i16, read_i32, read_i64, read_f32, read_f64, read_str, read_array_len, read_bool};
#[macro_export]
macro_rules! fn_main {
($body:expr) => {
fn main() {
let buffer = read_argument_bytes();
let response_bytes: Vec<u8> = $body(buffer);
write_return(response_bytes.to_vec());
}
};
}
#[macro_export]
macro_rules! async_runtime {
($async_block:block) => {
let rt = tokio::runtime::Runtime::new().unwrap();
let mut result = Vec::<u8>::new();
rt.block_on(async {
result = $async_block;
write_return(result.clone());
let _return_value: Result<Vec<u8>, Box<dyn std::error::Error>> = Ok(result.clone());
_return_value
})
}
}
pub fn cprintln(ln: &str){
print!("{ln}\r");
std::io::stdout().flush().unwrap();
}
pub fn tprintln(ln: &str){
let msg = format!("{}\n", ln);
let msg_ptr = msg.as_ptr();
let msg_len = msg.len();
unsafe { wasix::fd_write(wasix::FD_STDOUT, &[wasix::Ciovec{buf: msg_ptr, buf_len: msg_len}]).unwrap() };
}
fn eq<T: PartialEq>(left: &T, right: &T) -> bool {
left == right
}
pub fn assert_eq<T: PartialEq + std::fmt::Debug>(left: T, right: T) -> bool {
if !eq(&left, &right){
tprintln(&format!("{:?} did not equal {:?}", left, right));
unsafe { wasix::thread_exit(1) };
return false
}
tprintln(&format!("passed - {:?} equals {:?}", left, right));
true
}
pub struct Argument<T>{
value: T,
remaining: Vec<u8>
}
impl<T: Clone> Argument<T> {
pub fn get(self: &Self) -> T {
self.value.to_owned()
}
pub fn remaining_buffer(self: &Self) -> Vec<u8> {
self.remaining.to_owned()
}
}
fn read_argument_bytes() -> Vec<u8> {
let arg_len_bytes = std::io::stdin().take(4).bytes();
let mut arg_len_vec = Vec::<u8>::new();
for b in arg_len_bytes {
arg_len_vec.push(b.unwrap());
}
let arg_len_array: [u8; 4] = arg_len_vec.try_into().unwrap();
let arg_len = i32::from_le_bytes(arg_len_array);
let arg_bytes: Vec<u8> = std::io::stdin().take(arg_len as u64).bytes().map(|b| b.unwrap()).collect();
arg_bytes
}
fn write_return(return_bytes: Vec<u8>){
let return_len_bytes = (return_bytes.len() as i32).to_le_bytes();
std::io::stderr().write_all(return_len_bytes.as_slice()).unwrap();
std::io::stderr().write_all(return_bytes.as_slice()).unwrap();
std::io::stdout().flush().unwrap();
}
pub fn read_string_argument(mut buffer_vec: Vec<u8>) -> Argument<String> {
let mut slice = buffer_vec.as_slice();
let mut url_buffer = vec![0u8; buffer_vec.len()];
let try_read_str = read_str(&mut slice, &mut url_buffer);
let string_value: String = std::str::from_utf8(&url_buffer)
.unwrap()
.to_string()
.chars()
.into_iter()
.filter(|c| !c.is_control())
.collect();
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: string_value, remaining: buffer_vec }
}
pub fn read_vec_str_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<String>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
let mut url_buffer = vec![0u8; buffer_vec.len()];
let try_read_str = read_str(&mut slice, &mut url_buffer);
let string_value: String = std::str::from_utf8(&url_buffer)
.unwrap()
.to_string()
.chars()
.into_iter()
.filter(|c| !c.is_control())
.collect();
argument_vec.push(string_value);
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_of_byte_vecs_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<Vec<u8>>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for i in 0 .. try_read_len.unwrap(){
let try_read_len = read_array_len(&mut slice);
let mut sub_vec = vec![];
for _ in 0..try_read_len.unwrap() {
sub_vec.push(read_u8(&mut slice).unwrap());
}
argument_vec.push(sub_vec);
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_of_str_vecs_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<Vec<String>>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
let try_read_len = read_array_len(&mut slice).unwrap();
let mut sub_vec = vec![];
for _ in 0 .. try_read_len {
let mut value_vec = vec![0; buffer_vec.len()];
let mut value_buffer = value_vec.as_mut_slice();
let try_read_str = read_str(&mut slice, value_buffer).unwrap();
let string_value: String = std::str::from_utf8(&value_buffer)
.unwrap()
.to_string()
.chars()
.into_iter()
.filter(|c| !c.is_control())
.collect();
sub_vec.push(string_value);
}
argument_vec.push(sub_vec);
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_bool_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<bool>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_bool(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_u8_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<u8>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_u8(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_u16_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<u16>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_u16(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
println!("[WASM-internal-api] buffer_vec: {:?}", buffer_vec);
buffer_vec.drain(..bytes_read);
println!("[WASM-internal-api] buffer_vec: {:?}", buffer_vec);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_u32_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<u32>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_u32(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_u64_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<u64>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_u64(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_i8_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<i8>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_i8(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_i16_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<i16>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_i16(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
println!("[WASM-internal-api] buffer_vec: {:?}", buffer_vec);
buffer_vec.drain(..bytes_read);
println!("[WASM-internal-api] buffer_vec: {:?}", buffer_vec);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_i32_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<i32>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_i32(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_i64_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<i64>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_i64(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_f32_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<f32>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_f32(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_vec_f64_argument(mut buffer_vec: Vec<u8>) -> Argument<Vec<f64>> {
let mut slice = buffer_vec.as_slice();
let try_read_len = read_array_len(&mut slice);
let mut argument_vec = vec![];
for _ in 0..try_read_len.unwrap() {
argument_vec.push(read_f64(&mut slice).unwrap());
}
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument { value: argument_vec, remaining: buffer_vec }
}
pub fn read_bool_argument(mut buffer_vec: Vec<u8>) -> Argument<bool> {
let mut slice = buffer_vec.as_slice();
let try_read = read_bool(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<bool> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_u8_argument(mut buffer_vec: Vec<u8>) -> Argument<u8> {
let mut slice = buffer_vec.as_slice();
let try_read = read_u8(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<u8> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_u16_argument(mut buffer_vec: Vec<u8>) -> Argument<u16> {
let mut slice = buffer_vec.as_slice();
let try_read = read_u16(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<u16> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_u32_argument(mut buffer_vec: Vec<u8>) -> Argument<u32> {
let mut slice = buffer_vec.as_slice();
let try_read = read_u32(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<u32> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_u64_argument(mut buffer_vec: Vec<u8>) -> Argument<u64> {
let mut slice = buffer_vec.as_slice();
let try_read = read_u64(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<u64> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_i8_argument(mut buffer_vec: Vec<u8>) -> Argument<i8> {
let mut slice = buffer_vec.as_slice();
let try_read = read_i8(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<i8> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_i16_argument(mut buffer_vec: Vec<u8>) -> Argument<i16> {
let mut slice = buffer_vec.as_slice();
let try_read = read_i16(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<i16> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_i32_argument(mut buffer_vec: Vec<u8>) -> Argument<i32> {
let mut slice = buffer_vec.as_slice();
let try_read = read_i32(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<i32> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_i64_argument(mut buffer_vec: Vec<u8>) -> Argument<i64> {
let mut slice = buffer_vec.as_slice();
let try_read = read_i64(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<i64> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_f32_argument(mut buffer_vec: Vec<u8>) -> Argument<f32> {
let mut slice = buffer_vec.as_slice();
let try_read = read_f32(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<f32> { value: try_read.unwrap(), remaining: buffer_vec }
}
pub fn read_f64_argument(mut buffer_vec: Vec<u8>) -> Argument<f64> {
let mut slice = buffer_vec.as_slice();
let try_read = read_f64(&mut slice);
let bytes_read = buffer_vec.len() - slice.len();
buffer_vec.drain(..bytes_read);
Argument::<f64> { value: try_read.unwrap(), remaining: buffer_vec }
}