use std::fmt;
pub const APPLICATION_ID_GPKG: u32 = 0x4750_4B47;
pub const APPLICATION_ID_GP10: u32 = 0x4750_3130;
pub const APPLICATION_ID_GP11: u32 = 0x4750_3131;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[non_exhaustive]
pub enum GpkgVersion {
V1_0,
V1_1,
V1_2,
V1_3,
V1_4,
}
impl GpkgVersion {
pub fn from_pragmas(application_id: u32, user_version: u32) -> Option<Self> {
match application_id {
APPLICATION_ID_GP10 => Some(Self::V1_0),
APPLICATION_ID_GP11 => Some(Self::V1_1),
APPLICATION_ID_GPKG => match user_version / 100 {
102 => Some(Self::V1_2),
103 => Some(Self::V1_3),
v if v >= 104 => Some(Self::V1_4),
_ => None,
},
_ => None,
}
}
pub fn user_version(self) -> Option<u32> {
match self {
Self::V1_0 | Self::V1_1 => None,
Self::V1_2 => Some(10200),
Self::V1_3 => Some(10300),
Self::V1_4 => Some(10400),
}
}
pub fn as_str(self) -> &'static str {
match self {
Self::V1_0 => "1.0",
Self::V1_1 => "1.1",
Self::V1_2 => "1.2",
Self::V1_3 => "1.3",
Self::V1_4 => "1.4",
}
}
}
impl fmt::Display for GpkgVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn classification() {
assert_eq!(
GpkgVersion::from_pragmas(APPLICATION_ID_GPKG, 10400),
Some(GpkgVersion::V1_4)
);
assert_eq!(
GpkgVersion::from_pragmas(APPLICATION_ID_GPKG, 10201),
Some(GpkgVersion::V1_2)
);
assert_eq!(
GpkgVersion::from_pragmas(APPLICATION_ID_GPKG, 10500),
Some(GpkgVersion::V1_4)
);
assert_eq!(
GpkgVersion::from_pragmas(APPLICATION_ID_GP10, 0),
Some(GpkgVersion::V1_0)
);
assert_eq!(GpkgVersion::from_pragmas(0x1234_5678, 10400), None);
assert_eq!(GpkgVersion::from_pragmas(APPLICATION_ID_GPKG, 0), None);
}
}