#[cfg(not(test))]
use crate::event_handlers::TermInputHandler;
use crate::{
config::{Configuration, OutputLevel},
event_handlers::Handles,
parser::TIMESPEC_REGEX,
progress::BarType,
scan_manager::scan::Visibility,
scanner::RESPONSES,
};
use std::{fs::File, io::BufReader, sync::Arc};
use tokio::time;
pub async fn start_max_time_thread(handles: Arc<Handles>) {
log::trace!("enter: start_max_time_thread({handles:?})");
let captures = TIMESPEC_REGEX.captures(&handles.config.time_limit).unwrap();
let length_match = captures.get(1).unwrap();
let measurement_match = captures.get(2).unwrap();
if let Ok(length) = length_match.as_str().parse::<u64>() {
let length_in_secs = match measurement_match.as_str().to_ascii_lowercase().as_str() {
"s" => length,
"m" => length * 60, "h" => length * 60 * 60, "d" => length * 60 * 60 * 24, _ => length,
};
log::debug!(
"max time limit as string: {} and as seconds: {}",
handles.config.time_limit,
length_in_secs
);
time::sleep(time::Duration::new(length_in_secs, 0)).await;
log::trace!("exit: start_max_time_thread");
#[cfg(test)]
panic!("{handles:?}");
#[cfg(not(test))]
let _ = TermInputHandler::sigint_handler(handles.clone());
}
log::warn!(
"Could not parse the value provided ({}), can't enforce time limit",
handles.config.time_limit
);
}
pub fn resume_scan(filename: &str) -> Configuration {
log::trace!("enter: resume_scan({filename})");
let file = File::open(filename).unwrap_or_else(|e| {
log::error!("{e}");
log::error!("Could not open state file, exiting");
std::process::exit(1);
});
let reader = BufReader::new(file);
let state: serde_json::Value = serde_json::from_reader(reader).unwrap();
let conf = state.get("config").unwrap_or_else(|| {
log::error!("Could not load configuration from state file, exiting");
std::process::exit(1);
});
let config = serde_json::from_value(conf.clone()).unwrap_or_else(|e| {
log::error!("{e}");
log::error!("Could not deserialize configuration found in state file, exiting");
std::process::exit(1);
});
if let Some(responses) = state.get("responses") {
if let Some(arr_responses) = responses.as_array() {
for response in arr_responses {
if let Ok(deser_resp) = serde_json::from_value(response.clone()) {
RESPONSES.insert(deser_resp);
}
}
}
}
log::trace!("exit: resume_scan -> {config:?}");
config
}
pub fn determine_bar_type(
bar_limit: usize,
number_of_bars: usize,
output_level: OutputLevel,
) -> BarType {
let visibility = if bar_limit == 0 {
Visibility::Visible
} else if bar_limit < number_of_bars {
Visibility::Hidden
} else {
Visibility::Visible
};
match (output_level, visibility) {
(OutputLevel::Default, Visibility::Visible) => BarType::Default,
(OutputLevel::Quiet, Visibility::Visible) => BarType::Quiet,
(OutputLevel::Default, Visibility::Hidden) => BarType::Hidden,
(OutputLevel::Quiet, Visibility::Hidden) => BarType::Hidden,
(OutputLevel::Silent | OutputLevel::SilentJSON, _) => BarType::Hidden,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_no_limit_visible() {
let bar_type = determine_bar_type(0, 1, OutputLevel::Default);
assert!(matches!(bar_type, BarType::Default));
}
#[test]
fn test_limit_exceeded_hidden() {
let bar_type = determine_bar_type(1, 2, OutputLevel::Default);
assert!(matches!(bar_type, BarType::Hidden));
}
#[test]
fn test_limit_not_exceeded_visible() {
let bar_type = determine_bar_type(2, 1, OutputLevel::Default);
assert!(matches!(bar_type, BarType::Default));
}
#[test]
fn test_quiet_visible() {
let bar_type = determine_bar_type(0, 1, OutputLevel::Quiet);
assert!(matches!(bar_type, BarType::Quiet));
}
#[test]
fn test_quiet_hidden() {
let bar_type = determine_bar_type(1, 2, OutputLevel::Quiet);
assert!(matches!(bar_type, BarType::Hidden));
}
#[test]
fn test_silent_hidden() {
let bar_type = determine_bar_type(0, 1, OutputLevel::Silent);
assert!(matches!(bar_type, BarType::Hidden));
}
#[test]
fn test_silent_json_hidden() {
let bar_type = determine_bar_type(0, 1, OutputLevel::SilentJSON);
assert!(matches!(bar_type, BarType::Hidden));
}
}