1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use crate::{errors::BufkitDataErr, models::Model, site::Site};
use chrono::{Duration, NaiveDateTime};

/// Inventory lists first & last initialization times of the models in the archive for a site &
/// model. It also contains a list of model initialization times that are missing between the first
/// and last.
#[derive(Debug, PartialEq, Eq)]
pub struct Inventory {
    /// The earliest model run in the archive.
    pub first: NaiveDateTime,
    /// The last model run in the archive.
    pub last: NaiveDateTime,
    /// A list of start and end times for missing model runs.
    pub missing: Vec<(NaiveDateTime, NaiveDateTime)>,
    /// Whether this site is flagged for automatic download.
    pub auto_download: bool,
}

impl Inventory {
    /// Create a new inventory. Assume the provided data is sorted from earliest to latest.
    pub(crate) fn new(
        init_times: impl IntoIterator<Item = NaiveDateTime>,
        model: Model,
        site: &Site,
    ) -> Result<Self, BufkitDataErr> {
        let mut init_times = init_times.into_iter();
        let delta_hours = Duration::hours(model.hours_between_runs());

        let first = init_times
            .by_ref()
            .next()
            .ok_or(BufkitDataErr::NotEnoughData)?;
        let mut missing = vec![];

        let mut next_init_time = first;

        for init_time in init_times {
            next_init_time += delta_hours;

            if next_init_time < init_time {
                let start = next_init_time;
                let last = init_time - delta_hours;
                missing.push((start, last));
            }

            while next_init_time < init_time {
                next_init_time += delta_hours;
            }
        }

        let last = next_init_time;
        let auto_download = site.auto_download;

        Ok(Inventory {
            first,
            last,
            missing,
            auto_download,
        })
    }
}