use rpkg_rs::misc::resource_id::ResourceID;
use rpkg_rs::resource::package_builder::{PackageBuilder, PackageResourceBuilder};
use rpkg_rs::resource::resource_package::{
ChunkType, PackageVersion, ResourcePackage, ResourceReferenceFlags, ResourceReferenceFlagsLegacy,
ResourceReferenceFlagsStandard,
};
use rpkg_rs::resource::runtime_resource_id::{PlatformTag, RuntimeResourceID};
use std::str::FromStr;
use rpkg_rs::resource::resource_partition::PatchId;
fn test_package_with_resource(
compression_level: Option<i32>,
should_scramble: bool,
version: PackageVersion,
is_patch: bool,
legacy_references: bool,
) -> Result<(), Box<dyn std::error::Error>> {
let resource_id = ResourceID::from_str("[assembly:/res1.brick].pc_entitytype")?;
let unneeded_resource_ids = vec![
RuntimeResourceID::from_resource_id_with_platform(&ResourceID::from_str(
"[assembly:/res2.brick].pc_entitytype",
)?, "pc", PlatformTag::None),
RuntimeResourceID::from_resource_id_with_platform(&ResourceID::from_str(
"[assembly:/res3.brick].pc_entitytype",
)?, "pc", PlatformTag::None),
];
let references = vec![
RuntimeResourceID::from_resource_id_with_platform(&ResourceID::from_str(
"[assembly:/ref1.brick].pc_entitytype",
)?, "pc", PlatformTag::None),
RuntimeResourceID::from_resource_id_with_platform(&ResourceID::from_str(
"[assembly:/ref2.brick].pc_entitytype",
)?, "pc", PlatformTag::None),
];
let resource_reference_flags = if legacy_references {
ResourceReferenceFlags::Legacy(
ResourceReferenceFlagsLegacy::new()
.with_runtime_acquired(true)
.with_install_dependency(true),
)
} else {
ResourceReferenceFlags::Standard(ResourceReferenceFlagsStandard::new().with_language_code(0x1F))
};
let mut builder = PackageBuilder::new(69, ChunkType::Standard);
let rrid: RuntimeResourceID = RuntimeResourceID::from_resource_id_with_platform(&resource_id, "pc", PlatformTag::None);
let fake_data: Vec<u8> = (0..1024).map(|j| j as u8).collect();
let mut resource = PackageResourceBuilder::from_memory(
rrid,
"TEMP",
fake_data.clone(),
compression_level,
should_scramble,
)?;
for reference in &references {
resource.with_reference(*reference, resource_reference_flags.clone());
}
builder.with_resource(resource);
if is_patch {
builder.with_patch_id(&PatchId::Patch(1));
for rrid in &unneeded_resource_ids {
builder.with_unneeded_resource(*rrid);
}
}
if legacy_references{
builder.use_legacy_references();
}
let package_data = builder.build_to_vec(version)?;
let package = ResourcePackage::from_memory(package_data, is_patch)?;
let resource_data = package.read_resource(&rrid).unwrap();
assert_eq!(resource_data, fake_data, "Resource data doesn't match");
let resource_info = package.resources().get(&rrid).unwrap();
for (i, (rrid, flags)) in resource_info.references().iter().enumerate() {
let reference = references[i];
assert_eq!(*rrid, reference, "Reference at index {} doesn't match", i);
assert_eq!(
*flags, resource_reference_flags,
"Reference flags at index {} don't match",
i
);
}
if is_patch {
let parsed_unneeded_resource_ids = package.unneeded_resource_ids();
assert_eq!(
parsed_unneeded_resource_ids.len(),
unneeded_resource_ids.len(),
"Number of unneeded resources doesn't match"
);
for (i, rrid) in parsed_unneeded_resource_ids.iter().enumerate() {
let expected_rrid = unneeded_resource_ids[i];
assert_eq!(
**rrid, expected_rrid,
"Unneeded resource at index {} doesn't match",
i
);
}
}
Ok(())
}
#[test]
fn test_simple_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, false, PackageVersion::RPKGv1, false, false)
}
#[test]
fn test_compression_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(Some(4), false, PackageVersion::RPKGv1, false, false)
}
#[test]
fn test_scrambling_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, true, PackageVersion::RPKGv1, false, false)
}
#[test]
fn test_compression_and_scrambling_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(Some(4), true, PackageVersion::RPKGv1, false, false)
}
#[test]
fn test_simple_rpkg_v2() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, false, PackageVersion::RPKGv2, false, false)
}
#[test]
fn test_compression_rpkg_v2() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(Some(4), false, PackageVersion::RPKGv2, false, false)
}
#[test]
fn test_scrambling_rpkg_v2() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, true, PackageVersion::RPKGv2, false, false)
}
#[test]
fn test_compression_and_scrambling_rpkg_v2() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(Some(4), true, PackageVersion::RPKGv2, false, false)
}
#[test]
fn test_patch_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, false, PackageVersion::RPKGv1, true, false)
}
#[test]
fn test_compressed_and_scrambled_patch_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(Some(4), true, PackageVersion::RPKGv1, true, false)
}
#[test]
fn test_legacy_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, false, PackageVersion::RPKGv1, false, true)
}
#[test]
fn test_legacy_patch_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, false, PackageVersion::RPKGv1, true, true)
}
#[test]
fn test_legacy_compressed_and_scrambled_patch_rpkg_v1() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(Some(4), true, PackageVersion::RPKGv1, true, true)
}
#[test]
fn test_legacy_rpkg_v2() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, false, PackageVersion::RPKGv2, false, true)
}
#[test]
fn test_legacy_patch_rpkg_v2() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(None, false, PackageVersion::RPKGv2, true, true)
}
#[test]
fn test_legacy_compressed_and_scrambled_patch_rpkg_v2() -> Result<(), Box<dyn std::error::Error>> {
test_package_with_resource(Some(4), true, PackageVersion::RPKGv2, true, true)
}