use crate::{CURRENT_MAJOR_VERSION, CURRENT_MINOR_VERSION};
use serde::{Deserialize, Serialize, de::Visitor};
#[derive(Clone, Copy, Debug)]
pub struct SemVer(pub u32, pub u32);
impl SemVer {
pub fn major(&self) -> u32 {
self.0
}
pub fn minor(&self) -> u32 {
self.1
}
pub fn to_string(&self) -> String {
format!("{}.{}", self.0, self.1)
}
}
impl Default for SemVer {
fn default() -> Self {
SemVer(CURRENT_MAJOR_VERSION, CURRENT_MINOR_VERSION)
}
}
impl Serialize for SemVer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&format!("{}.{}", self.0, self.1))
}
}
impl<'de> Deserialize<'de> for SemVer {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_str(SemVerVisitor)
}
}
struct SemVerVisitor;
impl<'de> Visitor<'de> for SemVerVisitor {
type Value = SemVer;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str(
"a string of the form \"MAJOR.MINOR\" where MAJOR and MINOR are non-negative integers",
)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let split_results: Vec<_> = v.split(".").map(|s| s.parse::<u32>()).collect();
let mut version_components: [u32; 2] = [0, 0];
for (i, result) in split_results.iter().enumerate() {
match result {
Ok(value) => {
if i < 2 {
version_components[i] = *value;
}
}
Err(err) => {
return Err(E::custom(err.to_string()));
}
}
}
if split_results.len() > 2 {
return Err(E::custom(format!(
"too many components in format version [{}]; found [{}], but it must be exactly 2",
v,
split_results.len(),
)));
}
if split_results.len() < 2 {
return Err(E::custom(format!(
"not enough components in format version [{}]; found [{}], but it must be exactly 2",
v,
split_results.len(),
)));
}
if version_components[0] > CURRENT_MAJOR_VERSION {
return Err(E::custom(format!(
"major version of input data is [{}], but your version of rmf_site_format only supports up to [{}.{}]; try updating to the latest version of rmf_site_format to read this file",
version_components[0], CURRENT_MAJOR_VERSION, CURRENT_MINOR_VERSION,
)));
}
return Ok(SemVer(version_components[0], version_components[1]));
}
}