use crate::Error;
use bytes::Bytes;
use serde::Serialize;
use std::fmt;
use wasm_bindgen::JsValue;
#[derive(Debug)]
pub struct Response {
status: u16,
headers: Option<web_sys::Headers>,
body: Body,
unset: bool,
}
impl Default for Response {
fn default() -> Self {
Self {
status: 200,
headers: None,
body: Body::from(Bytes::new()),
unset: true,
}
}
}
impl Response {
pub fn status(&mut self, status: u16) -> &mut Self {
self.status = status;
self.unset = false;
self
}
pub fn body<T: Into<Body>>(&mut self, body: T) -> &mut Self {
self.body = body.into();
self.unset = false;
self
}
pub fn json<T: Serialize>(&mut self, value: &T) -> Result<&mut Self, Error> {
use mime::APPLICATION_JSON;
self.body = serde_json::to_vec(value)?.into();
self.content_type(APPLICATION_JSON).unwrap();
self.unset = false;
Ok(self)
}
pub fn text<T: Into<String>>(&mut self, text: T) -> &mut Self {
let str_val = text.into();
self.body = str_val.into();
self.unset = false;
self
}
pub fn header<K: AsRef<str>, V: AsRef<str>>(
&mut self,
key: K,
val: V,
) -> Result<&mut Self, Error> {
if self.headers.is_none() {
self.headers = Some(web_sys::Headers::new().unwrap());
}
if let Some(ref mut headers) = self.headers {
headers.set(key.as_ref(), val.as_ref())?;
}
Ok(self)
}
pub fn content_type<T: AsRef<str>>(&mut self, ctype: T) -> Result<&mut Self, Error> {
self.header(reqwest::header::CONTENT_TYPE, ctype)?;
Ok(self)
}
pub fn get_status(&self) -> u16 {
self.status
}
pub fn get_body(&self) -> &[u8] {
&self.body.inner.as_ref()
}
pub fn get_headers(&self) -> Option<&web_sys::Headers> {
self.headers.as_ref()
}
pub fn is_empty(&self) -> bool {
self.body.is_empty()
}
pub(crate) fn into_js(mut self) -> JsValue {
let map = js_sys::Map::new();
map.set(
&JsValue::from_str("status"),
&JsValue::from_f64(self.status as f64),
);
map.set(
&JsValue::from_str("body"),
&js_sys::Uint8Array::from(self.body.inner.as_ref()),
);
if self.headers.is_some() {
let headers = std::mem::take(&mut self.headers).unwrap();
map.set(&JsValue::from_str("headers"), &JsValue::from(headers));
} else {
map.set(
&JsValue::from_str("headers"),
&JsValue::from(web_sys::Headers::new().unwrap()),
);
}
JsValue::from(map)
}
pub fn is_unset(&self) -> bool {
self.unset
}
}
pub struct Body {
inner: Bytes,
}
impl Body {
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
impl From<Bytes> for Body {
#[inline]
fn from(bytes: Bytes) -> Body {
Body { inner: bytes }
}
}
impl From<Vec<u8>> for Body {
#[inline]
fn from(vec: Vec<u8>) -> Body {
Body { inner: vec.into() }
}
}
impl From<&'static [u8]> for Body {
#[inline]
fn from(s: &'static [u8]) -> Body {
Body {
inner: Bytes::from_static(s),
}
}
}
impl From<String> for Body {
#[inline]
fn from(s: String) -> Body {
Body { inner: s.into() }
}
}
impl From<&'static str> for Body {
#[inline]
fn from(s: &'static str) -> Body {
s.as_bytes().into()
}
}
impl fmt::Debug for Body {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Body").finish()
}
}