use std::{
fmt::{Display, Formatter},
str::FromStr,
};
use semver::Version as SemverVersion;
use crate::Error;
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct SchemaVersion(SemverVersion);
impl SchemaVersion {
pub fn new(version: SemverVersion) -> Self {
SchemaVersion(version)
}
pub fn inner(&self) -> &SemverVersion {
&self.0
}
}
impl FromStr for SchemaVersion {
type Err = Error;
fn from_str(s: &str) -> Result<SchemaVersion, Self::Err> {
if !s.contains('.') {
match s.parse() {
Ok(major) => Ok(SchemaVersion(SemverVersion::new(major, 0, 0))),
Err(e) => Err(Error::InvalidInteger { kind: *e.kind() }),
}
} else {
match SemverVersion::parse(s) {
Ok(version) => Ok(SchemaVersion(version)),
Err(e) => Err(Error::InvalidSemver {
kind: e.to_string(),
}),
}
}
}
}
impl Display for SchemaVersion {
fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
write!(fmt, "{}", self.0)
}
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
#[case("1.0.0", Ok(SchemaVersion(SemverVersion::new(1, 0, 0))))]
#[case("1", Ok(SchemaVersion(SemverVersion::new(1, 0, 0))))]
#[case("-1.0.0", Err(Error::InvalidSemver { kind: String::from("unexpected character '-' while parsing major version number") }))]
fn schema_version(#[case] version: &str, #[case] result: Result<SchemaVersion, Error>) {
assert_eq!(result, SchemaVersion::from_str(version))
}
#[rstest]
#[case(
SchemaVersion(SemverVersion::new(1, 0, 0)),
SchemaVersion(SemverVersion::new(0, 1, 0))
)]
fn compare_schema_version(#[case] version_a: SchemaVersion, #[case] version_b: SchemaVersion) {
assert!(version_a > version_b);
}
}