Skip to main content

aperture_cli/
invocation.rs

1//! CLI-agnostic invocation model for the execution engine.
2//!
3//! These types decouple the execution core from any specific CLI framework
4//! (e.g., clap). The executor accepts [`OperationCall`] and [`ExecutionContext`]
5//! and returns [`ExecutionResult`], enabling library/SDK usage, alternative
6//! frontends, and unit testing without CLI parsing dependencies.
7
8use crate::config::models::GlobalConfig;
9use crate::engine::executor::RetryContext;
10use crate::response_cache::CacheConfig;
11use serde_json::Value;
12use std::collections::HashMap;
13
14/// Describes a single API operation to invoke, fully resolved from user input.
15///
16/// All parameter values are pre-extracted and categorized by their `OpenAPI`
17/// location (path, query, header). This struct is framework-agnostic — it
18/// can be constructed from clap `ArgMatches`, a GUI form, or programmatically.
19#[derive(Debug, Clone)]
20pub struct OperationCall {
21    /// The `operationId` from the `OpenAPI` spec (e.g., `"getUserById"`).
22    pub operation_id: String,
23
24    /// Path parameters keyed by name (e.g., `{"id": "123"}`).
25    pub path_params: HashMap<String, String>,
26
27    /// Query parameters keyed by name (e.g., `{"page": "1"}`).
28    pub query_params: HashMap<String, String>,
29
30    /// Header parameters keyed by name (e.g., `{"X-Request-Id": "abc"}`).
31    pub header_params: HashMap<String, String>,
32
33    /// Optional JSON request body.
34    pub body: Option<String>,
35
36    /// Custom headers in raw `"Name: Value"` format, as provided by the user.
37    pub custom_headers: Vec<String>,
38}
39
40/// Execution-time configuration that is orthogonal to the operation itself.
41///
42/// Controls retry behavior, caching, dry-run mode, and authentication
43/// context. Does **not** include rendering concerns (output format, JQ
44/// filters) — those belong in the CLI rendering layer.
45#[derive(Debug, Clone, Default)]
46pub struct ExecutionContext {
47    /// If true, show the request that would be made without executing it.
48    pub dry_run: bool,
49
50    /// Optional idempotency key for safe retries.
51    pub idempotency_key: Option<String>,
52
53    /// Response cache configuration. `None` disables caching.
54    pub cache_config: Option<CacheConfig>,
55
56    /// Retry configuration. `None` disables retries.
57    pub retry_context: Option<RetryContext>,
58
59    /// Base URL override. `None` uses `BaseUrlResolver` priority chain.
60    pub base_url: Option<String>,
61
62    /// Global configuration for URL resolution and secret lookup.
63    pub global_config: Option<GlobalConfig>,
64
65    /// Server template variable overrides (e.g., `["region=us", "env=prod"]`).
66    pub server_var_args: Vec<String>,
67
68    /// If true, loop through all pages and stream results as NDJSON.
69    pub auto_paginate: bool,
70}
71
72/// Structured result returned by the executor. The CLI layer decides how
73/// to render this (JSON, YAML, table, etc.) — the executor never prints.
74#[derive(Debug, Clone)]
75pub enum ExecutionResult {
76    /// Successful HTTP response.
77    Success {
78        /// Response body text.
79        body: String,
80        /// HTTP status code.
81        status: u16,
82        /// Response headers.
83        headers: HashMap<String, String>,
84    },
85
86    /// Dry-run mode: the request that *would* have been sent.
87    DryRun {
88        /// Structured JSON representation of the request.
89        request_info: Value,
90    },
91
92    /// Response served from cache.
93    Cached {
94        /// Cached response body text.
95        body: String,
96    },
97
98    /// The operation completed but produced no response body.
99    Empty,
100}