From 7e21bc648346d494785e35f26d9416698a566125 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 6 Jul 2023 05:15:25 -0400 Subject: [PATCH] container: Add an API to serialize `Transport` This will fix the need demonstrated by https://github.com/containers/bootc/pull/106/files#diff-c163debeb7fdf9b238e5c589e0000c80684ca9a09abd408242df4bad489626a6R38 We made a historical mistake here in having our `Display` include the `:`...but it's hard to deal with because inherently the format is messy because of the `://` in `docker://`. --- lib/src/container/mod.rs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/src/container/mod.rs b/lib/src/container/mod.rs index 239d7529..a0d4491e 100644 --- a/lib/src/container/mod.rs +++ b/lib/src/container/mod.rs @@ -100,15 +100,32 @@ impl TryFrom<&str> for Transport { fn try_from(value: &str) -> Result { Ok(match value { - "registry" | "docker" => Self::Registry, - "oci" => Self::OciDir, - "oci-archive" => Self::OciArchive, - "containers-storage" => Self::ContainerStorage, + Self::REGISTRY_STR | "docker" => Self::Registry, + Self::OCI_STR => Self::OciDir, + Self::OCI_ARCHIVE_STR => Self::OciArchive, + Self::CONTAINERS_STORAGE_STR => Self::ContainerStorage, o => return Err(anyhow!("Unknown transport '{}'", o)), }) } } +impl Transport { + const OCI_STR: &str = "oci"; + const OCI_ARCHIVE_STR: &str = "oci-archive"; + const CONTAINERS_STORAGE_STR: &str = "containers-storage"; + const REGISTRY_STR: &str = "registry"; + + /// Retrieve an identifier that can then be re-parsed from [`Transport::try_from::<&str>`]. + pub fn serializable_name(&self) -> &'static str { + match self { + Transport::Registry => Self::REGISTRY_STR, + Transport::OciDir => Self::OCI_STR, + Transport::OciArchive => Self::OCI_ARCHIVE_STR, + Transport::ContainerStorage => Self::CONTAINERS_STORAGE_STR, + } + } +} + impl TryFrom<&str> for ImageReference { type Error = anyhow::Error; @@ -428,6 +445,18 @@ mod tests { use super::*; + #[test] + fn test_serializable_transport() { + for v in [ + Transport::Registry, + Transport::ContainerStorage, + Transport::OciArchive, + Transport::OciDir, + ] { + assert_eq!(Transport::try_from(v.serializable_name()).unwrap(), v); + } + } + const INVALID_IRS: &[&str] = &["", "foo://", "docker:blah", "registry:", "foo:bar"]; const VALID_IRS: &[&str] = &[ "containers-storage:localhost/someimage",