use crate::cf_ips::CFIPs;
use crate::domain::Domain;
use std::{error::Error, sync::Arc};
use tokio::sync::Mutex;
#[derive(Debug)]
pub struct Checker {
pub domains: Vec<Arc<Mutex<Domain>>>,
pub cf_ips: Arc<CFIPs>,
}
impl Checker {
pub async fn build(target: String) -> Result<Self, Box<dyn Error>> {
let target = target.split("\n").collect::<Vec<&str>>();
let mut domains = vec![];
target.iter().for_each(|domain| {
if let Ok(domain) = Domain::build(domain.to_string()) {
domains.push(Arc::new(Mutex::new(domain)));
}
});
let cf_ips = CFIPs::load().await?;
Ok(Self {
domains,
cf_ips: Arc::new(cf_ips),
})
}
}
impl Checker {
pub async fn check(&mut self) -> Result<(), Box<dyn Error>> {
let mut handles = vec![];
for domain in self.domains.iter_mut() {
let cf_ips = self.cf_ips.clone();
let domain = domain.clone();
let handle = tokio::spawn(async move {
domain.lock().await.verify_domain(cf_ips).await.unwrap();
});
handles.push(handle);
}
for handle in handles {
handle.await?;
}
Ok(())
}
}
impl Checker {
pub async fn cf_detected_domains(&self) -> Vec<Arc<Mutex<Domain>>> {
let mut v = vec![];
let iter = self.domains.iter();
for domain in iter {
let domain = domain.clone();
if domain.lock().await.check_result != 0 {
v.push(domain.clone());
}
}
v
}
}