public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox 02/18] schema: support optional return values
Date: Fri, 18 Dec 2020 12:25:50 +0100	[thread overview]
Message-ID: <20201218112608.6845-3-w.bumiller@proxmox.com> (raw)
In-Reply-To: <20201218112608.6845-1-w.bumiller@proxmox.com>

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
 proxmox/src/api/cli/format.rs |  9 +++++++--
 proxmox/src/api/format.rs     | 13 +++++++++---
 proxmox/src/api/router.rs     | 37 ++++++++++++++++++++++++++++++-----
 3 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/proxmox/src/api/cli/format.rs b/proxmox/src/api/cli/format.rs
index 61d530a..a4e7c02 100644
--- a/proxmox/src/api/cli/format.rs
+++ b/proxmox/src/api/cli/format.rs
@@ -5,6 +5,7 @@ use serde_json::Value;
 use std::collections::HashSet;
 
 use crate::api::format::*;
+use crate::api::router::ReturnType;
 use crate::api::schema::*;
 
 use super::{value_to_text, TableFormatOptions};
@@ -32,16 +33,20 @@ pub fn format_and_print_result(result: &Value, output_format: &str) {
 /// 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 {
diff --git a/proxmox/src/api/format.rs b/proxmox/src/api/format.rs
index 6916b26..eac2214 100644
--- a/proxmox/src/api/format.rs
+++ b/proxmox/src/api/format.rs
@@ -4,6 +4,7 @@ use anyhow::Error;
 
 use std::io::Write;
 
+use crate::api::router::ReturnType;
 use crate::api::schema::*;
 use crate::api::{ApiHandler, ApiMethod};
 
@@ -197,8 +198,14 @@ fn dump_api_parameters(param: &ObjectSchema) -> String {
     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));
@@ -243,7 +250,7 @@ fn dump_method_definition(method: &str, path: &str, def: Option<&ApiMethod>) ->
         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;
 
diff --git a/proxmox/src/api/router.rs b/proxmox/src/api/router.rs
index f08f9a8..9fb9ec1 100644
--- a/proxmox/src/api/router.rs
+++ b/proxmox/src/api/router.rs
@@ -398,6 +398,33 @@ pub struct ApiAccess {
     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 {
@@ -410,7 +437,7 @@ 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
@@ -433,7 +460,7 @@ impl ApiMethod {
         Self {
             parameters,
             handler,
-            returns: &NULL_SCHEMA,
+            returns: ReturnType::new(false, &NULL_SCHEMA),
             protected: false,
             reload_timezone: false,
             access: ApiAccess {
@@ -447,7 +474,7 @@ impl ApiMethod {
         Self {
             parameters,
             handler: &DUMMY_HANDLER,
-            returns: &NULL_SCHEMA,
+            returns: ReturnType::new(false, &NULL_SCHEMA),
             protected: false,
             reload_timezone: false,
             access: ApiAccess {
@@ -457,8 +484,8 @@ impl ApiMethod {
         }
     }
 
-    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
     }
-- 
2.20.1





  parent reply	other threads:[~2020-12-18 11:37 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-18 11:25 [pbs-devel] [PATCH proxmox 00/18] Optional Return Types and AllOf schema Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 01/18] formatting fixup Wolfgang Bumiller
2020-12-18 11:25 ` Wolfgang Bumiller [this message]
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 03/18] api-macro: support optional return values Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 04/18] schema: support AllOf schemas Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 05/18] schema: allow AllOf schema as method parameter Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 06/18] api-macro: add 'flatten' to SerdeAttrib Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 07/18] api-macro: forbid flattened fields Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 08/18] api-macro: add more standard Maybe methods Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 09/18] api-macro: suport AllOf on structs Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 10/18] schema: ExtractValueDeserializer Wolfgang Bumiller
2020-12-18 11:25 ` [pbs-devel] [PATCH proxmox 11/18] api-macro: object schema entry tuple -> struct Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH proxmox 12/18] api-macro: more tuple refactoring Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH proxmox 13/18] api-macro: factor parameter extraction into a function Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH proxmox 14/18] api-macro: support flattened parameters Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH proxmox 15/18] schema: ParameterSchema at 'api' level Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH proxmox 16/18] proxmox: temporary d/changelog update Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH proxmox 17/18] macro: " Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH proxmox 18/18] proxmox changelog update Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH backup 1/2] adaptions for proxmox 0.9 and proxmox-api-macro 0.3 Wolfgang Bumiller
2020-12-18 11:26 ` [pbs-devel] [PATCH backup 2/2] tests: verify-api: check AllOf schemas Wolfgang Bumiller
2020-12-22  6:45 ` [pbs-devel] [PATCH proxmox 00/18] Optional Return Types and AllOf schema Dietmar Maurer
2020-12-22  6:51   ` Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201218112608.6845-3-w.bumiller@proxmox.com \
    --to=w.bumiller@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal