[pve-devel] [PATCH v2 proxmox master stable-2 1/2] apt: repos: extend `DebianCodename` by `Unknown` variant

Christian Ebner c.ebner at proxmox.com
Tue Feb 6 10:51:00 CET 2024


Instead of returning an Option for the DebianCodename variant, with None
for unknowns, extend the enum by an Unknown variant with additional
internal type to avoid misuse of this variant.

Co-authored-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
---
Changes since v1:
- Fixed incorrect refactoring of codename matching
- s/Codename/DebianCodename/ in commit title and message\
- fixed warning for DebianCodename Display::fmt implementation by
  removing unused variable binding.

 proxmox-apt/src/repositories/file.rs    |  2 +-
 proxmox-apt/src/repositories/release.rs | 61 +++++++++++++++----------
 2 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/proxmox-apt/src/repositories/file.rs b/proxmox-apt/src/repositories/file.rs
index b4c6b08..bce7271 100644
--- a/proxmox-apt/src/repositories/file.rs
+++ b/proxmox-apt/src/repositories/file.rs
@@ -405,7 +405,7 @@ impl APTRepositoryFile {
                     add_info("warning", message_old(base_suite));
                 }
 
-                if Some(codename) == current_codename.next() {
+                if codename == current_codename.next() {
                     add_info("ignore-pre-upgrade-warning", message_new(base_suite));
                 } else if codename > current_codename {
                     add_info("warning", message_new(base_suite));
diff --git a/proxmox-apt/src/repositories/release.rs b/proxmox-apt/src/repositories/release.rs
index da391e5..43c9746 100644
--- a/proxmox-apt/src/repositories/release.rs
+++ b/proxmox-apt/src/repositories/release.rs
@@ -3,8 +3,17 @@ use std::io::{BufRead, BufReader};
 
 use anyhow::{bail, format_err, Error};
 
+mod private {
+    // public types in private modules are unnamable by external users, this is similar to the
+    // "sealed trait" pattern
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+    pub struct Internal;
+}
+use private::Internal;
+
 /// The code names of Debian releases. Does not include `sid`.
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[repr(u8)]
 pub enum DebianCodename {
     Lenny = 5,
     Squeeze,
@@ -15,13 +24,37 @@ pub enum DebianCodename {
     Bullseye,
     Bookworm,
     Trixie,
+    Unknown(u8, Internal),
 }
 
 impl DebianCodename {
-    pub fn next(&self) -> Option<Self> {
-        match (*self as u8 + 1).try_into() {
-            Ok(codename) => Some(codename),
-            Err(_) => None,
+    pub fn value(&self) -> u8 {
+        match self {
+            Self::Unknown(number, _) => *number,
+            // see 'arbitrary_enum_discriminant' feature for why this is safe:
+            // https://rust-lang.github.io/rfcs/2363-arbitrary-enum-discriminant.html
+            other => unsafe { *(other as *const Self as *const u8) },
+        }
+    }
+
+    pub fn next(&self) -> Self {
+        (self.value() + 1).into()
+    }
+}
+
+impl From<u8> for DebianCodename {
+    fn from(number: u8) -> Self {
+        match number {
+            5 => Self::Lenny,
+            6 => Self::Squeeze,
+            7 => Self::Wheezy,
+            8 => Self::Jessie,
+            9 => Self::Stretch,
+            10 => Self::Buster,
+            11 => Self::Bullseye,
+            12 => Self::Bookworm,
+            13 => Self::Trixie,
+            number => Self::Unknown(number, Internal),
         }
     }
 }
@@ -45,25 +78,6 @@ impl TryFrom<&str> for DebianCodename {
     }
 }
 
-impl TryFrom<u8> for DebianCodename {
-    type Error = Error;
-
-    fn try_from(number: u8) -> Result<Self, Error> {
-        match number {
-            5 => Ok(DebianCodename::Lenny),
-            6 => Ok(DebianCodename::Squeeze),
-            7 => Ok(DebianCodename::Wheezy),
-            8 => Ok(DebianCodename::Jessie),
-            9 => Ok(DebianCodename::Stretch),
-            10 => Ok(DebianCodename::Buster),
-            11 => Ok(DebianCodename::Bullseye),
-            12 => Ok(DebianCodename::Bookworm),
-            13 => Ok(DebianCodename::Trixie),
-            _ => bail!("unknown Debian release number '{}'", number),
-        }
-    }
-}
-
 impl Display for DebianCodename {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
@@ -76,6 +90,7 @@ impl Display for DebianCodename {
             DebianCodename::Bullseye => write!(f, "bullseye"),
             DebianCodename::Bookworm => write!(f, "bookworm"),
             DebianCodename::Trixie => write!(f, "trixie"),
+            DebianCodename::Unknown(_, _) => write!(f, "unknown"),
         }
     }
 }
-- 
2.30.2





More information about the pve-devel mailing list