surrealpatch/lib/src/fnc/script/fetch/classes/response/init.rs
2023-07-17 13:40:58 +00:00

80 lines
2 KiB
Rust

use std::string::String as StdString;
use js::{
class::{Trace, Tracer},
prelude::*,
Class, Ctx, Exception, FromJs, Object, Result, Value,
};
use crate::fnc::script::fetch::{classes::Headers, util};
/// Struct containing data from the init argument from the Response constructor.
#[derive(Clone)]
pub struct ResponseInit<'js> {
// u16 instead of reqwest::StatusCode since javascript allows non valid status codes in some
// circumstances.
pub status: u16,
pub status_text: StdString,
pub headers: Class<'js, Headers>,
}
impl<'js> Trace<'js> for ResponseInit<'js> {
fn trace<'a>(&self, tracer: Tracer<'a, 'js>) {
self.headers.trace(tracer);
}
}
impl<'js> ResponseInit<'js> {
/// Returns a ResponseInit object with all values as the default value.
pub fn default(ctx: Ctx<'js>) -> Result<Self> {
let headers = Class::instance(ctx, Headers::new_empty())?;
Ok(ResponseInit {
status: 200,
status_text: StdString::new(),
headers,
})
}
}
impl<'js> FromJs<'js> for ResponseInit<'js> {
fn from_js(ctx: &Ctx<'js>, value: Value<'js>) -> Result<Self> {
let object = Object::from_js(ctx, value)?;
// Extract status.
let status =
if let Some(Coerced(status)) = object.get::<_, Option<Coerced<i32>>>("status")? {
if !(200..=599).contains(&status) {
return Err(Exception::throw_range(ctx, "response status code outside range"));
}
status as u16
} else {
200u16
};
// Extract status text.
let status_text = if let Some(Coerced(string)) =
object.get::<_, Option<Coerced<StdString>>>("statusText")?
{
if !util::is_reason_phrase(string.as_str()) {
return Err(Exception::throw_type(ctx, "statusText was not a valid reason phrase"));
}
string
} else {
StdString::new()
};
// Extract headers.
let headers = if let Some(headers) = object.get::<_, Option<Value>>("headers")? {
let headers = Headers::new_inner(ctx, headers)?;
Class::instance(ctx.clone(), headers)?
} else {
Class::instance(ctx.clone(), Headers::new_empty())?
};
Ok(ResponseInit {
status,
status_text,
headers,
})
}
}