diff --git a/nvx-rs/src/host/sandbox/mount.rs b/nvx-rs/src/host/sandbox/mount.rs index c90e30184..5ec97f304 100644 --- a/nvx-rs/src/host/sandbox/mount.rs +++ b/nvx-rs/src/host/sandbox/mount.rs @@ -77,14 +77,12 @@ impl MountAccess { /// /// Fails with [`ErrorKind::Unsupported`](crate::ErrorKind::Unsupported) for another name. pub fn from_name(name: &str) -> Result { - match name { - "ro" => Ok(Self::ReadOnly), - "rw" => Ok(Self::ReadWrite), - _ => Err(refused(format!( - "unsupported sandbox mount mode {}; choose ro or rw", - repr(name) - ))), - } + setting_from_name( + "mode", + [Self::ReadOnly, Self::ReadWrite], + Self::as_str, + name, + ) } } @@ -117,14 +115,7 @@ impl MountOwner { /// /// Fails with [`ErrorKind::Unsupported`](crate::ErrorKind::Unsupported) for another name. pub fn from_name(name: &str) -> Result { - match name { - "vmm" => Ok(Self::Vmm), - "caller" => Ok(Self::Caller), - _ => Err(refused(format!( - "unsupported sandbox mount owner {}; choose vmm or caller", - repr(name) - ))), - } + setting_from_name("owner", [Self::Vmm, Self::Caller], Self::as_str, name) } } @@ -157,14 +148,7 @@ impl MountKind { /// /// Fails with [`ErrorKind::Unsupported`](crate::ErrorKind::Unsupported) for another name. pub fn from_name(name: &str) -> Result { - match name { - "directory" => Ok(Self::Directory), - "file" => Ok(Self::File), - _ => Err(refused(format!( - "unsupported sandbox mount kind {}; choose directory or file", - repr(name) - ))), - } + setting_from_name("kind", [Self::Directory, Self::File], Self::as_str, name) } } @@ -174,6 +158,29 @@ impl fmt::Display for MountKind { } } +/// Returns the one of `values`, the two values of a share's `setting`, whose name, as `as_str` +/// gives it, is `name`, as a recorded share gives it. +/// +/// Fails with [`ErrorKind::Unsupported`](crate::ErrorKind::Unsupported) for another name, with a +/// message that names the setting and its two values. +fn setting_from_name( + setting: &str, + values: [T; 2], + as_str: fn(T) -> &'static str, + name: &str, +) -> Result { + values + .into_iter() + .find(|&value| as_str(value) == name) + .ok_or_else(|| { + let [first, second] = values.map(as_str); + refused(format!( + "unsupported sandbox mount {setting} {}; choose {first} or {second}", + repr(name) + )) + }) +} + /// A kind of access-policy path. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum PolicyKind {