router: OneOfSchema support
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com> Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
This commit is contained in:
parent
d48a150835
commit
ae7454b05e
@ -1,11 +1,11 @@
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use proxmox_lang::c_str;
|
use proxmox_lang::c_str;
|
||||||
use proxmox_schema::{ObjectSchemaType, Schema, SchemaPropertyEntry};
|
use proxmox_schema::{ObjectSchemaType, OneOfSchema, Schema, SchemaPropertyEntry};
|
||||||
|
|
||||||
/// allows to configure the default output fromat using environment vars
|
/// allows to configure the default output fromat using environment vars
|
||||||
pub const ENV_VAR_PROXMOX_OUTPUT_FORMAT: &str = "PROXMOX_OUTPUT_FORMAT";
|
pub const ENV_VAR_PROXMOX_OUTPUT_FORMAT: &str = "PROXMOX_OUTPUT_FORMAT";
|
||||||
@ -66,10 +66,9 @@ fn data_to_text(data: &Value, schema: &Schema) -> Result<String, Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match schema {
|
match schema {
|
||||||
Schema::Null => {
|
// When printing a table of OneOf values, different variants have different properties, and
|
||||||
// makes no sense to display Null columns
|
// nonexistent properties will be null.
|
||||||
bail!("internal error");
|
Schema::Null => Ok(String::new()),
|
||||||
}
|
|
||||||
Schema::Boolean(_) => match data.as_bool() {
|
Schema::Boolean(_) => match data.as_bool() {
|
||||||
Some(value) => Ok(String::from(if value { "1" } else { "0" })),
|
Some(value) => Ok(String::from(if value { "1" } else { "0" })),
|
||||||
None => bail!("got unexpected data (expected bool)."),
|
None => bail!("got unexpected data (expected bool)."),
|
||||||
@ -89,6 +88,7 @@ fn data_to_text(data: &Value, schema: &Schema) -> Result<String, Error> {
|
|||||||
Schema::Object(_) => Ok(data.to_string()),
|
Schema::Object(_) => Ok(data.to_string()),
|
||||||
Schema::Array(_) => Ok(data.to_string()),
|
Schema::Array(_) => Ok(data.to_string()),
|
||||||
Schema::AllOf(_) => Ok(data.to_string()),
|
Schema::AllOf(_) => Ok(data.to_string()),
|
||||||
|
Schema::OneOf(_) => Ok(data.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,6 +620,16 @@ fn format_object<W: Write>(
|
|||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
format_object_with_properties(output, data, schema, options, properties_to_print)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_object_with_properties<W: Write>(
|
||||||
|
output: W,
|
||||||
|
data: &Value,
|
||||||
|
schema: &dyn ObjectSchemaType,
|
||||||
|
options: &TableFormatOptions,
|
||||||
|
properties_to_print: Vec<String>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
let row_count = properties_to_print.len();
|
let row_count = properties_to_print.len();
|
||||||
if row_count == 0 {
|
if row_count == 0 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -723,6 +733,25 @@ fn format_object<W: Write>(
|
|||||||
render_table(output, &tabledata, &column_names, options)
|
render_table(output, &tabledata, &column_names, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn format_one_of<W: Write>(
|
||||||
|
output: W,
|
||||||
|
data: &Value,
|
||||||
|
schema: &OneOfSchema,
|
||||||
|
options: &TableFormatOptions,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let properties_to_print = if options.column_config.is_empty() {
|
||||||
|
extract_one_of_variant_properties(data, schema)?
|
||||||
|
} else {
|
||||||
|
options
|
||||||
|
.column_config
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.name.clone())
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
format_object_with_properties(output, data, schema, options, properties_to_print)
|
||||||
|
}
|
||||||
|
|
||||||
fn extract_properties_to_print<I>(properties: I) -> Vec<String>
|
fn extract_properties_to_print<I>(properties: I) -> Vec<String>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = &'static SchemaPropertyEntry>,
|
I: Iterator<Item = &'static SchemaPropertyEntry>,
|
||||||
@ -743,6 +772,21 @@ where
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extract_one_of_variant_properties(
|
||||||
|
value: &Value,
|
||||||
|
schema: &OneOfSchema,
|
||||||
|
) -> Result<Vec<String>, Error> {
|
||||||
|
let variant_name = value[schema.type_property()]
|
||||||
|
.as_str()
|
||||||
|
.ok_or_else(|| format_err!("missing '{}' property", schema.type_property()))?;
|
||||||
|
let variant_schema = schema
|
||||||
|
.lookup_variant(variant_name)
|
||||||
|
.ok_or_else(|| format_err!("invalid variant '{variant_name}'"))?;
|
||||||
|
Ok(extract_properties_to_print(
|
||||||
|
variant_schema.unwrap_object_schema().properties(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// Format data using TableFormatOptions
|
/// Format data using TableFormatOptions
|
||||||
pub fn value_to_text<W: Write>(
|
pub fn value_to_text<W: Write>(
|
||||||
output: W,
|
output: W,
|
||||||
@ -768,8 +812,8 @@ pub fn value_to_text<W: Write>(
|
|||||||
Schema::String(_string_schema) => {
|
Schema::String(_string_schema) => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
Schema::Object(object_schema) => {
|
Schema::Object(schema) => {
|
||||||
format_object(output, data, object_schema, options)?;
|
format_object(output, data, schema, options)?;
|
||||||
}
|
}
|
||||||
Schema::Array(array_schema) => {
|
Schema::Array(array_schema) => {
|
||||||
let list = match data.as_array_mut() {
|
let list = match data.as_array_mut() {
|
||||||
@ -781,19 +825,25 @@ pub fn value_to_text<W: Write>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match array_schema.items {
|
match array_schema.items {
|
||||||
Schema::Object(object_schema) => {
|
Schema::Object(schema) => {
|
||||||
format_table(output, list, object_schema, options)?;
|
format_table(output, list, schema, options)?;
|
||||||
}
|
}
|
||||||
Schema::AllOf(all_of_schema) => {
|
Schema::AllOf(schema) => {
|
||||||
format_table(output, list, all_of_schema, options)?;
|
format_table(output, list, schema, options)?;
|
||||||
|
}
|
||||||
|
Schema::OneOf(schema) => {
|
||||||
|
format_table(output, list, schema, options)?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Schema::AllOf(all_of_schema) => {
|
Schema::AllOf(schema) => {
|
||||||
format_object(output, data, all_of_schema, options)?;
|
format_object(output, data, schema, options)?;
|
||||||
|
}
|
||||||
|
Schema::OneOf(schema) => {
|
||||||
|
format_one_of(output, data, schema, options)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user