use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum DCatEndpoint {
Production,
Int,
Xbox,
XboxInt,
Dev,
OneP,
OnePInt,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum PackageType {
Uap,
Xap,
AppX,
#[default]
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum IdentifierType {
ProductId,
XboxTitleId,
PackageFamilyName,
ContentId,
LegacyWindowsPhoneProductId,
LegacyWindowsStoreProductId,
LegacyXboxProductId,
}
impl IdentifierType {
pub fn as_str(&self) -> &'static str {
match self {
IdentifierType::ProductId => "productId",
IdentifierType::XboxTitleId => "xboxTitleId",
IdentifierType::PackageFamilyName => "packageFamilyName",
IdentifierType::ContentId => "contentId",
IdentifierType::LegacyWindowsPhoneProductId => "legacyWindowsPhoneProductId",
IdentifierType::LegacyWindowsStoreProductId => "legacyWindowsStoreProductId",
IdentifierType::LegacyXboxProductId => "legacyXboxProductId",
}
}
pub fn dcat_alternate_id_name(&self) -> Option<&'static str> {
Some(match self {
IdentifierType::ProductId => return None,
IdentifierType::XboxTitleId => "XboxTitleID",
IdentifierType::PackageFamilyName => "PackageFamilyName",
IdentifierType::ContentId => "CONTENTID",
IdentifierType::LegacyWindowsPhoneProductId => "LegacyWindowsPhoneProductID",
IdentifierType::LegacyWindowsStoreProductId => "LegacyWindowsStoreProductID",
IdentifierType::LegacyXboxProductId => "LegacyXboxProductID",
})
}
pub fn parse_tolerant(raw: &str) -> Option<IdentifierType> {
let normalized: String = raw
.chars()
.filter(|c| c.is_ascii_alphanumeric())
.flat_map(|c| c.to_lowercase())
.collect();
Some(match normalized.as_str() {
"productid" => IdentifierType::ProductId,
"xboxtitleid" => IdentifierType::XboxTitleId,
"packagefamilyname" => IdentifierType::PackageFamilyName,
"contentid" => IdentifierType::ContentId,
"legacywindowsphoneproductid" => IdentifierType::LegacyWindowsPhoneProductId,
"legacywindowsstoreproductid" => IdentifierType::LegacyWindowsStoreProductId,
"legacyxboxproductid" => IdentifierType::LegacyXboxProductId,
_ => return None,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ImagePurpose {
Logo,
Tile,
Screenshot,
BoxArt,
BrandedKeyArt,
Poster,
FeaturePromotionalSquareArt,
ImageGallery,
SuperHeroArt,
TitledHeroArt,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ProductKind {
Game,
Application,
Book,
Movie,
Physical,
Software,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum DeviceFamily {
Desktop,
Mobile,
Xbox,
ServerCore,
IotCore,
HoloLens,
Andromeda,
Universal,
Wcos,
}
impl DeviceFamily {
pub fn platform_dependency_name(&self) -> &'static str {
match self {
DeviceFamily::Desktop => "Windows.Desktop",
DeviceFamily::Mobile => "Windows.Mobile",
DeviceFamily::Xbox => "Windows.Xbox",
DeviceFamily::ServerCore => "Windows.Server",
DeviceFamily::IotCore => "Windows.Iot",
DeviceFamily::HoloLens => "Windows.Holographic",
DeviceFamily::Andromeda => "Windows.8828080",
DeviceFamily::Universal => "Windows.Universal",
DeviceFamily::Wcos => "Windows.Core",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum DisplayCatalogResult {
NotFound,
Restricted,
TimedOut,
Error,
Found,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn identifier_type_canonical_str_matches_serde() {
for it in [
IdentifierType::ProductId,
IdentifierType::XboxTitleId,
IdentifierType::PackageFamilyName,
IdentifierType::ContentId,
IdentifierType::LegacyWindowsPhoneProductId,
IdentifierType::LegacyWindowsStoreProductId,
IdentifierType::LegacyXboxProductId,
] {
let json = serde_json::to_string(&it).unwrap();
assert_eq!(json, format!("\"{}\"", it.as_str()));
}
}
#[test]
fn identifier_type_parse_tolerant_pascal_case() {
assert_eq!(
IdentifierType::parse_tolerant("ProductId"),
Some(IdentifierType::ProductId),
);
assert_eq!(
IdentifierType::parse_tolerant("PackageFamilyName"),
Some(IdentifierType::PackageFamilyName),
);
assert_eq!(
IdentifierType::parse_tolerant("LegacyWindowsPhoneProductId"),
Some(IdentifierType::LegacyWindowsPhoneProductId),
);
}
#[test]
fn identifier_type_parse_tolerant_camel_case() {
assert_eq!(
IdentifierType::parse_tolerant("productId"),
Some(IdentifierType::ProductId),
);
assert_eq!(
IdentifierType::parse_tolerant("xboxTitleId"),
Some(IdentifierType::XboxTitleId),
);
}
#[test]
fn identifier_type_parse_tolerant_separators() {
assert_eq!(
IdentifierType::parse_tolerant("product-id"),
Some(IdentifierType::ProductId),
);
assert_eq!(
IdentifierType::parse_tolerant("product_id"),
Some(IdentifierType::ProductId),
);
assert_eq!(
IdentifierType::parse_tolerant("product id"),
Some(IdentifierType::ProductId),
);
assert_eq!(
IdentifierType::parse_tolerant("package.family.name"),
Some(IdentifierType::PackageFamilyName),
);
}
#[test]
fn identifier_type_parse_tolerant_screaming_case() {
assert_eq!(
IdentifierType::parse_tolerant("PRODUCT_ID"),
Some(IdentifierType::ProductId),
);
assert_eq!(
IdentifierType::parse_tolerant("XBOX-TITLE-ID"),
Some(IdentifierType::XboxTitleId),
);
}
#[test]
fn identifier_type_parse_tolerant_rejects_unknown() {
assert_eq!(IdentifierType::parse_tolerant(""), None);
assert_eq!(IdentifierType::parse_tolerant("notARealId"), None);
assert_eq!(IdentifierType::parse_tolerant("product"), None);
assert_eq!(IdentifierType::parse_tolerant("xxxProductIdxxx"), None);
}
#[test]
fn identifier_type_round_trip_via_tolerant_and_serde() {
for it in [
IdentifierType::ProductId,
IdentifierType::XboxTitleId,
IdentifierType::PackageFamilyName,
IdentifierType::ContentId,
IdentifierType::LegacyWindowsPhoneProductId,
IdentifierType::LegacyWindowsStoreProductId,
IdentifierType::LegacyXboxProductId,
] {
let s = it.as_str();
assert_eq!(IdentifierType::parse_tolerant(s), Some(it.clone()));
let json = format!("\"{s}\"");
let parsed: IdentifierType = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, it);
}
}
}