use crate::error::{Error, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ApiVersion(u32);
pub const SUPPORTED_API: &[ApiVersion] = &[ApiVersion(1)];
impl ApiVersion {
pub fn supported(version: u32) -> Result<Self> {
let candidate = Self(version);
if SUPPORTED_API.contains(&candidate) {
Ok(candidate)
} else {
Err(Error::UnsupportedApi {
requested: version,
supported: SUPPORTED_API.iter().map(|v| v.0).collect(),
})
}
}
#[must_use]
pub const fn get(self) -> u32 {
self.0
}
}
impl core::fmt::Display for ApiVersion {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.0)
}
}
#[cfg(test)]
mod tests {
#![expect(
clippy::unwrap_used,
reason = "tests unwrap known-valid fixtures; a panic is the intended failure signal"
)]
use super::{ApiVersion, SUPPORTED_API};
#[test]
fn version_one_is_supported() {
assert_eq!(ApiVersion::supported(1).unwrap().get(), 1);
}
#[test]
fn an_unknown_version_is_refused_and_the_message_lists_the_supported_set() {
let err = ApiVersion::supported(99).unwrap_err();
assert!(err.to_string().contains("supports api 1"), "{err}");
}
#[test]
fn the_supported_set_is_never_empty() {
assert!(!SUPPORTED_API.is_empty());
}
}