Replace use of unwrap and expect in generated rust code
In order to eliminate rust sdk/cli/tui runtime panics we must get rid of `unwrap` and `expect` use (in tests it can stay). Lot of not generated code was already cleaned and now we need to address what is produced by the generator. Change-Id: Id9782fb947c61c64fc88bd743596e9996fa56b44 Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
This commit is contained in:
@@ -82,7 +82,7 @@ class JsonValue(common_rust.JsonValue):
|
|||||||
if self.original_data_type and isinstance(
|
if self.original_data_type and isinstance(
|
||||||
self.original_data_type, common_rust.Dictionary
|
self.original_data_type, common_rust.Dictionary
|
||||||
):
|
):
|
||||||
imports.update(["std::collections::BTreeMap", "eyre::WrapErr"])
|
imports.update(["std::collections::BTreeMap"])
|
||||||
return imports
|
return imports
|
||||||
|
|
||||||
|
|
||||||
@@ -807,7 +807,6 @@ class RustCliGenerator(BaseGenerator):
|
|||||||
f"openstack_sdk::api::{'::'.join(link_res_name.split('/'))}::find"
|
f"openstack_sdk::api::{'::'.join(link_res_name.split('/'))}::find"
|
||||||
f" as find_{link_res_name.split('/')[-1]}"
|
f" as find_{link_res_name.split('/')[-1]}"
|
||||||
)
|
)
|
||||||
global_additional_imports.add("eyre::OptionExt")
|
|
||||||
global_additional_imports.add("eyre::eyre")
|
global_additional_imports.add("eyre::eyre")
|
||||||
|
|
||||||
# List of operation variants (based on the body)
|
# List of operation variants (based on the body)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
{% import 'rust_macros.j2' as macros with context -%}
|
{% import 'rust_macros.j2' as macros with context -%}
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
use eyre::{OptionExt, WrapErr};
|
||||||
|
|
||||||
use openstack_sdk::AsyncOpenStack;
|
use openstack_sdk::AsyncOpenStack;
|
||||||
|
|
||||||
@@ -230,7 +231,7 @@ impl {{ target_class_name }}Command {
|
|||||||
let mut regexes: Vec<Regex> = vec![
|
let mut regexes: Vec<Regex> = vec![
|
||||||
{%- for hdr, spec in resource_header_metadata.items() %}
|
{%- for hdr, spec in resource_header_metadata.items() %}
|
||||||
{%- if "*" in hdr %}
|
{%- if "*" in hdr %}
|
||||||
Regex::new(r"(?i){{ hdr | replace("*", "\.*") }}").unwrap(),
|
Regex::new(r"(?i){{ hdr | replace("*", "\.*") }}").wrap_err("failed to compile the regex")?,
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -21,8 +21,15 @@
|
|||||||
|
|
||||||
let size: u64 = headers
|
let size: u64 = headers
|
||||||
.get("content-length")
|
.get("content-length")
|
||||||
.map(|x| x.to_str().expect("Header is a string"))
|
.and_then(|x| {
|
||||||
|
x.to_str()
|
||||||
|
.inspect_err(|e| {
|
||||||
|
tracing::warn!("content-length header cannot be treated as string: {}", e)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
.unwrap_or("0")
|
.unwrap_or("0")
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.inspect_err(|e| tracing::warn!("content-length header mut represent u64 number: {}", e))
|
||||||
|
.unwrap_or_default();
|
||||||
download_file(self.file.clone().unwrap_or(image_name), size, data).await?;
|
download_file(self.file.clone().unwrap_or(image_name), size, data).await?;
|
||||||
|
|||||||
@@ -2,10 +2,17 @@
|
|||||||
|
|
||||||
let size: u64 = headers
|
let size: u64 = headers
|
||||||
.get("content-length")
|
.get("content-length")
|
||||||
.map(|x| x.to_str().expect("Header is a string"))
|
.and_then(|x| {
|
||||||
|
x.to_str()
|
||||||
|
.inspect_err(|e| {
|
||||||
|
tracing::warn!("content-length header cannot be treated as string: {}", e)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
.unwrap_or("0")
|
.unwrap_or("0")
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.inspect_err(|e| tracing::warn!("content-length header mut represent u64 number: {}", e))
|
||||||
|
.unwrap_or_default();
|
||||||
download_file(
|
download_file(
|
||||||
self.file.clone().unwrap_or(self.{{ last_path_parameter.name }}.clone()),
|
self.file.clone().unwrap_or(self.{{ last_path_parameter.name }}.clone()),
|
||||||
size,
|
size,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// Patching resource requires fetching and calculating diff
|
// Patching resource requires fetching and calculating diff
|
||||||
let resource_id = find_data["id"]
|
let resource_id = find_data["id"]
|
||||||
.as_str()
|
.as_str()
|
||||||
.expect("Resource ID is a string")
|
.ok_or_else(|| eyre::eyre!("resource ID must be a string"))?
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
let data: {{ response_class_name }} = serde_json::from_value(find_data)?;
|
let data: {{ response_class_name }} = serde_json::from_value(find_data)?;
|
||||||
@@ -46,8 +46,8 @@
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
let curr_json = serde_json::to_value(&data).unwrap();
|
let curr_json = serde_json::to_value(&data).wrap_err("current state must be a valid json object")?;
|
||||||
let mut new_json = serde_json::to_value(&new).unwrap();
|
let mut new_json = serde_json::to_value(&new).wrap_err("new state must be a valid json object")?;
|
||||||
|
|
||||||
{%- if root.additional_fields_type %}
|
{%- if root.additional_fields_type %}
|
||||||
{#- additional properties are not present in the output and thus handleded on the raw json #}
|
{#- additional properties are not present in the output and thus handleded on the raw json #}
|
||||||
|
|||||||
@@ -37,8 +37,7 @@
|
|||||||
{%- else %}
|
{%- else %}
|
||||||
.with_prompt("{{ k }}")
|
.with_prompt("{{ k }}")
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
.interact()
|
.interact()?;
|
||||||
.unwrap();
|
|
||||||
{{ builder_name }}.{{ v.remote_name }}(secret.to_string());
|
{{ builder_name }}.{{ v.remote_name }}(secret.to_string());
|
||||||
}
|
}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
@@ -46,7 +45,7 @@
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
ep_builder.{{ root_field.remote_name }}({{ builder_name }}.build().unwrap());
|
ep_builder.{{ root_field.remote_name }}({{ builder_name }}.build().wrap_err("error preparing the request data")?);
|
||||||
{% if root_field.is_optional %}
|
{% if root_field.is_optional %}
|
||||||
}
|
}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ Some({{ val }})
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{{ dst_var }}.{{ param.remote_name }}({{ builder_name }}.build().expect("A valid object"));
|
{{ dst_var }}.{{ param.remote_name }}({{ builder_name }}.build().wrap_err("error preparing the request data")?);
|
||||||
|
|
||||||
{%- elif param.data_type.__class__.__name__ == "Struct" %}
|
{%- elif param.data_type.__class__.__name__ == "Struct" %}
|
||||||
{% set builder_name = param.local_name + "_builder" %}
|
{% set builder_name = param.local_name + "_builder" %}
|
||||||
@@ -297,7 +297,7 @@ Some({{ val }})
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{{ dst_var }}.{{ param.remote_name }}({{ builder_name }}.build().expect("A valid object"));
|
{{ dst_var }}.{{ param.remote_name }}({{ builder_name }}.build().wrap_err("error preparing the request data")?);
|
||||||
}
|
}
|
||||||
|
|
||||||
{%- elif param.data_type.item_type.__class__.__name__ == "JsonValue" %}
|
{%- elif param.data_type.item_type.__class__.__name__ == "JsonValue" %}
|
||||||
@@ -428,14 +428,16 @@ Some({{ val }})
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
{{ dst_var }}.{{ param.remote_name }}(
|
{{ dst_var }}.{{ param.remote_name }}(
|
||||||
{{ val_var }}.iter()
|
{{ val_var }}.iter()
|
||||||
.map( |v| {
|
.map(|v| {
|
||||||
v.as_object()
|
v.as_object()
|
||||||
.expect("Is a valid Json object")
|
.ok_or_eyre("{{ param.remote_name }} must be a valid json object")
|
||||||
.into_iter()
|
.map(|obj| {
|
||||||
.map(|(k, v)| (k.into(), v.clone().into()))
|
obj.into_iter()
|
||||||
.collect::<BTreeMap<_,Value>>()
|
.map(|(k, v)| (k.into(), v.clone()))
|
||||||
|
.collect::<BTreeMap<_, Value>>()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
);
|
);
|
||||||
{%- else %}
|
{%- else %}
|
||||||
{#- Normal array #}
|
{#- Normal array #}
|
||||||
@@ -550,13 +552,13 @@ Some({{ val }})
|
|||||||
if let Some(val) = &self.path.{{ v.local_name }} {
|
if let Some(val) = &self.path.{{ v.local_name }} {
|
||||||
{{ builder }}.{{ v.local_name }}(val);
|
{{ builder }}.{{ v.local_name }}(val);
|
||||||
} else {
|
} else {
|
||||||
{{ builder }}.{{ v.local_name }}(client.get_current_project().expect("Project ID must be known").id);
|
{{ builder }}.{{ v.local_name }}(client.get_current_project().wrap_err("project ID must be known")?.id);
|
||||||
}
|
}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- elif not find_mode and find_present and operation_type in ["show", "set", "download"] %}
|
{%- elif not find_mode and find_present and operation_type in ["show", "set", "download"] %}
|
||||||
let resource_id = find_data["id"]
|
let resource_id = find_data["id"]
|
||||||
.as_str()
|
.as_str()
|
||||||
.expect("Resource ID is a string")
|
.ok_or_else(|| eyre::eyre!("resource ID must be a string"))?
|
||||||
.to_string();
|
.to_string();
|
||||||
{{ builder }}.{{ v.local_name }}(resource_id.clone());
|
{{ builder }}.{{ v.local_name }}(resource_id.clone());
|
||||||
{%- else %}
|
{%- else %}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class TestRustCliResponseManager(TestCase):
|
|||||||
|
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
use eyre::{OptionExt, WrapErr};
|
||||||
use openstack_sdk::AsyncOpenStack;
|
use openstack_sdk::AsyncOpenStack;
|
||||||
use crate::output::OutputProcessor;
|
use crate::output::OutputProcessor;
|
||||||
use crate::Cli;
|
use crate::Cli;
|
||||||
|
|||||||
Reference in New Issue
Block a user