use crate::cookie::Cookie;
use serde::Deserialize;
use std::time::{Duration, SystemTime};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SolutionSource {
Fresh,
Cached { age: Duration },
}
impl SolutionSource {
pub fn is_cached(&self) -> bool {
matches!(self, SolutionSource::Cached { .. })
}
}
#[derive(Debug, Clone)]
pub struct Solution {
pub url: String,
pub status: u16,
pub cookies: Vec<Cookie>,
pub user_agent: String,
pub response: Option<String>,
pub solved_at: SystemTime,
pub source: SolutionSource,
}
impl Solution {
pub fn cookie_header(&self) -> String {
self.cookies
.iter()
.map(|c| format!("{}={}", c.name, c.value))
.collect::<Vec<_>>()
.join("; ")
}
pub fn html(&self) -> &str {
self.response.as_deref().unwrap_or("")
}
pub(crate) fn from_wire(s: WireSolution) -> Self {
Self {
url: s.url,
status: s.status,
cookies: s.cookies,
user_agent: s.user_agent,
response: Some(s.response),
solved_at: SystemTime::now(),
source: SolutionSource::Fresh,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct WireSolution {
pub url: String,
pub status: u16,
pub cookies: Vec<Cookie>,
#[serde(rename = "userAgent")]
pub user_agent: String,
pub response: String,
}
#[derive(Debug, Deserialize)]
pub(crate) struct ApiResponse {
pub status: String,
#[serde(default)]
pub message: String,
pub solution: Option<WireSolution>,
#[serde(default)]
pub session: Option<String>,
}