From 7c7e99dca1c83231ab92d2817a5c1eb72656d880 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Thu, 3 Mar 2022 15:54:00 +0100 Subject: [PATCH] proxmox-schema: add convenience macros for ParameterError with two variants: (expr, expr) => assumes that the second is an 'Error' (expr, (tt)+) => passes the tt through anyhow::format_err also added tests Signed-off-by: Dominik Csapak --- proxmox-schema/src/schema.rs | 28 +++++++++++++++++++++++++++- proxmox-schema/tests/schema.rs | 13 +++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/proxmox-schema/src/schema.rs b/proxmox-schema/src/schema.rs index 0f90682a..79b240f1 100644 --- a/proxmox-schema/src/schema.rs +++ b/proxmox-schema/src/schema.rs @@ -21,6 +21,32 @@ pub struct ParameterError { error_list: Vec<(String, Error)>, } +/// Like anyhow's `format_err` but producing a `ParameterError`. +#[macro_export] +macro_rules! param_format_err { + ($field:expr, $err:expr) => { + $crate::ParameterError::from(($field, $err)) + }; + + ($field:expr, $($msg:tt)+) => { + $crate::ParameterError::from(($field, ::anyhow::format_err!($($msg)+))) + }; +} + +/// Like anyhow's `bail` but enclosing a `ParameterError`, so +/// a `downcast` can extract it later. This is useful for +/// API calls that need to do parameter checking manually. +#[macro_export] +macro_rules! param_bail { + ($field:expr, $err:expr) => {{ + return Err($crate::param_format_err!($field, $err).into()); + }}; + + ($field:expr, $($msg:tt)+) => {{ + return Err($crate::param_format_err!($field, $($msg)+).into()); + }}; +} + impl std::error::Error for ParameterError {} impl ParameterError { @@ -538,7 +564,7 @@ impl ArraySchema { for (i, item) in list.iter().enumerate() { let result = self.items.verify_json(item); if let Err(err) = result { - return Err(ParameterError::from((format!("[{}]", i), err)).into()); + param_bail!(format!("[{}]", i), err); } } diff --git a/proxmox-schema/tests/schema.rs b/proxmox-schema/tests/schema.rs index ed09bb18..a0d79866 100644 --- a/proxmox-schema/tests/schema.rs +++ b/proxmox-schema/tests/schema.rs @@ -395,3 +395,16 @@ fn test_verify_complex_array() { assert!(res.is_err()); } } + +#[test] +fn test_parameter_error_macro() { + fn _bail_with_format() -> Result<(), anyhow::Error> { + let baz = "baz"; + param_bail!("foo", "bar: {}", baz); + } + + fn _bail_with_err() -> Result<(), anyhow::Error> { + let err = anyhow::format_err!("bar"); + param_bail!("foo", err); + } +}