alex35mil
alex35mil
CDCloudflare Developers
Created by alex35mil on 11/30/2023 in #🦀rust-on-workers
How to send `FormData` via `Fetch`? I
@natsumesou you can call .into() on a string to turn it into JsValue since the latter implements From<String>
6 replies
CDCloudflare Developers
Created by alex35mil on 11/30/2023 in #🦀rust-on-workers
How to send `FormData` via `Fetch`? I
Apparently, there's no way to use exposed FormData for a request body, so I just build a string manually (I don't send any files yet, so it supports only text fields):
pub trait Body: fmt::Debug {
fn content_type(&self) -> String;
fn try_into(&self) -> Result<JsValue, worker::Error>;
}

#[derive(Debug)]
pub struct FormDataBody(HashMap<String, String>);

impl FormDataBody {
const BOUNDARY: &'static str = "X-INSERT-YOUR-BOUNDARY";

pub fn new() -> Self {
Self(HashMap::new())
}

pub fn append(&mut self, key: &str, value: &str) {
self.0.insert(key.to_string(), value.to_string());
}
}

impl Body for FormDataBody {
fn content_type(&self) -> String {
format!("multipart/form-data; boundary={}", Self::BOUNDARY)
}

fn try_into(&self) -> Result<JsValue, worker::Error> {
let mut body = String::new();

for (key, value) in &self.0 {
body.push_str(&format!("--{}\r\n", Self::BOUNDARY));
body.push_str(&format!("Content-Disposition: form-data; name=\"{key}\""));
body.push_str(&format!("\r\n\r\n{value}\r\n"));
}

body.push_str(&format!("--{}--\r\n", Self::BOUNDARY));

Ok(body.into())
}
}
pub trait Body: fmt::Debug {
fn content_type(&self) -> String;
fn try_into(&self) -> Result<JsValue, worker::Error>;
}

#[derive(Debug)]
pub struct FormDataBody(HashMap<String, String>);

impl FormDataBody {
const BOUNDARY: &'static str = "X-INSERT-YOUR-BOUNDARY";

pub fn new() -> Self {
Self(HashMap::new())
}

pub fn append(&mut self, key: &str, value: &str) {
self.0.insert(key.to_string(), value.to_string());
}
}

impl Body for FormDataBody {
fn content_type(&self) -> String {
format!("multipart/form-data; boundary={}", Self::BOUNDARY)
}

fn try_into(&self) -> Result<JsValue, worker::Error> {
let mut body = String::new();

for (key, value) in &self.0 {
body.push_str(&format!("--{}\r\n", Self::BOUNDARY));
body.push_str(&format!("Content-Disposition: form-data; name=\"{key}\""));
body.push_str(&format!("\r\n\r\n{value}\r\n"));
}

body.push_str(&format!("--{}--\r\n", Self::BOUNDARY));

Ok(body.into())
}
}
6 replies