planetr 0.2.0

Planetr Rust Crate
Documentation
use serde::{Deserialize, Serialize};
use std::ffi::{CStr, CString};
use std::mem;
use std::os::raw::{c_char, c_void};
use serde_json::json;
use std::error::Error;
use std::fmt;

#[derive(Deserialize, Serialize)]
pub struct ImportResp {
    data: String,
    err: String,
}

#[derive(Debug)]
pub struct PlanetrError {
    details: String
}
#[allow(dead_code)]
impl PlanetrError {
    pub fn new(msg: &str) -> PlanetrError {PlanetrError{details: msg.to_string()}}
}
impl fmt::Display for PlanetrError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {write!(f,"{}",self.details)}
}
impl Error for PlanetrError {
    fn description(&self) -> &str {&self.details}
}

#[no_mangle]
pub extern fn wasm_allocate(size: usize) -> *mut c_void {
    let mut buffer = Vec::with_capacity(size);
    let pointer = buffer.as_mut_ptr(); 
    mem::forget(buffer); 
    pointer as *mut c_void
}

#[no_mangle]
pub extern fn wasm_deallocate(pointer: *mut c_void, capacity: usize) {
    unsafe {let _ = Vec::from_raw_parts(pointer, 0, capacity);}
}

pub fn wasm_parse_func_args(req_json: *mut c_char) -> Result<String, PlanetrError> {
    let c_str: &CStr = unsafe { CStr::from_ptr(req_json) };
    let str_slice = match c_str.to_str(){
        Ok(str_slice) => str_slice,
        Err(err) => return Err(PlanetrError::new(&err.to_string()))
    };
    Ok(str_slice.to_string())
}

pub fn wasm_error(err: &str) -> *const c_char {
    let resp = json! ({"status_code": 500,"body": err,});
    let c_string = CString::new(resp.to_string()).expect("CString::new failed");
    return c_string.into_raw();
}

extern "C" { fn wasm_host_http_get(a_ptr: *const u8, a_len: usize) -> *mut c_char;}
extern "C" { fn wasm_host_log(a_ptr: *const u8, a_len: usize, dummy: usize);}

pub struct Context {}
#[allow(dead_code)]
impl Context {
    pub fn log(self: &Self, logstr: String) {
        unsafe {
            let a_ptr = logstr.as_ptr();
            let a_len = logstr.len();
            wasm_host_log(a_ptr, a_len, 0);
        }
    }
    pub fn http_get(self: &Self, url: String) -> Result<String, PlanetrError> {
        unsafe {
            let a_ptr = url.as_ptr();
            let a_len = url.len();
            let ret_ptr = wasm_host_http_get(a_ptr, a_len);
            if ret_ptr == std::ptr::null::<c_char>() as *mut c_char {
                return Err(PlanetrError::new("internal server error"));
            }
            let c_str: &CStr = CStr::from_ptr(ret_ptr);
            let resp_json = match c_str.to_str(){
                Ok(resp_json) => resp_json,
                Err(err) => return Err(PlanetrError::new(&err.to_string()))
            };
            let json_obj : ImportResp = match serde_json::from_str(resp_json){
                Ok(json_obj) => json_obj,
                Err(err) => return Err(PlanetrError::new(&err.to_string()))  
            };
            if json_obj.err.len() > 0 {
                return Err(PlanetrError::new(&json_obj.err.to_string()))  
            }
            Ok(json_obj.data.to_string())
        }
    }
}