use std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RelationType {
Media,
SimpleAttributes,
RelatedFeatures,
Tiles,
Attributes,
Other(String),
}
impl RelationType {
pub fn as_str(&self) -> &str {
match self {
Self::Media => "media",
Self::SimpleAttributes => "simple_attributes",
Self::RelatedFeatures => "related_features",
Self::Tiles => "tiles",
Self::Attributes => "attributes",
Self::Other(s) => s.as_str(),
}
}
}
impl FromStr for RelationType {
type Err = std::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rt = match s {
"media" => Self::Media,
"simple_attributes" => Self::SimpleAttributes,
"related_features" | "features" => Self::RelatedFeatures,
"tiles" => Self::Tiles,
"attributes" => Self::Attributes,
other => Self::Other(other.to_owned()),
};
Ok(rt)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct GpkgRelation {
pub id: i64,
pub base_table_name: String,
pub base_primary_column: String,
pub related_table_name: String,
pub related_primary_column: String,
pub relation_name: RelationType,
pub mapping_table_name: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MappingRow {
pub id: i64,
pub base_id: i64,
pub related_id: i64,
}
#[cfg(test)]
mod tests {
use super::*;
fn parse(s: &str) -> RelationType {
s.parse().unwrap()
}
#[test]
fn test_relation_type_from_str_known_variants() {
assert_eq!(parse("media"), RelationType::Media);
assert_eq!(parse("simple_attributes"), RelationType::SimpleAttributes);
assert_eq!(parse("related_features"), RelationType::RelatedFeatures);
assert_eq!(parse("features"), RelationType::RelatedFeatures);
assert_eq!(parse("tiles"), RelationType::Tiles);
assert_eq!(parse("attributes"), RelationType::Attributes);
}
#[test]
fn test_relation_type_from_str_other() {
assert_eq!(
parse("custom_relation"),
RelationType::Other("custom_relation".to_owned())
);
assert_eq!(parse(""), RelationType::Other(String::new()));
}
#[test]
fn test_relation_type_as_str_roundtrip() {
let cases = [
("media", RelationType::Media),
("simple_attributes", RelationType::SimpleAttributes),
("related_features", RelationType::RelatedFeatures),
("tiles", RelationType::Tiles),
("attributes", RelationType::Attributes),
];
for (expected, variant) in &cases {
assert_eq!(
variant.as_str(),
*expected,
"as_str() for {variant:?} should return {expected:?}"
);
assert_eq!(
parse(expected),
*variant,
"parse({expected:?}) did not round-trip"
);
}
}
#[test]
fn test_relation_type_other_preserves_raw_string() {
let raw = "my_organisation_ext";
let rt = parse(raw);
assert_eq!(rt.as_str(), raw);
}
#[test]
fn test_gpkg_relation_clone_and_eq() {
let rel = GpkgRelation {
id: 7,
base_table_name: "features".to_owned(),
base_primary_column: "id".to_owned(),
related_table_name: "media".to_owned(),
related_primary_column: "id".to_owned(),
relation_name: RelationType::Media,
mapping_table_name: "features_media".to_owned(),
};
let cloned = rel.clone();
assert_eq!(rel, cloned);
}
#[test]
fn test_mapping_row_clone_and_eq() {
let row = MappingRow {
id: 1,
base_id: 42,
related_id: 99,
};
let cloned = row.clone();
assert_eq!(row, cloned);
}
}