Improve rust integer type definition

Look at minimum and maximum for integers to identify
i8/u8/i16/u16/i32/u32
Change-Id: Ie8e934e39f9f45f43739f17a60882ff89ab50d0f
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
This commit is contained in:
Artem Goncharov
2025年09月09日 16:47:38 +02:00
parent 7794508262
commit 3ac21566ce

View File

@@ -28,6 +28,19 @@ def wrap_markdown(input: str, width: int = 79) -> str:
return md.text(input, options={"wrap": width})
def wrap_with(value: str, template="{}") -> str:
"""
Wrap a value (or list of values) with the given template.
- value: a single value or iterable
- template: a string containing `{}` as placeholder
"""
# Handle single value
if isinstance(value, str):
return template.format(value)
# Handle iterable
return [template.format(v) for v in value]
class BaseGenerator:
def __init__(self):
# Lower debug level of mdformat
@@ -39,6 +52,7 @@ class BaseGenerator:
undefined=StrictUndefined,
)
self.env.filters["wrap_markdown"] = wrap_markdown
self.env.filters["wrap_with"] = wrap_with
def get_parser(self, parser):
return parser

View File

@@ -81,18 +81,45 @@ class Integer(BasePrimitiveType):
format: str | None = None
imports: set[str] = set()
clap_macros: set[str] = set()
minimum: int | None = None
maximum: int | None = None
original_data_type: BaseCompoundType | BaseCompoundType | None = None
@property
def type_hint(self):
if self.format == "int32":
if self.minimum is not None:
if self.minimum == 0:
if not self.maximum or self.format == "u32":
return "u32"
elif self.maximum == 65535 or self.format == "u16":
return "u16"
elif self.maximum == 255 or self.format == "u8":
return "u8"
elif self.minimum == -128 and self.maximum == 127:
return "i8"
elif self.minimum == -32768 and self.maximum == 32767:
return "i8"
if self.format in ["int32", "i32"]:
return "i32"
elif self.format == "int64":
elif self.format == ["int16", "i16"]:
return "i16"
elif self.format == ["int8", "i8"]:
return "i8"
elif self.format == ["uint32", "u32"]:
return "u32"
elif self.format == ["uint16", "u16"]:
return "u16"
elif self.format == ["uint8", "u8"]:
return "u8"
elif self.format == ["int64", "i64"]:
return "i64"
elif self.format == ["uint64", "u64"]:
return "u64"
return "i32"
def get_sample(self):
return "123"
return f"7 as {self.type_hint}" if self.type_hint != "i32" else "123"
class Null(BasePrimitiveType):

View File

@@ -180,10 +180,11 @@ Some({{ val }})
{#- Macros to render setting Request data from CLI input #}
{%- macro set_request_data_from_input(manager, dst_var, param, val_var, by_ref=False) %}
{%- set is_nullable = param.is_nullable if param.is_nullable is defined else False %}
{%- if param.type_hint in ["Option<Option<bool>>", "Option<Option<i32>>", "Option<Option<i64>>"] %}
{%- set primitives = ["bool", "u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "f8", "f16", "f32", "f64"] %}
{%- if param.type_hint in primitives | wrap_with("Option<Option<{}>>") | list %}
{{ dst_var }}.{{ param.remote_name }}({{ ("*" + val_var) if not by_ref else (val + ".clone()") }});
{%- elif param.type_hint in ["Option<i32>", "Option<i64>", "Option<f32>", "Option<f64>", "Option<bool>"] %}
{%- elif param.type_hint in primitives | wrap_with("Option<{}>") | list %}
{%- if param.is_optional is defined and not param.is_optional %}
if let Some(val) = {{ val_var }} {
{{ dst_var }}.{{ param.remote_name }}({{ "*val" if not by_ref else "val.clone()" }});
@@ -192,7 +193,7 @@ Some({{ val }})
{{ dst_var }}.{{ param.remote_name }}({{ ("*" + val_var) if not by_ref else (val_var + ".clone()") }});
{%- endif %}
{%- elif param.type_hint in ["i32", "i64", "f32", "f64", "bool"] %}
{%- elif param.type_hint in primitives %}
{{ dst_var }}.{{ param.remote_name }}({{ val_var | replace("&", "" )}});
{%- elif param.data_type.__class__.__name__ in ["ArrayInput"] %}

View File

@@ -148,6 +148,7 @@ impl fooCommand {
undefined=StrictUndefined,
)
env.filters["wrap_markdown"] = base.wrap_markdown
env.filters["wrap_with"] = base.wrap_with
template = env.get_template("rust_cli/impl.rs.j2")
content = template.render(

View File

@@ -203,3 +203,24 @@ pub struct Request<'a> {
"".join([x.rstrip() for x in expected_root_render.split()]),
"".join([x.rstrip() for x in content.split()]),
)
def test_type_u32(self):
schema = {"type": "integer", "format": "int32", "minimum": 0}
parser = model.JsonSchemaParser()
type_model = parser.parse_schema(schema, [])
rust_type = rust_sdk.TypeManager().convert_model(type_model)
self.assertEqual("u32", rust_type.type_hint)
def test_type_u16(self):
schema = {"type": "integer", "minimum": 0, "maximum": 65535}
parser = model.JsonSchemaParser()
type_model = parser.parse_schema(schema, [])
rust_type = rust_sdk.TypeManager().convert_model(type_model)
self.assertEqual("u16", rust_type.type_hint)
def test_type_u8(self):
schema = {"type": "integer", "minimum": 0, "maximum": 255}
parser = model.JsonSchemaParser()
type_model = parser.parse_schema(schema, [])
rust_type = rust_sdk.TypeManager().convert_model(type_model)
self.assertEqual("u8", rust_type.type_hint)
Reference in New Issue
openstack/codegenerator
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.

The note is not visible to the blocked user.