use crate::parser::Selector;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct Response {
status_code: u16,
content_type: String,
body: String,
url: String,
headers: HashMap<String, String>,
latency: std::time::Duration,
}
impl Response {
pub fn new(
status_code: u16,
content_type: String,
body: String,
url: String,
headers: HashMap<String, String>,
) -> Self {
Self {
status_code,
content_type,
body,
url,
headers,
latency: std::time::Duration::ZERO,
}
}
#[must_use]
pub fn latency(&self) -> std::time::Duration {
self.latency
}
pub(crate) fn set_latency(&mut self, latency: std::time::Duration) {
self.latency = latency;
}
#[must_use]
pub fn status(&self) -> u16 {
self.status_code
}
#[must_use]
pub fn text(&self) -> &str {
&self.body
}
#[must_use]
pub fn url(&self) -> &str {
&self.url
}
#[must_use]
pub fn content_type(&self) -> &str {
&self.content_type
}
#[must_use]
pub fn headers(&self) -> &HashMap<String, String> {
&self.headers
}
#[must_use]
pub fn content_length(&self) -> usize {
self.body.len()
}
#[must_use]
pub fn selector(&self) -> Selector {
Selector::from_html_with_url(&self.body, &self.url)
}
pub fn json(&self) -> Result<serde_json::Value, serde_json::Error> {
serde_json::from_str(&self.body)
}
#[must_use]
pub fn markdown(&self, css_selector: Option<&str>, main_content_only: bool) -> String {
let root = self.selector();
let page = if main_content_only {
root.css("body").into_iter().next().unwrap_or(root)
} else {
root
};
match css_selector {
None => page.markdown().to_string(),
Some(sel) => {
let parts: Vec<String> = page
.css(sel)
.into_iter()
.filter(|el| !crate::parser::markdown::in_hidden_context(el))
.map(|el| el.markdown().to_string())
.collect();
parts.join("\n")
}
}
}
#[must_use]
pub fn is_success(&self) -> bool {
(200..300).contains(&self.status_code)
}
#[must_use]
pub fn is_blocked(&self) -> bool {
crate::fetchers::constants::BLOCKED_STATUS_CODES.contains(&self.status_code)
}
}