Prepare generation of create types for tui.

Change-Id: I326156aa1ebfd85ad19bf4f164c0537d236ae204
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
This commit is contained in:
Artem Goncharov
2025-10-08 18:44:08 +02:00
parent 298e6753ed
commit e962f0fa5a
4 changed files with 58 additions and 8 deletions

View File

@@ -628,7 +628,7 @@ class HashMapResponse(Dictionary):
"""Wrapper around a simple dictionary to implement Display trait"""
# name: str | None = None
lifetimes: set[str] = set()
# lifetimes: set[str] = set()
@property
def type_hint(self):

View File

@@ -231,6 +231,17 @@ class Struct(rust_sdk.Struct):
return result
class StringEnum(common_rust.StringEnum):
def get_sdk_setter(
self, source_var_name: str, sdk_mod_path: str, into: bool = False
) -> str:
return f"val.clone().into()"
@property
def derive_container_macros(self) -> str | None:
return "#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]"
class TypeManager(common_rust.TypeManager):
"""Rust SDK type manager
@@ -253,6 +264,7 @@ class TypeManager(common_rust.TypeManager):
request_parameter_class: type[common_rust.RequestParameter] = (
common_rust.RequestParameter
)
string_enum_class = StringEnum
sdk_type_manager: SdkTypeManager | None = None

View File

@@ -16,7 +16,7 @@
// `openstack-codegenerator`.
{% import 'rust_macros.j2' as macros with context -%}
use derive_builder::Builder;
use eyre::{Result, WrapErr, Report};
use eyre::{Result, WrapErr, Report, eyre};
use serde::{Deserialize, Serialize};
use std::fmt;
use tokio::sync::mpsc::UnboundedSender;
@@ -33,7 +33,7 @@ use {{ mod }};
{%- set sdk_data_type = sdk_type_manager.get_root_data_type() %}
{%- if data_type.__class__.__name__ == "Struct" %}
#[derive(Builder, Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Builder, Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)]
#[builder(setter(strip_option))]
pub struct {{ class_name }}{
{%- for name, param in type_manager.parameters|dictsort if param.location != "header" %}
@@ -51,6 +51,7 @@ pub struct {{ class_name }}{
Option<{{ param.type_hint }}>,
{%- endif %}
{%- endif %}
{%- endfor %}
{%- if data_type["fields"] is defined %}
{#- Structure #}
@@ -62,13 +63,48 @@ pub struct {{ class_name }}{
{%- endfor %}
{%- endif %}
{%- endfor %}
}
{%- for type, sdk_type in type_manager.get_subtypes_with_sdk() %}
{%- if type["base_type"] == "struct" %}
{%- if type["variants"] is defined %}
{#- Enum #}
{{ macros.docstring(type.description, indent=0) }}
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub enum {{ type.name }} {
{%- for k in type.variants.keys()|sort %}
{{ type.variant_serde_macros(k) }}
{{ k }},
{%- endfor %}
}
impl TryFrom<String> for {{ type.name }} {
type Error = Report;
fn try_from(value: String) -> Result<Self, Self::Error> {
match value.as_str() {
{%- for k, vals in type.variants|dictsort %}
{%- for val in vals|sort %}
"{{val}}" => Ok(Self::{{k}}),
{%- endfor %}
{%- endfor %}
other => Err(eyre!("'{}' is not a valid {{ type.name }}", other)),
}
}
}
impl From<{{ type.name }}> for {{ sdk_mod_path | join("::") }}::{{ sdk_type.name }} {
fn from(value: {{ type.name }}) -> Self {
match value {
{%- for k in type.variants.keys()|sort %}
{{ type.name }}::{{k}} => Self::{{k}},
{%- endfor %}
}
}
}
{%- elif type["base_type"] == "struct" %}
/// {{ type.name }} data
#[derive(Builder, Debug, Default, Deserialize, Clone, Eq, PartialEq, Serialize)]
#[derive(Builder, Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[builder(setter(strip_option))]
pub struct {{ type.name }} {
{%- for _, field in type.fields | dictsort %}
@@ -118,7 +154,7 @@ impl fmt::Display for {{ class_name }} {
}
}
impl TryFrom<&{{ class_name }}> for RequestBuilder{{ "<'_>" if sdk_type_manager.get_request_static_lifetimes(data_type) else "" }} {
impl TryFrom<&{{ class_name }}> for RequestBuilder{{ "<'_>" if sdk_type_manager.get_request_static_lifetimes(sdk_data_type) else "" }} {
type Error = Report;
fn try_from(value: &{{ class_name }}) -> Result<Self, Self::Error> {
let mut ep_builder = Self::default();
@@ -182,7 +218,7 @@ impl ExecuteApiRequest for {{ class_name }} {
request: request.clone(),
data: ep.query_async(session).await?,
})?;
{%- elif operation_type in ["action", "set"] %}
{%- elif operation_type in ["action", "create", "set"] %}
app_tx.send(Action::ApiResponseData {
request: request.clone(),
data: ep.query_async(session).await?,

View File

@@ -3133,6 +3133,8 @@ resources:
sdk_mod_name: create
rust-sdk:
module_name: create
rust-tui:
module_name: create
delete:
operation_id: security-group-rules/id:delete
operation_type: delete