* [pbs-devel] [PATCH proxmox] schema: add const fn unwrap_*_schema/format methods
@ 2022-02-22 8:47 Wolfgang Bumiller
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
0 siblings, 2 replies; 3+ messages in thread
From: Wolfgang Bumiller @ 2022-02-22 8:47 UTC (permalink / raw)
To: pbs-devel
'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
^ permalink raw reply [flat|nested] 3+ messages in thread
* [pbs-devel] [PATCH backup] constify schema usage and dedup some code
2022-02-22 8:47 [pbs-devel] [PATCH proxmox] schema: add const fn unwrap_*_schema/format methods Wolfgang Bumiller
@ 2022-02-22 8:47 ` Wolfgang Bumiller
2022-02-23 8:31 ` [pbs-devel] [PATCH proxmox] schema: add const fn unwrap_*_schema/format methods Thomas Lamprecht
1 sibling, 0 replies; 3+ messages in thread
From: Wolfgang Bumiller @ 2022-02-22 8:47 UTC (permalink / raw)
To: pbs-devel
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
pbs-config/src/acl.rs | 12 ++---
pbs-config/src/datastore.rs | 12 ++---
pbs-config/src/domains.rs | 12 ++---
pbs-config/src/drive.rs | 23 +++-----
pbs-config/src/media_pool.rs | 7 +--
pbs-config/src/remote.rs | 9 ++--
pbs-config/src/sync.rs | 11 ++--
pbs-config/src/tape_job.rs | 12 ++---
pbs-config/src/traffic_control.rs | 10 ++--
pbs-config/src/user.rs | 16 +++---
pbs-config/src/verify.rs | 10 ++--
src/config/acme/plugin.rs | 16 +++---
src/tools/systemd/config.rs | 88 +++++++++----------------------
13 files changed, 83 insertions(+), 155 deletions(-)
diff --git a/pbs-config/src/acl.rs b/pbs-config/src/acl.rs
index 13af45a9..28f0f686 100644
--- a/pbs-config/src/acl.rs
+++ b/pbs-config/src/acl.rs
@@ -8,7 +8,7 @@ use anyhow::{bail, Error};
use lazy_static::lazy_static;
-use proxmox_schema::{ApiStringFormat, ApiType, Schema, StringSchema};
+use proxmox_schema::ApiType;
use pbs_api_types::{Authid, Userid, Role, ROLE_NAME_NO_ACCESS};
@@ -20,12 +20,12 @@ lazy_static! {
pub static ref ROLE_NAMES: HashMap<&'static str, (u64, &'static str)> = {
let mut map = HashMap::new();
- let list = match Role::API_SCHEMA {
- Schema::String(StringSchema { format: Some(ApiStringFormat::Enum(list)), .. }) => list,
- _ => unreachable!(),
- };
+ const ROLE_SCHEMA_ENUM_LIST: &'static [proxmox_schema::EnumEntry] = Role::API_SCHEMA
+ .unwrap_string_schema()
+ .unwrap_format()
+ .unwrap_enum_format();
- for entry in list.iter() {
+ for entry in ROLE_SCHEMA_ENUM_LIST {
let privs: u64 = Role::from_str(entry.value).unwrap() as u64;
map.insert(entry.value, (privs, entry.description));
}
diff --git a/pbs-config/src/datastore.rs b/pbs-config/src/datastore.rs
index 12071a9f..dc56e0c3 100644
--- a/pbs-config/src/datastore.rs
+++ b/pbs-config/src/datastore.rs
@@ -2,7 +2,7 @@ use anyhow::{Error};
use lazy_static::lazy_static;
use std::collections::HashMap;
-use proxmox_schema::{ApiType, Schema};
+use proxmox_schema::ApiType;
use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{DataStoreConfig, DATASTORE_SCHEMA};
@@ -14,12 +14,10 @@ lazy_static! {
}
fn init() -> SectionConfig {
- let obj_schema = match DataStoreConfig::API_SCHEMA {
- Schema::Object(ref obj_schema) => obj_schema,
- _ => unreachable!(),
- };
-
- let plugin = SectionConfigPlugin::new("datastore".to_string(), Some(String::from("name")), obj_schema);
+ const OBJ_SCHEMA: &proxmox_schema::ObjectSchema =
+ DataStoreConfig::API_SCHEMA.unwrap_object_schema();
+ let plugin =
+ SectionConfigPlugin::new("datastore".to_string(), Some(String::from("name")), OBJ_SCHEMA);
let mut config = SectionConfig::new(&DATASTORE_SCHEMA);
config.register_plugin(plugin);
diff --git a/pbs-config/src/domains.rs b/pbs-config/src/domains.rs
index 90a83bc6..12a58048 100644
--- a/pbs-config/src/domains.rs
+++ b/pbs-config/src/domains.rs
@@ -3,7 +3,7 @@ use std::collections::HashMap;
use anyhow::{Error};
use lazy_static::lazy_static;
-use proxmox_schema::{ApiType, Schema};
+use proxmox_schema::ApiType;
use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{OpenIdRealmConfig, REALM_ID_SCHEMA};
@@ -15,12 +15,10 @@ lazy_static! {
fn init() -> SectionConfig {
- let obj_schema = match OpenIdRealmConfig::API_SCHEMA {
- Schema::Object(ref obj_schema) => obj_schema,
- _ => unreachable!(),
- };
-
- let plugin = SectionConfigPlugin::new("openid".to_string(), Some(String::from("realm")), obj_schema);
+ const OBJ_SCHEMA: &proxmox_schema::ObjectSchema =
+ OpenIdRealmConfig::API_SCHEMA.unwrap_object_schema();
+ let plugin =
+ SectionConfigPlugin::new("openid".to_string(), Some(String::from("realm")), OBJ_SCHEMA);
let mut config = SectionConfig::new(&REALM_ID_SCHEMA);
config.register_plugin(plugin);
diff --git a/pbs-config/src/drive.rs b/pbs-config/src/drive.rs
index 13be8841..66aa3c78 100644
--- a/pbs-config/src/drive.rs
+++ b/pbs-config/src/drive.rs
@@ -35,25 +35,18 @@ lazy_static! {
fn init() -> SectionConfig {
let mut config = SectionConfig::new(&DRIVE_NAME_SCHEMA);
- let obj_schema = match VirtualTapeDrive::API_SCHEMA {
- Schema::Object(ref obj_schema) => obj_schema,
- _ => unreachable!(),
- };
- let plugin = SectionConfigPlugin::new("virtual".to_string(), Some("name".to_string()), obj_schema);
+ const VIRT_SCHEMA: &ObjectSchema = VirtualTapeDrive::API_SCHEMA.unwrap_object_schema();
+ let plugin =
+ SectionConfigPlugin::new("virtual".to_string(), Some("name".to_string()), VIRT_SCHEMA);
config.register_plugin(plugin);
- let obj_schema = match LtoTapeDrive::API_SCHEMA {
- Schema::Object(ref obj_schema) => obj_schema,
- _ => unreachable!(),
- };
- let plugin = SectionConfigPlugin::new("lto".to_string(), Some("name".to_string()), obj_schema);
+ const LTO_SCHEMA: &ObjectSchema = LtoTapeDrive::API_SCHEMA.unwrap_object_schema();
+ let plugin = SectionConfigPlugin::new("lto".to_string(), Some("name".to_string()), LTO_SCHEMA);
config.register_plugin(plugin);
- let obj_schema = match ScsiTapeChanger::API_SCHEMA {
- Schema::Object(ref obj_schema) => obj_schema,
- _ => unreachable!(),
- };
- let plugin = SectionConfigPlugin::new("changer".to_string(), Some("name".to_string()), obj_schema);
+ const CHANGER_SCHEMA: &ObjectSchema = ScsiTapeChanger::API_SCHEMA.unwrap_object_schema();
+ let plugin =
+ SectionConfigPlugin::new("changer".to_string(), Some("name".to_string()), CHANGER_SCHEMA);
config.register_plugin(plugin);
config
}
diff --git a/pbs-config/src/media_pool.rs b/pbs-config/src/media_pool.rs
index 35a2924e..40403d27 100644
--- a/pbs-config/src/media_pool.rs
+++ b/pbs-config/src/media_pool.rs
@@ -26,11 +26,8 @@ lazy_static! {
fn init() -> SectionConfig {
let mut config = SectionConfig::new(&MEDIA_POOL_NAME_SCHEMA);
- let obj_schema = match MediaPoolConfig::API_SCHEMA {
- Schema::Object(ref obj_schema) => obj_schema,
- _ => unreachable!(),
- };
- let plugin = SectionConfigPlugin::new("pool".to_string(), Some("name".to_string()), obj_schema);
+ const OBJ_SCHEMA: &ObjectSchema = MediaPoolConfig::API_SCHEMA.unwrap_object_schema();
+ let plugin = SectionConfigPlugin::new("pool".to_string(), Some("name".to_string()), OBJ_SCHEMA);
config.register_plugin(plugin);
config
diff --git a/pbs-config/src/remote.rs b/pbs-config/src/remote.rs
index 921410e2..81da3574 100644
--- a/pbs-config/src/remote.rs
+++ b/pbs-config/src/remote.rs
@@ -15,12 +15,9 @@ lazy_static! {
}
fn init() -> SectionConfig {
- let obj_schema = match Remote::API_SCHEMA {
- Schema::AllOf(ref allof_schema) => allof_schema,
- _ => unreachable!(),
- };
-
- let plugin = SectionConfigPlugin::new("remote".to_string(), Some("name".to_string()), obj_schema);
+ const OBJ_SCHEMA: &proxmox_schema::AllOfSchema = Remote::API_SCHEMA.unwrap_all_of_schema();
+ let plugin =
+ SectionConfigPlugin::new("remote".to_string(), Some("name".to_string()), OBJ_SCHEMA);
let mut config = SectionConfig::new(&REMOTE_ID_SCHEMA);
config.register_plugin(plugin);
diff --git a/pbs-config/src/sync.rs b/pbs-config/src/sync.rs
index f515613f..a9e137b6 100644
--- a/pbs-config/src/sync.rs
+++ b/pbs-config/src/sync.rs
@@ -3,7 +3,7 @@ use std::collections::HashMap;
use anyhow::Error;
use lazy_static::lazy_static;
-use proxmox_schema::{ApiType, Schema};
+use proxmox_schema::ApiType;
use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{JOB_ID_SCHEMA, SyncJobConfig};
@@ -16,12 +16,9 @@ lazy_static! {
fn init() -> SectionConfig {
- let obj_schema = match SyncJobConfig::API_SCHEMA {
- Schema::AllOf(ref allof_schema) => allof_schema,
- _ => unreachable!(),
- };
-
- let plugin = SectionConfigPlugin::new("sync".to_string(), Some(String::from("id")), obj_schema);
+ const OBJ_SCHEMA: &proxmox_schema::AllOfSchema =
+ SyncJobConfig::API_SCHEMA.unwrap_all_of_schema();
+ let plugin = SectionConfigPlugin::new("sync".to_string(), Some(String::from("id")), OBJ_SCHEMA);
let mut config = SectionConfig::new(&JOB_ID_SCHEMA);
config.register_plugin(plugin);
diff --git a/pbs-config/src/tape_job.rs b/pbs-config/src/tape_job.rs
index 992d4382..f208f7a1 100644
--- a/pbs-config/src/tape_job.rs
+++ b/pbs-config/src/tape_job.rs
@@ -2,7 +2,7 @@ use anyhow::{Error};
use lazy_static::lazy_static;
use std::collections::HashMap;
-use proxmox_schema::{Schema, ApiType};
+use proxmox_schema::ApiType;
use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{TapeBackupJobConfig, JOB_ID_SCHEMA};
@@ -14,12 +14,10 @@ lazy_static! {
}
fn init() -> SectionConfig {
- let obj_schema = match TapeBackupJobConfig::API_SCHEMA {
- Schema::AllOf(ref allof_schema) => allof_schema,
- _ => unreachable!(),
- };
-
- let plugin = SectionConfigPlugin::new("backup".to_string(), Some(String::from("id")), obj_schema);
+ const OBJ_SCHEMA: &proxmox_schema::AllOfSchema =
+ TapeBackupJobConfig::API_SCHEMA.unwrap_all_of_schema();
+ let plugin =
+ SectionConfigPlugin::new("backup".to_string(), Some(String::from("id")), OBJ_SCHEMA);
let mut config = SectionConfig::new(&JOB_ID_SCHEMA);
config.register_plugin(plugin);
diff --git a/pbs-config/src/traffic_control.rs b/pbs-config/src/traffic_control.rs
index 860d0fb7..98b6a544 100644
--- a/pbs-config/src/traffic_control.rs
+++ b/pbs-config/src/traffic_control.rs
@@ -4,7 +4,7 @@ use std::collections::HashMap;
use anyhow::Error;
use lazy_static::lazy_static;
-use proxmox_schema::{ApiType, Schema};
+use proxmox_schema::ApiType;
use pbs_api_types::{TrafficControlRule, TRAFFIC_CONTROL_ID_SCHEMA};
@@ -21,11 +21,9 @@ lazy_static! {
fn init() -> SectionConfig {
let mut config = SectionConfig::new(&TRAFFIC_CONTROL_ID_SCHEMA);
- let obj_schema = match TrafficControlRule::API_SCHEMA {
- Schema::AllOf(ref allof_schema) => allof_schema,
- _ => unreachable!(),
- };
- let plugin = SectionConfigPlugin::new("rule".to_string(), Some("name".to_string()), obj_schema);
+ const OBJ_SCHEMA: &proxmox_schema::AllOfSchema =
+ TrafficControlRule::API_SCHEMA.unwrap_all_of_schema();
+ let plugin = SectionConfigPlugin::new("rule".to_string(), Some("name".to_string()), OBJ_SCHEMA);
config.register_plugin(plugin);
config
diff --git a/pbs-config/src/user.rs b/pbs-config/src/user.rs
index f62d45db..a69865a9 100644
--- a/pbs-config/src/user.rs
+++ b/pbs-config/src/user.rs
@@ -22,18 +22,14 @@ lazy_static! {
fn init() -> SectionConfig {
let mut config = SectionConfig::new(&Authid::API_SCHEMA);
- let user_schema = match User::API_SCHEMA {
- Schema::Object(ref user_schema) => user_schema,
- _ => unreachable!(),
- };
- let user_plugin = SectionConfigPlugin::new("user".to_string(), Some("userid".to_string()), user_schema);
+ const USER_SCHEMA: &ObjectSchema = User::API_SCHEMA.unwrap_object_schema();
+ let user_plugin =
+ SectionConfigPlugin::new("user".to_string(), Some("userid".to_string()), USER_SCHEMA);
config.register_plugin(user_plugin);
- let token_schema = match ApiToken::API_SCHEMA {
- Schema::Object(ref token_schema) => token_schema,
- _ => unreachable!(),
- };
- let token_plugin = SectionConfigPlugin::new("token".to_string(), Some("tokenid".to_string()), token_schema);
+ const TOKEN_SCHEMA: &ObjectSchema = ApiToken::API_SCHEMA.unwrap_object_schema();
+ let token_plugin =
+ SectionConfigPlugin::new("token".to_string(), Some("tokenid".to_string()), TOKEN_SCHEMA);
config.register_plugin(token_plugin);
config
diff --git a/pbs-config/src/verify.rs b/pbs-config/src/verify.rs
index b6c70caa..efe22996 100644
--- a/pbs-config/src/verify.rs
+++ b/pbs-config/src/verify.rs
@@ -15,12 +15,10 @@ lazy_static! {
}
fn init() -> SectionConfig {
- let obj_schema = match VerificationJobConfig::API_SCHEMA {
- Schema::Object(ref obj_schema) => obj_schema,
- _ => unreachable!(),
- };
-
- let plugin = SectionConfigPlugin::new("verification".to_string(), Some(String::from("id")), obj_schema);
+ const OBJ_SCHEMA: &proxmox_schema::ObjectSchema =
+ VerificationJobConfig::API_SCHEMA.unwrap_object_schema();
+ let plugin =
+ SectionConfigPlugin::new("verification".to_string(), Some(String::from("id")), OBJ_SCHEMA);
let mut config = SectionConfig::new(&JOB_ID_SCHEMA);
config.register_plugin(plugin);
diff --git a/src/config/acme/plugin.rs b/src/config/acme/plugin.rs
index 5decc154..1788267f 100644
--- a/src/config/acme/plugin.rs
+++ b/src/config/acme/plugin.rs
@@ -107,25 +107,21 @@ impl DnsPlugin {
fn init() -> SectionConfig {
let mut config = SectionConfig::new(&PLUGIN_ID_SCHEMA);
- let standalone_schema = match &StandalonePlugin::API_SCHEMA {
- Schema::Object(schema) => schema,
- _ => unreachable!(),
- };
+ const STANDALONE_SCHEMA: &proxmox_schema::ObjectSchema =
+ StandalonePlugin::API_SCHEMA.unwrap_object_schema();
let standalone_plugin = SectionConfigPlugin::new(
"standalone".to_string(),
Some("id".to_string()),
- standalone_schema,
+ STANDALONE_SCHEMA,
);
config.register_plugin(standalone_plugin);
- let dns_challenge_schema = match DnsPlugin::API_SCHEMA {
- Schema::AllOf(ref schema) => schema,
- _ => unreachable!(),
- };
+ const DNS_CHALLENGE_SCHEMA: &proxmox_schema::AllOfSchema =
+ DnsPlugin::API_SCHEMA.unwrap_all_of_schema();
let dns_challenge_plugin = SectionConfigPlugin::new(
"dns".to_string(),
Some("id".to_string()),
- dns_challenge_schema,
+ DNS_CHALLENGE_SCHEMA,
);
config.register_plugin(dns_challenge_plugin);
diff --git a/src/tools/systemd/config.rs b/src/tools/systemd/config.rs
index 95c1a942..8dae1bf5 100644
--- a/src/tools/systemd/config.rs
+++ b/src/tools/systemd/config.rs
@@ -15,31 +15,25 @@ lazy_static! {
pub static ref MOUNT_CONFIG: SectionConfig = init_mount();
}
+fn register_unit_section(config: &mut SectionConfig) {
+ const UNIT_SCHEMA: &ObjectSchema = SystemdUnitSection::API_SCHEMA.unwrap_object_schema();
+ config.register_plugin(SectionConfigPlugin::new("Unit".to_string(), None, UNIT_SCHEMA));
+}
+
+fn register_install_section(config: &mut SectionConfig) {
+ const INSTALL_SCHEMA: &ObjectSchema = SystemdInstallSection::API_SCHEMA.unwrap_object_schema();
+ config.register_plugin(SectionConfigPlugin::new("Install".to_string(), None, INSTALL_SCHEMA));
+}
+
fn init_service() -> SectionConfig {
let mut config = SectionConfig::with_systemd_syntax(&SYSTEMD_SECTION_NAME_SCHEMA);
- match SystemdUnitSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Unit".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
- match SystemdInstallSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Install".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
- match SystemdServiceSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Service".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
+ register_unit_section(&mut config);
+ register_install_section(&mut config);
+
+ const SERVICE_SCHEMA: &ObjectSchema = SystemdServiceSection::API_SCHEMA.unwrap_object_schema();
+ config.register_plugin(SectionConfigPlugin::new("Service".to_string(), None, SERVICE_SCHEMA));
config
}
@@ -48,27 +42,11 @@ fn init_timer() -> SectionConfig {
let mut config = SectionConfig::with_systemd_syntax(&SYSTEMD_SECTION_NAME_SCHEMA);
- match SystemdUnitSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Unit".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
- match SystemdInstallSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Install".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
- match SystemdTimerSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Timer".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
+ register_unit_section(&mut config);
+ register_install_section(&mut config);
+
+ const TIMER_SCHEMA: &ObjectSchema = SystemdTimerSection::API_SCHEMA.unwrap_object_schema();
+ config.register_plugin(SectionConfigPlugin::new("Timer".to_string(), None, TIMER_SCHEMA));
config
}
@@ -77,27 +55,11 @@ fn init_mount() -> SectionConfig {
let mut config = SectionConfig::with_systemd_syntax(&SYSTEMD_SECTION_NAME_SCHEMA);
- match SystemdUnitSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Unit".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
- match SystemdInstallSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Install".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
- match SystemdMountSection::API_SCHEMA {
- Schema::Object(ref obj_schema) => {
- let plugin = SectionConfigPlugin::new("Mount".to_string(), None, obj_schema);
- config.register_plugin(plugin);
- }
- _ => unreachable!(),
- };
+ register_unit_section(&mut config);
+ register_install_section(&mut config);
+
+ const MOUNT_SCHEMA: &ObjectSchema = SystemdMountSection::API_SCHEMA.unwrap_object_schema();
+ config.register_plugin(SectionConfigPlugin::new("Mount".to_string(), None, MOUNT_SCHEMA));
config
}
--
2.30.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [pbs-devel] [PATCH proxmox] schema: add const fn unwrap_*_schema/format methods
2022-02-22 8:47 [pbs-devel] [PATCH proxmox] schema: add const fn unwrap_*_schema/format methods Wolfgang Bumiller
2022-02-22 8:47 ` [pbs-devel] [PATCH backup] constify schema usage and dedup some code Wolfgang Bumiller
@ 2022-02-23 8:31 ` Thomas Lamprecht
1 sibling, 0 replies; 3+ messages in thread
From: Thomas Lamprecht @ 2022-02-23 8:31 UTC (permalink / raw)
To: Proxmox Backup Server development discussion, Wolfgang Bumiller
On 22.02.22 09:47, Wolfgang Bumiller wrote:
> '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 ;-) )
>
IMO the usage gets nicer, lots of removal of unreachable!(), and even if
not used correctly (without const) we're as good as now; so can only win.
If there's no objection from others I'd say: go for it.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-02-23 8:31 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-22 8:47 [pbs-devel] [PATCH proxmox] schema: add const fn unwrap_*_schema/format methods Wolfgang Bumiller
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox