1use super::*;
2
3#[derive(Debug, Default)]
4pub struct Merge {
5 pub config: MergeConfig,
6 pub merged: OpenAPI,
7 pub merge_time: time::Duration,
8 pub save_time: time::Duration,
9}
10
11impl Merge {
12 pub fn merge(mut self) -> io::Result<Self> {
13 let now = time::Instant::now();
14 let mut inputs = self.config.inputs.drain(..);
15 let base = inputs
17 .next()
18 .ok_or(io::Error::other("At least one input required"))?;
19 let merged = inputs.fold(base, merge_into_base).openapi;
20 let merge_time = now.elapsed();
21
22 Ok(Self {
23 merged,
24 merge_time,
25 ..self
26 })
27 }
28
29 pub fn save(self) -> io::Result<Self> {
30 let now = time::Instant::now();
31 let path = self.config.output();
32 save_json_file(&path, &self.merged)?;
33 let save_time = now.elapsed();
34
35 Ok(Self { save_time, ..self })
36 }
37}
38
39impl From<MergeConfig> for Merge {
40 fn from(config: MergeConfig) -> Self {
41 Self {
42 config,
43 ..default()
44 }
45 }
46}
47
48fn merge_into_base(base: Input, mut other: Input) -> Input {
49 tracing::info!(other = %other.source, "Processing");
50
51 let mut openapi = base.openapi;
52 openapi.merge_components(other.components());
53 openapi.merge_security(other.security());
54 openapi.merge_tags(other.tags());
55 openapi.merge_extensions(other.extensions());
56
57 for (path, method, operation) in other.operations() {
58 openapi.merge_operation(path, method, operation);
59 }
60
61 Input { openapi, ..base }
62}