use std::str::FromStr;
#[derive(Debug, Clone, PartialEq)]
pub enum ExtensionScope {
ReadWrite,
WriteOnly,
}
impl FromStr for ExtensionScope {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
match s {
"read-write" => Ok(ExtensionScope::ReadWrite),
"write-only" => Ok(ExtensionScope::WriteOnly),
_ => Ok(ExtensionScope::ReadWrite), }
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct GpkgExtension {
pub table_name: Option<String>,
pub column_name: Option<String>,
pub extension_name: String,
pub definition: String,
pub scope: ExtensionScope,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extension_scope_from_str_read_write() {
let scope = "read-write"
.parse::<ExtensionScope>()
.expect("should parse read-write");
assert_eq!(scope, ExtensionScope::ReadWrite);
}
#[test]
fn test_extension_scope_from_str_write_only() {
let scope = "write-only"
.parse::<ExtensionScope>()
.expect("should parse write-only");
assert_eq!(scope, ExtensionScope::WriteOnly);
}
#[test]
fn test_extension_scope_from_str_unknown_defaults_to_read_write() {
let scope = "something-unrecognised"
.parse::<ExtensionScope>()
.expect("unknown scope should fall back to ReadWrite");
assert_eq!(
scope,
ExtensionScope::ReadWrite,
"unknown scope string must default to the conservative ReadWrite variant"
);
}
#[test]
fn test_gpkg_extension_debug_format() {
let ext = GpkgExtension {
table_name: Some("features_table".to_string()),
column_name: Some("geom".to_string()),
extension_name: "gpkg_rtree_index".to_string(),
definition: "http://www.geopackage.org/spec/#extension_rtree".to_string(),
scope: ExtensionScope::ReadWrite,
};
let debug_str = format!("{ext:?}");
assert!(debug_str.contains("gpkg_rtree_index"));
assert!(debug_str.contains("ReadWrite"));
assert!(debug_str.contains("features_table"));
}
#[test]
fn test_gpkg_extension_clone_equality() {
let ext = GpkgExtension {
table_name: None,
column_name: None,
extension_name: "gpkg_webp".to_string(),
definition: "http://www.geopackage.org/spec/#extension_webp".to_string(),
scope: ExtensionScope::ReadWrite,
};
let cloned = ext.clone();
assert_eq!(ext, cloned, "cloned GpkgExtension must equal the original");
}
#[test]
fn test_gpkg_extension_write_only_scope() {
let ext = GpkgExtension {
table_name: Some("metadata_table".to_string()),
column_name: None,
extension_name: "gpkg_metadata".to_string(),
definition: "http://www.geopackage.org/spec/#extension_metadata".to_string(),
scope: ExtensionScope::WriteOnly,
};
assert_eq!(ext.scope, ExtensionScope::WriteOnly);
assert!(ext.table_name.is_some());
assert!(ext.column_name.is_none());
}
#[test]
fn test_extension_scope_exhaustive_known_values() {
let cases: &[(&str, ExtensionScope)] = &[
("read-write", ExtensionScope::ReadWrite),
("write-only", ExtensionScope::WriteOnly),
];
for (s, expected) in cases {
let parsed = s
.parse::<ExtensionScope>()
.expect("known scope string must parse without error");
assert_eq!(
&parsed, expected,
"scope string '{s}' did not round-trip correctly"
);
}
}
}