Skip to main content

oxirs_samm/codegen/
openapi_types.rs

1use serde_json::{Map, Value};
2
3/// Configuration for the `x-samm-pagination` OpenAPI extension.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct PaginationConfig {
6    /// Maximum number of items returned per page.
7    pub page_size: usize,
8    /// Whether the pagination strategy uses opaque cursors (`true`) or numeric page offsets (`false`).
9    pub cursor_based: bool,
10    /// Optional HTTP response-header name where the server advertises the total result-set count.
11    pub total_count_header: Option<String>,
12}
13
14impl Default for PaginationConfig {
15    fn default() -> Self {
16        Self {
17            page_size: 10,
18            cursor_based: false,
19            total_count_header: None,
20        }
21    }
22}
23
24impl PaginationConfig {
25    /// Serialise the config to the `x-samm-pagination` JSON object.
26    pub fn to_extension_value(&self) -> Value {
27        let mut obj = Map::new();
28        obj.insert(
29            "pageSize".to_string(),
30            Value::Number(serde_json::Number::from(self.page_size)),
31        );
32        obj.insert("cursorBased".to_string(), Value::Bool(self.cursor_based));
33        if let Some(ref header) = self.total_count_header {
34            obj.insert(
35                "totalCountHeader".to_string(),
36                Value::String(header.clone()),
37            );
38        }
39        Value::Object(obj)
40    }
41}
42
43/// Target OpenAPI specification version for [`OpenApiGenerator`].
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
45pub enum OpenApiVersion {
46    /// OpenAPI 3.0.3 (default, maximum compatibility).
47    #[default]
48    V30,
49    /// OpenAPI 3.1.0, aligned with JSON Schema 2020-12.
50    V31,
51}
52
53/// HTTP methods supported in generated path items.
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum HttpMethod {
56    /// HTTP GET
57    Get,
58    /// HTTP POST
59    Post,
60    /// HTTP PUT
61    Put,
62    /// HTTP PATCH
63    Patch,
64    /// HTTP DELETE
65    Delete,
66}
67
68impl HttpMethod {
69    /// Returns the lowercase string representation of the HTTP method.
70    pub fn as_str(self) -> &'static str {
71        match self {
72            HttpMethod::Get => "get",
73            HttpMethod::Post => "post",
74            HttpMethod::Put => "put",
75            HttpMethod::Patch => "patch",
76            HttpMethod::Delete => "delete",
77        }
78    }
79}
80
81/// Configuration for [`OpenApiGenerator`].
82#[derive(Debug, Clone)]
83pub struct OpenApiOptions {
84    /// Target OpenAPI specification version (3.0 or 3.1).
85    pub version: OpenApiVersion,
86    /// The base path prefix for all generated endpoints.
87    pub base_path: String,
88    /// API version string embedded in the `info` object.
89    pub api_version: String,
90    /// Whether to include a GET endpoint for reading the Aspect.
91    pub include_get: bool,
92    /// Whether to include a POST endpoint for creating Aspect instances.
93    pub include_post: bool,
94    /// Whether to include a PUT endpoint for updating Aspect instances.
95    pub include_put: bool,
96    /// Whether to include a DELETE endpoint.
97    pub include_delete: bool,
98    /// Prefer JSON Schema `$defs` (2020-12) style inside component schemas.
99    pub use_defs_keyword: bool,
100    /// Language used for description / title lookup.
101    pub language: String,
102    /// Optional pagination extension configuration.
103    pub pagination: Option<PaginationConfig>,
104}
105
106impl Default for OpenApiOptions {
107    fn default() -> Self {
108        Self {
109            version: OpenApiVersion::V30,
110            base_path: "/api/v1/aspects".to_string(),
111            api_version: "1.0.0".to_string(),
112            include_get: true,
113            include_post: false,
114            include_put: false,
115            include_delete: false,
116            use_defs_keyword: false,
117            language: "en".to_string(),
118            pagination: None,
119        }
120    }
121}