use std::collections::HashSet;
use crate::api::format::*;
+use crate::api::router::ReturnType;
use crate::api::schema::*;
use super::{value_to_text, TableFormatOptions};
/// formatted tables with borders.
pub fn format_and_print_result_full(
result: &mut Value,
- schema: &Schema,
+ return_type: &ReturnType,
output_format: &str,
options: &TableFormatOptions,
) {
+ if return_type.optional && result.is_null() {
+ return;
+ }
+
if output_format == "json-pretty" {
println!("{}", serde_json::to_string_pretty(&result).unwrap());
} else if output_format == "json" {
println!("{}", serde_json::to_string(&result).unwrap());
} else if output_format == "text" {
- if let Err(err) = value_to_text(std::io::stdout(), result, schema, options) {
+ if let Err(err) = value_to_text(std::io::stdout(), result, &return_type.schema, options) {
eprintln!("unable to format result: {}", err);
}
} else {
use std::io::Write;
+use crate::api::router::ReturnType;
use crate::api::schema::*;
use crate::api::{ApiHandler, ApiMethod};
res
}
-fn dump_api_return_schema(schema: &Schema) -> String {
- let mut res = String::from("*Returns*: ");
+fn dump_api_return_schema(returns: &ReturnType) -> String {
+ let schema = &returns.schema;
+
+ let mut res = if returns.optional {
+ "*Returns* (optionally): ".to_string()
+ } else {
+ "*Returns*: ".to_string()
+ };
let type_text = get_schema_type_text(schema, ParameterDisplayStyle::Config);
res.push_str(&format!("**{}**\n\n", type_text));
Some(api_method) => {
let param_descr = dump_api_parameters(api_method.parameters);
- let return_descr = dump_api_return_schema(api_method.returns);
+ let return_descr = dump_api_return_schema(&api_method.returns);
let mut method = method;
pub permission: &'static Permission,
}
+#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
+pub struct ReturnType {
+ /// A return type may be optional, meaning the method may return null or some fixed data.
+ ///
+ /// If true, the return type in pseudo openapi terms would be `"oneOf": [ "null", "T" ]`.
+ pub optional: bool,
+
+ /// The method's return type.
+ pub schema: &'static schema::Schema,
+}
+
+impl std::fmt::Debug for ReturnType {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.optional {
+ write!(f, "optional {:?}", self.schema)
+ } else {
+ write!(f, "{:?}", self.schema)
+ }
+ }
+}
+
+impl ReturnType {
+ pub const fn new(optional: bool, schema: &'static Schema) -> Self {
+ Self { optional, schema }
+ }
+}
+
/// This struct defines a synchronous API call which returns the result as json `Value`
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
pub struct ApiMethod {
/// Parameter type Schema
pub parameters: &'static schema::ObjectSchema,
/// Return type Schema
- pub returns: &'static schema::Schema,
+ pub returns: ReturnType,
/// Handler function
pub handler: &'static ApiHandler,
/// Access Permissions
Self {
parameters,
handler,
- returns: &NULL_SCHEMA,
+ returns: ReturnType::new(false, &NULL_SCHEMA),
protected: false,
reload_timezone: false,
access: ApiAccess {
Self {
parameters,
handler: &DUMMY_HANDLER,
- returns: &NULL_SCHEMA,
+ returns: ReturnType::new(false, &NULL_SCHEMA),
protected: false,
reload_timezone: false,
access: ApiAccess {
}
}
- pub const fn returns(mut self, schema: &'static Schema) -> Self {
- self.returns = schema;
+ pub const fn returns(mut self, returns: ReturnType) -> Self {
+ self.returns = returns;
self
}