use std::borrow::Borrow; use std::path::Path; use serde::{Deserialize, Deserializer, Serialize}; use crate::{Id, IdUnchecked}; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum VolumeId = String> { Backup, Custom(Id), } impl> std::fmt::Display for VolumeId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { VolumeId::Backup => write!(f, "BACKUP"), VolumeId::Custom(id) => write!(f, "{}", id), } } } impl> AsRef for VolumeId { fn as_ref(&self) -> &str { match self { VolumeId::Backup => "BACKUP", VolumeId::Custom(id) => id.as_ref(), } } } impl> Borrow for VolumeId { fn borrow(&self) -> &str { self.as_ref() } } impl> AsRef for VolumeId { fn as_ref(&self) -> &Path { AsRef::::as_ref(self).as_ref() } } impl<'de, S> Deserialize<'de> for VolumeId where S: AsRef, IdUnchecked: Deserialize<'de>, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let unchecked: IdUnchecked = Deserialize::deserialize(deserializer)?; Ok(match unchecked.0.as_ref() { "BACKUP" => VolumeId::Backup, _ => VolumeId::Custom(Id::try_from(unchecked.0).map_err(serde::de::Error::custom)?), }) } } impl> Serialize for VolumeId { fn serialize(&self, serializer: Ser) -> Result where Ser: serde::Serializer, { serializer.serialize_str(self.as_ref()) } }