use hurl_core::input::Input;
use hurl_core::types::Count;
use crate::runner::{HurlResult, RunnerOptions, VariableSet};
use crate::util::logger::LoggerOptions;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Job {
pub filename: Input,
pub runner_options: RunnerOptions,
pub variables: VariableSet,
pub logger_options: LoggerOptions,
pub seq: usize,
}
impl Job {
pub fn new(
filename: &Input,
seq: usize,
runner_options: &RunnerOptions,
variables: &VariableSet,
logger_options: &LoggerOptions,
) -> Self {
Job {
filename: filename.clone(),
runner_options: runner_options.clone(),
variables: variables.clone(),
logger_options: logger_options.clone(),
seq,
}
}
}
pub struct JobResult {
pub job: Job,
pub content: String,
pub hurl_result: HurlResult,
}
impl JobResult {
pub fn new(job: Job, content: String, hurl_result: HurlResult) -> Self {
JobResult {
job,
content,
hurl_result,
}
}
}
pub struct JobQueue<'job> {
jobs: &'job [Job],
index: usize,
repeat: Count,
repeat_index: usize,
}
impl<'job> JobQueue<'job> {
pub fn new(jobs: &'job [Job], repeat: Count) -> Self {
JobQueue {
jobs,
index: 0,
repeat,
repeat_index: 0,
}
}
pub fn jobs_count(&self) -> Count {
match self.repeat {
Count::Finite(n) => Count::Finite(self.jobs.len() * n),
Count::Infinite => Count::Infinite,
}
}
fn job_at(&self, index: usize) -> Job {
let mut job = self.jobs[index].clone();
job.seq = self.jobs[index].seq + (self.jobs.len() * self.repeat_index);
job
}
}
impl Iterator for JobQueue<'_> {
type Item = Job;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.jobs.len() {
self.repeat_index = self.repeat_index.checked_add(1).unwrap_or(0);
match self.repeat {
Count::Finite(n) => {
if self.repeat_index >= n {
None
} else {
self.index = 1;
Some(self.job_at(0))
}
}
Count::Infinite => {
self.index = 1;
Some(self.job_at(0))
}
}
} else {
self.index += 1;
Some(self.job_at(self.index - 1))
}
}
}
#[cfg(test)]
mod tests {
use hurl_core::input::Input;
use hurl_core::types::Count;
use crate::parallel::job::{Job, JobQueue};
use crate::runner::{RunnerOptionsBuilder, VariableSet};
use crate::util::logger::LoggerOptionsBuilder;
fn new_job(file: &str, index: usize) -> Job {
let variables = VariableSet::new();
let runner_options = RunnerOptionsBuilder::default().build();
let logger_options = LoggerOptionsBuilder::default().build();
Job::new(
&Input::new(file),
index,
&runner_options,
&variables,
&logger_options,
)
}
#[test]
fn job_queue_is_finite() {
let jobs = [
new_job("a.hurl", 0),
new_job("b.hurl", 1),
new_job("c.hurl", 2),
];
let mut queue = JobQueue::new(&jobs, Count::Finite(2));
assert_eq!(queue.next(), Some(new_job("a.hurl", 0)));
assert_eq!(queue.next(), Some(new_job("b.hurl", 1)));
assert_eq!(queue.next(), Some(new_job("c.hurl", 2)));
assert_eq!(queue.next(), Some(new_job("a.hurl", 3)));
assert_eq!(queue.next(), Some(new_job("b.hurl", 4)));
assert_eq!(queue.next(), Some(new_job("c.hurl", 5)));
assert_eq!(queue.next(), None);
assert_eq!(queue.jobs_count(), Count::Finite(6));
}
#[test]
fn input_queue_is_infinite() {
let jobs = [new_job("foo.hurl", 0)];
let mut queue = JobQueue::new(&jobs, Count::Infinite);
assert_eq!(queue.next(), Some(new_job("foo.hurl", 0)));
assert_eq!(queue.next(), Some(new_job("foo.hurl", 1)));
assert_eq!(queue.next(), Some(new_job("foo.hurl", 2)));
assert_eq!(queue.next(), Some(new_job("foo.hurl", 3)));
assert_eq!(queue.next(), Some(new_job("foo.hurl", 4)));
assert_eq!(queue.jobs_count(), Count::Infinite);
}
}