httpgenerator_cli/execution/
orchestrator.rs1use std::path::PathBuf;
2
3use httpgenerator_core::{generate_http_files, openapi::load_and_normalize_document_with_options};
4
5use crate::{
6 CliError,
7 args::CliArgs,
8 auth::try_get_access_token,
9 observer::{ExecutionObserver, ExecutionSummary, NoopExecutionObserver},
10 writer::write_files,
11};
12
13use super::{
14 authorization::resolve_authorization_header, settings::build_generator_settings,
15 validation::validate_openapi_document,
16};
17
18pub fn execute(args: CliArgs) -> Result<ExecutionSummary, CliError> {
19 let mut observer = NoopExecutionObserver;
20 execute_with(args, &mut observer, try_get_access_token)
21}
22
23pub fn execute_with_observer<O>(
24 args: CliArgs,
25 observer: &mut O,
26) -> Result<ExecutionSummary, CliError>
27where
28 O: ExecutionObserver,
29{
30 execute_with(args, observer, try_get_access_token)
31}
32
33pub fn should_attempt_azure_auth(args: &CliArgs) -> bool {
34 if args
35 .authorization_header
36 .as_deref()
37 .map(str::trim)
38 .is_some_and(|header| !header.is_empty())
39 {
40 return false;
41 }
42
43 args.azure_scope
44 .as_deref()
45 .map(str::trim)
46 .is_some_and(|scope| !scope.is_empty())
47 || args
48 .azure_tenant_id
49 .as_deref()
50 .map(str::trim)
51 .is_some_and(|tenant_id| !tenant_id.is_empty())
52}
53
54pub(crate) fn execute_with<F, O>(
55 args: CliArgs,
56 observer: &mut O,
57 acquire_token: F,
58) -> Result<ExecutionSummary, CliError>
59where
60 F: Fn(Option<&str>, &str) -> Result<Option<String>, String>,
61 O: ExecutionObserver,
62{
63 let open_api_path = args.open_api_path.clone().ok_or(CliError::MissingInput)?;
64 if !args.skip_validation {
65 observer.validation_started();
66 }
67
68 let validation = validate_openapi_document(&open_api_path, args.skip_validation)?;
69 if let Some(inspection) = &validation {
70 observer.validation_succeeded(inspection);
71 }
72
73 let should_attempt_azure_auth = should_attempt_azure_auth(&args);
74 if should_attempt_azure_auth {
75 observer.azure_auth_started();
76 }
77
78 let (authorization_header, azure_auth) = resolve_authorization_header(&args, acquire_token);
79 if should_attempt_azure_auth {
80 observer.azure_auth_finished(&azure_auth);
81 }
82
83 let document = load_and_normalize_document_with_options(&open_api_path, args.skip_validation)
84 .map_err(|error| CliError::LoadOpenApi(error.to_string()))?;
85 let settings = build_generator_settings(&args, open_api_path.clone(), authorization_header);
86 let result = generate_http_files(&settings, &document);
87 observer.file_writing_started(result.files.len());
88 let output_folder = PathBuf::from(&args.output_folder);
89 let files = write_files(&output_folder, result.files, args.timeout)?;
90 observer.files_written(&files);
91
92 Ok(ExecutionSummary {
93 output_folder,
94 files,
95 validation,
96 azure_auth,
97 })
98}