From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox] schema: add const fn unwrap_*_schema/format methods
Date: Tue, 22 Feb 2022 09:47:16 +0100 [thread overview]
Message-ID: <20220222084717.60064-1-w.bumiller@proxmox.com> (raw)
'unwrap_' because they will panic and as `const fn` since
panic in const fn is now possible
Note that const evaluation will only be triggered when
actually used in const context, so to ensure *compile time*
checks, use something like this:
const FOO_SCHEMA: &AllOfSchema =
SomeType::API_SCHEMA.unwrap_all_of_schema();
then_use(FOO_SCHEMA);
or to use the list of enum values of an enum string type
with compile time checks:
const LIST: &'static [EnumEntry] =
AnEnumStringType::API_SCHEMA
.unwrap_string_schema()
.unwrap_format()
.unwrap_enum_format();
for values in LIST {
...
}
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
While schemas are usually unlikely to change type or lose properties
such as enum lists, for `ObjectSchema` and `AllOfSchema` this may
actually allow catching future issues at build-time...
If we want to do this, I'd prepare a similar patch set for all the
`ApiHandler::...` value extractions we do in the CLI in pbs (just look
at the output of `egrep -B1 -nr 'unreachable' ./src ./*/src` in pbs ;-) )
proxmox-schema/src/schema.rs | 90 ++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/proxmox-schema/src/schema.rs b/proxmox-schema/src/schema.rs
index 58c6a82..0f90682 100644
--- a/proxmox-schema/src/schema.rs
+++ b/proxmox-schema/src/schema.rs
@@ -459,6 +459,14 @@ impl StringSchema {
bail!("Expected string value.");
}
}
+
+ /// Get the [`format`](ApiStringFormat), panics if there is no format.
+ pub const fn unwrap_format(&self) -> &'static ApiStringFormat {
+ match self.format {
+ Some(v) => v,
+ None => panic!("unwrap_format on StringSchema without format"),
+ }
+ }
}
/// Data type to describe array of values.
@@ -950,6 +958,62 @@ impl Schema {
_ => bail!("Got unexpected schema type."),
}
}
+
+ /// Gets the underlying [`BooleanSchema`], panics on different schemas.
+ pub const fn unwrap_boolean_schema(&self) -> &BooleanSchema {
+ match self {
+ Schema::Boolean(s) => s,
+ _ => panic!("unwrap_boolean_schema on different schema"),
+ }
+ }
+
+ /// Gets the underlying [`IntegerSchema`], panics on different schemas.
+ pub const fn unwrap_integer_schema(&self) -> &IntegerSchema {
+ match self {
+ Schema::Integer(s) => s,
+ _ => panic!("unwrap_integer_schema on different schema"),
+ }
+ }
+
+ /// Gets the underlying [`NumberSchema`], panics on different schemas.
+ pub const fn unwrap_number_schema(&self) -> &NumberSchema {
+ match self {
+ Schema::Number(s) => s,
+ _ => panic!("unwrap_number_schema on different schema"),
+ }
+ }
+
+ /// Gets the underlying [`StringSchema`], panics on different schemas.
+ pub const fn unwrap_string_schema(&self) -> &StringSchema {
+ match self {
+ Schema::String(s) => s,
+ _ => panic!("unwrap_string_schema on different schema"),
+ }
+ }
+
+ /// Gets the underlying [`ObjectSchema`], panics on different schemas.
+ pub const fn unwrap_object_schema(&self) -> &ObjectSchema {
+ match self {
+ Schema::Object(s) => s,
+ _ => panic!("unwrap_object_schema on different schema"),
+ }
+ }
+
+ /// Gets the underlying [`ArraySchema`], panics on different schemas.
+ pub const fn unwrap_array_schema(&self) -> &ArraySchema {
+ match self {
+ Schema::Array(s) => s,
+ _ => panic!("unwrap_array_schema on different schema"),
+ }
+ }
+
+ /// Gets the underlying [`AllOfSchema`], panics on different schemas.
+ pub const fn unwrap_all_of_schema(&self) -> &AllOfSchema {
+ match self {
+ Schema::AllOf(s) => s,
+ _ => panic!("unwrap_all_of_schema on different schema"),
+ }
+ }
}
/// A string enum entry. An enum entry must have a value and a description.
@@ -1047,6 +1111,32 @@ pub enum ApiStringFormat {
VerifyFn(fn(&str) -> Result<(), Error>),
}
+impl ApiStringFormat {
+ /// Gets the underlying [`&[EnumEntry]`](EnumEntry) list, panics on different formats.
+ pub const fn unwrap_enum_format(&self) -> &'static [EnumEntry] {
+ match self {
+ ApiStringFormat::Enum(v) => v,
+ _ => panic!("unwrap_enum_format on a different ApiStringFormat"),
+ }
+ }
+
+ /// Gets the underlying [`&ConstRegexPattern`](ConstRegexPattern), panics on different formats.
+ pub const fn unwrap_pattern_format(&self) -> &'static ConstRegexPattern {
+ match self {
+ ApiStringFormat::Pattern(v) => v,
+ _ => panic!("unwrap_pattern_format on a different ApiStringFormat"),
+ }
+ }
+
+ /// Gets the underlying property [`&Schema`](Schema), panics on different formats.
+ pub const fn unwrap_property_string_format(&self) -> &'static Schema {
+ match self {
+ ApiStringFormat::PropertyString(v) => v,
+ _ => panic!("unwrap_property_string_format on a different ApiStringFormat"),
+ }
+ }
+}
+
impl std::fmt::Debug for ApiStringFormat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
--
2.30.2
next reply other threads:[~2022-02-22 8:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-22 8:47 Wolfgang Bumiller [this message]
2022-02-22 8:47 ` [pbs-devel] [PATCH backup] constify schema usage and dedup some code Wolfgang Bumiller
2022-02-23 8:31 ` [pbs-devel] [PATCH proxmox] schema: add const fn unwrap_*_schema/format methods Thomas Lamprecht
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=20220222084717.60064-1-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.