WIP: sending the Request

This commit is contained in:
Brian Carroll 2022-07-14 09:31:16 +01:00
parent 2791326a94
commit 664ee1f0dc
No known key found for this signature in database
GPG Key ID: 9CF4E3BF9C4722C7
3 changed files with 42 additions and 48 deletions

View File

@ -183,6 +183,7 @@ checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022"
name = "host"
version = "0.1.0"
dependencies = [
"lazy_static",
"libc",
"reqwest",
"roc_std",

View File

@ -20,5 +20,6 @@ path = "src/main.rs"
roc_std = { path = "../../../crates/roc_std" }
libc = "0.2"
reqwest = "0.11.11"
lazy_static = "1.4.0"
[workspace]

View File

@ -1,11 +1,13 @@
#![allow(non_snake_case)]
mod glue;
use core::alloc::Layout;
use core::ffi::c_void;
use core::mem::{ManuallyDrop, MaybeUninit};
use libc;
use reqwest::{Client, ClientBuilder, Request};
use roc_std::{RocResult, RocList, RocStr};
use reqwest::{Client, Method};
use roc_std::{RocList, RocResult, RocStr};
use std::ffi::CStr;
use std::os::raw::c_char;
@ -133,56 +135,46 @@ std::thread_local! {
static HTTP_CLIENT: RefCell<Option<Client>> = RefCell::new(None);
}
struct RocHeader {
name: RocStr,
value: RocStr,
}
// This is not the right Rust translation, it's something more complicated...
enum RocBody {
Body(RocStr, RocList<u8>),
EmptyBody
}
#[repr(C)]
struct RocRequest {
method : RocStr,
headers : RocList<RocHeader>,
url : RocStr,
body : RocBody,
responseHandler : *const u8, // Response (List U8) -> Result a Error
timeout : RocResult<f64, ()>,
tracker : RocResult<RocStr, ()>,
allowCookiesFromOtherDomains : bool,
}
#[repr(C)]
struct RocMetadata {
url : RocStr,
statusCode : u16,
statusText : RocStr,
headers : RocList<RocHeader>,
}
enum RocResponseOfListU8 {
BadUrl(RocStr),
Timeout,
NetworkError,
BadStatus(RocMetadata, RocList<u8>),
GoodStatus(RocMetadata, RocList<u8>),
}
#[no_mangle]
pub extern "C" fn roc_fx_send_request(req: RocRequest) {
pub extern "C" fn roc_fx_send_request(roc_request: &glue::Request, /* should I borrow or not? */) {
HTTP_CLIENT.with(|refcell| {
let client = match refcell.take() {
Some(c) => c,
None => {
// Lazily create the client, the first time the Roc program decides to send a request
let builder = Client::builder();
let c = builder.build().expect("Failed to create HTTP client");
refcell.replace(Some(c.clone())); // cheap to clone, has internal refcount
c
}
};
/*
let (mimetype, body_bytes_slice): (String, Vec<u8>) = match roc_request.body.discriminant() {
glue::discriminant_Body::EmptyBody => ("".into(), vec![]),
glue::discriminant_Body::Body => {
let (mimetype_union, body_roclist) = unsafe { roc_request.body.as_Body() };
let mimetype_string: String = unsafe { mimetype_union.as_MimeType() }.as_str().into();
let body_bytes: &[u8] = body_roclist.as_slice();
(mimetype_string, Vec::from(body_bytes))
}
};
*/
let url = match reqwest::Url::parse(roc_request.url.as_str()) {
Ok(u) => u,
Err(_) => todo!("return a Future that immediately resolves to BadUrl"),
};
let rust_body_bytes: Vec<u8> = vec![];
let roc_body_bytes = RocList::from_slice(&rust_body_bytes);
let request = client
.request(Method::GET /* TODO */, url)
.body(Vec::from(body_bytes_slice))
.build();
let roc_response: RocResponseOfListU8 = todo!();
// call_the_closure
// let rust_body_bytes: Vec<u8> = vec![]; // reqwest something something
// let roc_body_bytes = RocList::from_slice(&rust_body_bytes);
// let roc_response: glue::Response = todo!();
// call_the_closure
});
}