Skip to main content

openapi_to_rust/
streaming.rs

1use std::collections::BTreeMap;
2
3/// Configuration for SSE streaming client generation
4#[derive(Debug, Clone)]
5pub struct StreamingConfig {
6    /// List of streaming endpoints to generate clients for
7    pub endpoints: Vec<StreamingEndpoint>,
8    /// Whether to generate streaming client implementations
9    pub generate_client: bool,
10    /// Name of the generated streaming client module
11    pub client_module_name: String,
12    /// Whether to generate event parsing helper utilities
13    pub event_parser_helpers: bool,
14    /// Configuration for automatic reconnection logic
15    pub reconnection_config: Option<ReconnectionConfig>,
16}
17
18impl Default for StreamingConfig {
19    fn default() -> Self {
20        Self {
21            endpoints: Vec::new(),
22            generate_client: true,
23            client_module_name: "streaming".to_string(),
24            event_parser_helpers: true,
25            reconnection_config: None,
26        }
27    }
28}
29
30/// HTTP method for streaming endpoint
31#[derive(Debug, Clone, Default, PartialEq, Eq)]
32pub enum HttpMethod {
33    #[default]
34    Post,
35    Get,
36}
37
38/// Configuration for a single streaming endpoint
39#[derive(Debug, Clone)]
40pub struct StreamingEndpoint {
41    /// OpenAPI operation ID that supports streaming
42    pub operation_id: String,
43    /// URL path for the endpoint (e.g., "/global/event")
44    pub path: String,
45    /// HTTP method for the streaming request (default: POST)
46    pub http_method: HttpMethod,
47    /// Parameter name that controls streaming (e.g., "stream"), empty for always-streaming endpoints
48    /// Only used for POST requests
49    pub stream_parameter: String,
50    /// Query parameters for GET requests (e.g., session_id)
51    pub query_parameters: Vec<QueryParameter>,
52    /// Name of the union type that represents streaming events
53    pub event_union_type: String,
54    /// Content type for streaming responses (e.g., "text/event-stream")
55    pub content_type: Option<String>,
56    /// Base URL for the API (optional override)
57    pub base_url: Option<String>,
58    /// Event flow pattern for this endpoint
59    pub event_flow: EventFlow,
60    /// Required headers for streaming requests
61    pub required_headers: Vec<(String, String)>,
62    /// Authentication header configuration
63    pub auth_header: Option<AuthHeader>,
64    /// Optional headers that can be set dynamically (e.g., beta features)
65    pub optional_headers: Vec<OptionalHeader>,
66}
67
68/// Query parameter configuration for GET streaming endpoints
69#[derive(Debug, Clone)]
70pub struct QueryParameter {
71    /// Parameter name
72    pub name: String,
73    /// Whether this parameter is required
74    pub required: bool,
75}
76
77impl Default for StreamingEndpoint {
78    fn default() -> Self {
79        Self {
80            operation_id: String::new(),
81            path: String::new(),
82            http_method: HttpMethod::default(),
83            stream_parameter: String::new(),
84            query_parameters: Vec::new(),
85            event_union_type: String::new(),
86            content_type: Some("text/event-stream".to_string()),
87            base_url: None,
88            event_flow: EventFlow::Simple,
89            required_headers: Vec::new(),
90            auth_header: None,
91            optional_headers: Vec::new(),
92        }
93    }
94}
95
96/// Authentication header configuration
97#[derive(Debug, Clone)]
98pub enum AuthHeader {
99    /// Bearer token format: "Authorization: Bearer {token}"
100    Bearer(String),
101    /// Direct API key format: "{header_name}: {api_key}"
102    ApiKey(String),
103}
104
105/// Defines the event flow pattern for streaming
106#[derive(Debug, Clone, Default)]
107pub enum EventFlow {
108    /// Simple streaming - just emit events as they arrive
109    #[default]
110    Simple,
111    /// Start-Delta-Stop pattern with specific event types
112    StartDeltaStop {
113        /// Events that signal the start of a stream
114        start_events: Vec<String>,
115        /// Events that contain incremental updates
116        delta_events: Vec<String>,
117        /// Events that signal the end of a stream
118        stop_events: Vec<String>,
119    },
120}
121
122/// Configuration for automatic reconnection logic
123#[derive(Debug, Clone)]
124pub struct ReconnectionConfig {
125    /// Maximum number of reconnection attempts
126    pub max_retries: u32,
127    /// Initial delay between reconnection attempts (milliseconds)
128    pub initial_delay_ms: u64,
129    /// Maximum delay between reconnection attempts (milliseconds)
130    pub max_delay_ms: u64,
131    /// Multiplier for exponential backoff
132    pub backoff_multiplier: f64,
133}
134
135impl Default for ReconnectionConfig {
136    fn default() -> Self {
137        Self {
138            max_retries: 3,
139            initial_delay_ms: 1000,
140            max_delay_ms: 30000,
141            backoff_multiplier: 2.0,
142        }
143    }
144}
145
146/// Error types for streaming operations
147#[derive(Debug, Clone)]
148pub enum StreamingError {
149    /// Connection error
150    Connection(String),
151    /// Parsing error for SSE events
152    Parsing(String),
153    /// Authentication error
154    Authentication(String),
155    /// Rate limiting error
156    RateLimit(String),
157    /// Generic API error
158    Api(String),
159}
160
161impl std::fmt::Display for StreamingError {
162    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163        match self {
164            StreamingError::Connection(msg) => write!(f, "Connection error: {msg}"),
165            StreamingError::Parsing(msg) => write!(f, "Parsing error: {msg}"),
166            StreamingError::Authentication(msg) => write!(f, "Authentication error: {msg}"),
167            StreamingError::RateLimit(msg) => write!(f, "Rate limit error: {msg}"),
168            StreamingError::Api(msg) => write!(f, "API error: {msg}"),
169        }
170    }
171}
172
173impl std::error::Error for StreamingError {}
174
175/// Configuration for optional headers that can be set dynamically
176#[derive(Debug, Clone)]
177pub struct OptionalHeader {
178    /// Header name
179    pub name: String,
180    /// Description of what this header does
181    pub description: String,
182    /// Whether this header can accept multiple values (comma-separated)
183    pub multiple_values: bool,
184    /// Default value if any
185    pub default_value: Option<String>,
186    /// Example values for documentation
187    pub examples: Vec<String>,
188}
189
190/// Configuration for detecting streaming endpoints from OpenAPI specs
191#[derive(Debug, Clone)]
192pub struct StreamingDetectionConfig {
193    /// Parameter names that indicate streaming capability
194    pub stream_parameter_names: Vec<String>,
195    /// Content types that indicate SSE responses
196    pub sse_content_types: Vec<String>,
197    /// Schema name patterns for event types
198    pub event_type_patterns: Vec<String>,
199}
200
201impl Default for StreamingDetectionConfig {
202    fn default() -> Self {
203        Self {
204            stream_parameter_names: vec!["stream".to_string()],
205            sse_content_types: vec!["text/event-stream".to_string()],
206            event_type_patterns: vec![
207                "*Event".to_string(),
208                "*StreamEvent".to_string(),
209                "*StreamResponse".to_string(),
210            ],
211        }
212    }
213}
214
215/// Detected streaming endpoint from OpenAPI analysis
216#[derive(Debug, Clone)]
217pub struct DetectedStreamingEndpoint {
218    /// Operation ID
219    pub operation_id: String,
220    /// Stream parameter name
221    pub stream_parameter: String,
222    /// Detected event union type
223    pub event_union_type: Option<String>,
224    /// Detected content type
225    pub content_type: Option<String>,
226    /// Detected event types
227    pub event_types: Vec<String>,
228}
229
230/// Auto-detection result for streaming capabilities
231#[derive(Debug, Clone)]
232pub struct StreamingDetectionResult {
233    /// Detected streaming endpoints
234    pub endpoints: Vec<DetectedStreamingEndpoint>,
235    /// Event types found in the spec
236    pub event_types: BTreeMap<String, Vec<String>>,
237    /// Discriminated unions that could be streaming events
238    pub potential_event_unions: Vec<String>,
239}