Skip to main content

openapi_nexus_core/data/
http_response.rs

1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4
5use super::content_type::ContentType;
6use super::status_code::StatusCode;
7use openapi_nexus_spec::oas31::spec::{Header, ObjectOrReference, ObjectSchema, Response};
8
9/// Normalized representation of an OpenAPI response for template generation.
10///
11/// `HttpResponse` captures the status code, body schemas grouped by content type,
12/// a human-readable description, and response headers. It is consumed by the
13/// TypeScript generators to drive return-type and transformer creation.
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct HttpResponse {
16    pub status: StatusCode,
17    pub description: String,
18    pub headers: BTreeMap<String, ObjectOrReference<Header>>,
19    pub contents: BTreeMap<ContentType, Option<ObjectOrReference<ObjectSchema>>>,
20}
21
22impl HttpResponse {
23    /// Construct an `HttpResponse` from the resolved OpenAPI `Response`.
24    ///
25    /// The method copies metadata we need during code generation while preserving
26    /// any referenced schemas for later resolution.
27    pub fn from_openapi(status: StatusCode, response: &Response) -> HttpResponse {
28        let contents = response
29            .content
30            .iter()
31            .map(|(content_type, media_type)| {
32                let parsed_type = content_type.parse::<ContentType>().unwrap();
33                (parsed_type, media_type.schema.clone())
34            })
35            .collect();
36
37        HttpResponse {
38            status,
39            description: response.description.clone().unwrap_or_default(),
40            headers: response.headers.clone(),
41            contents,
42        }
43    }
44
45    pub fn is_success(&self) -> bool {
46        self.status.is_success()
47    }
48
49    pub fn is_default(&self) -> bool {
50        self.status.is_default()
51    }
52
53    pub fn json_schema(&self) -> Option<&ObjectOrReference<ObjectSchema>> {
54        self.contents
55            .get(&ContentType::Json)
56            .and_then(|schema| schema.as_ref())
57    }
58
59    pub fn content_types(&self) -> impl Iterator<Item = &ContentType> {
60        self.contents.keys()
61    }
62
63    pub fn has_body(&self) -> bool {
64        !self.contents.is_empty()
65    }
66
67    pub fn has_json_body(&self) -> bool {
68        self.contents.contains_key(&ContentType::Json)
69    }
70}