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
62
63
64
65
66
67
68
69
use super::*;

pub use description::Description;
pub use dispute::Dispute;
pub use operation::OperationSelection;
pub use path::PathModification;
pub use source::InputSource;

mod description;
mod dispute;
mod operation;
mod path;
mod source;

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Input {
    #[serde(flatten)]
    pub source: InputSource,
    pub operation_selection: Option<OperationSelection>,
    pub description: Option<Description>,
    pub path_modification: Option<PathModification>,
    #[serde(skip)]
    pub openapi: OpenAPI,
    #[serde(skip)]
    pub load_time: time::Duration,
}

impl Input {
    pub fn load(self, base: &Path) -> io::Result<Self> {
        let now = time::Instant::now();
        let openapi = self.source.load(base)?;
        let load_time = now.elapsed();

        Ok(Self {
            openapi,
            load_time,
            ..self
        })
    }

    pub fn operations(&self) -> impl Iterator<Item = (&str, &str, &openapiv3::Operation)> {
        self.openapi
            .operations()
            .filter(|(_path, _method, operation)| self.filter_operation(operation))
    }

    fn filter_operation(&self, operation: &openapiv3::Operation) -> bool {
        self.operation_selection
            .as_ref()
            .map_or(true, |selection| selection.filter_operation(operation))
    }

    pub fn components(&mut self) -> Option<openapiv3::Components> {
        self.openapi.components.take()
    }

    pub fn security(&mut self) -> Option<Vec<openapiv3::SecurityRequirement>> {
        self.openapi.security.take()
    }

    pub fn tags(&self) -> Vec<openapiv3::Tag> {
        self.openapi.tags.clone()
    }

    pub fn extensions(&self) -> indexmap::IndexMap<String, json::Value> {
        self.openapi.extensions.clone()
    }
}