#[derive(Debug, Clone)] pub struct Version { value: semver::Version, } #[derive(Debug, Clone)] pub struct VersionError { msg: String, } impl From for VersionError { fn from(value: semver::Error) -> Self { Self { msg: value.to_string(), } } } impl Version { pub fn from(val: &str) -> Result { Ok(Self { value: semver::Version::parse(val)?, }) } } impl<'de> serde::Deserialize<'de> for Version { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { let s = String::deserialize(deserializer)?; semver::Version::parse(&s) .map(|value| Version { value }) .map_err(serde::de::Error::custom) } } impl serde::Serialize for Version { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { self.value.to_string().serialize(serializer) } } impl std::fmt::Display for Version { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { return self.value.fmt(f); } } #[cfg(test)] mod test { use super::*; #[test] fn version_serialize_deserialize() { let v = "10.0.1331-ababa+b123"; let version = Version { value: semver::Version::parse(v).unwrap(), }; let s = serde_json::to_string(&version).unwrap(); let version2: Version = serde_json::from_str(&s).unwrap(); assert_eq!(version2.value.major, 10); assert_eq!(version2.value.minor, 0); assert_eq!(version2.value.patch, 1331); assert_eq!(version2.value.build.to_string(), "b123"); assert_eq!(version2.value.pre.to_string(), "ababa"); assert_eq!(version2.value.to_string(), v); } }