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:
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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"] %}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
Block a user