use crate::error::{Error, Result};
use crate::network::{NetworkStore, Sizes, Timing};
use crate::response::Response;
use crate::types::Headers;
use serde::de::DeserializeOwned;
use std::sync::{Arc, Weak};
#[derive(Clone)]
pub struct Request {
inner: Arc<RequestInner>,
}
struct RequestInner {
url: String,
method: String,
headers: Headers,
resource_type: String,
request_id: String,
is_navigation: bool,
store: Weak<NetworkStore>,
}
impl Request {
pub(crate) fn new(
url: String,
method: String,
headers: Headers,
resource_type: String,
request_id: String,
is_navigation: bool,
store: Weak<NetworkStore>,
) -> Self {
Self {
inner: Arc::new(RequestInner {
url,
method,
headers,
resource_type,
request_id,
is_navigation,
store,
}),
}
}
pub fn url(&self) -> &str {
&self.inner.url
}
pub fn method(&self) -> &str {
&self.inner.method
}
pub fn headers(&self) -> &Headers {
&self.inner.headers
}
pub fn resource_type(&self) -> &str {
&self.inner.resource_type
}
pub fn is_navigation_request(&self) -> bool {
self.inner.is_navigation
}
pub fn request_id(&self) -> &str {
&self.inner.request_id
}
fn store(&self) -> Option<Arc<NetworkStore>> {
self.inner.store.upgrade()
}
pub(crate) fn store_weak(&self) -> Option<Arc<NetworkStore>> {
self.inner.store.upgrade()
}
pub async fn response(&self) -> Result<Option<Response>> {
Ok(self
.store()
.and_then(|s| s.get_response(&self.inner.request_id)))
}
pub fn post_data(&self) -> Option<String> {
self.store()
.and_then(|s| s.post_data(&self.inner.request_id))
}
pub fn post_data_buffer(&self) -> Option<Vec<u8>> {
self.post_data().map(|s| s.into_bytes())
}
pub fn post_data_json<T: DeserializeOwned>(&self) -> Option<Result<T>> {
let data = self.post_data()?;
Some(serde_json::from_str(&data).map_err(Error::from))
}
pub fn redirected_from(&self) -> Option<Request> {
let store = self.store()?;
let prev_id = store.redirect_source(&self.inner.request_id)?;
store.get_request(&prev_id)
}
pub fn redirected_to(&self) -> Option<Request> {
let store = self.store()?;
let next_id = store.redirect_target(&self.inner.request_id)?;
store.get_request(&next_id)
}
pub fn failure(&self) -> Option<String> {
self.store()
.and_then(|s| s.failure(&self.inner.request_id))
}
pub fn timing(&self) -> Option<Timing> {
self.store()
.and_then(|s| s.timing(&self.inner.request_id))
}
pub fn sizes(&self) -> Option<Sizes> {
self.store()
.and_then(|s| s.sizes(&self.inner.request_id))
}
pub fn all_headers(&self) -> Headers {
self.store()
.and_then(|s| s.raw_request_headers(&self.inner.request_id))
.unwrap_or_else(|| self.inner.headers.clone())
}
pub fn frame(&self) -> Option<crate::frame::Frame> {
None
}
}