Flatten Extension out of existence

This commit is contained in:
Matt Nadareski
2026-04-09 22:06:41 -04:00
parent 967d9ffe87
commit 853e2ff5c0
16 changed files with 30 additions and 281 deletions

View File

@@ -2758,7 +2758,6 @@ namespace SabreTools.Data.Extensions.Test
[InlineData("diskarea", ItemType.DiskArea)]
[InlineData("display", ItemType.Display)]
[InlineData("driver", ItemType.Driver)]
[InlineData("extension", ItemType.Extension)]
[InlineData("feature", ItemType.Feature)]
[InlineData("file", ItemType.File)]
[InlineData("info", ItemType.Info)]
@@ -3158,7 +3157,6 @@ namespace SabreTools.Data.Extensions.Test
[InlineData(ItemType.DiskArea, "diskarea")]
[InlineData(ItemType.Display, "display")]
[InlineData(ItemType.Driver, "driver")]
[InlineData(ItemType.Extension, "extension")]
[InlineData(ItemType.Feature, "feature")]
[InlineData(ItemType.File, "file")]
[InlineData(ItemType.Info, "info")]

View File

@@ -923,7 +923,6 @@ namespace SabreTools.Data.Extensions
"display" => ItemType.Display,
"driver" => ItemType.Driver,
"dump" => ItemType.Dump,
"extension" => ItemType.Extension,
"feature" => ItemType.Feature,
"info" => ItemType.Info,
"input" => ItemType.Input,
@@ -1405,7 +1404,6 @@ namespace SabreTools.Data.Extensions
ItemType.Display => "display",
ItemType.Driver => "driver",
ItemType.Dump => "dump",
ItemType.Extension => "extension",
ItemType.Feature => "feature",
ItemType.Info => "info",
ItemType.Input => "input",

View File

@@ -12,7 +12,8 @@ namespace SabreTools.Data.Models.Metadata
/// <remarks>(unknown|cartridge|floppydisk|harddisk|cylinder|cassette|punchcard|punchtape|printout|serial|parallel|snapshot|quickload|memcard|cdrom|magtape|romimage|midiin|midiout|picture|vidfile)</remarks>
public DeviceType? DeviceType { get; set; }
public Extension[]? Extension { get; set; }
/// <remarks>Extension subitem</remarks>
public string[]? ExtensionName { get; set; }
public string? FixedImage { get; set; }
@@ -37,8 +38,8 @@ namespace SabreTools.Data.Models.Metadata
var obj = new Device();
obj.DeviceType = DeviceType;
if (Extension is not null)
obj.Extension = Array.ConvertAll(Extension, i => (Extension)i.Clone());
if (ExtensionName is not null)
obj.ExtensionName = Array.ConvertAll(ExtensionName, i => i);
obj.FixedImage = FixedImage;
obj.InstanceBriefName = InstanceBriefName;
obj.InstanceName = InstanceName;

View File

@@ -291,7 +291,6 @@ namespace SabreTools.Data.Models.Metadata
Display,
Driver,
Dump,
Extension,
Feature,
File, // TODO: This should be merged with Rom?
Info,

View File

@@ -1,44 +0,0 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("extension"), XmlRoot("extension")]
public class Extension : DatItem, ICloneable, IEquatable<Extension>
{
#region Properties
public string? Name { get; set; }
#endregion
public Extension() => ItemType = ItemType.Extension;
/// <inheritdoc/>
public object Clone()
{
var obj = new Extension();
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(Extension? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -489,7 +489,7 @@ namespace SabreTools.Metadata.DatFiles.Test
{
return new Data.Models.Metadata.Device
{
Extension = [CreateMetadataExtension()],
ExtensionName = ["name"],
FixedImage = "fixedimage",
InstanceBriefName = "briefname",
InstanceName = "name",
@@ -644,14 +644,6 @@ namespace SabreTools.Metadata.DatFiles.Test
};
}
private static Data.Models.Metadata.Extension CreateMetadataExtension()
{
return new Data.Models.Metadata.Extension
{
Name = "name",
};
}
private static Data.Models.Metadata.Feature CreateMetadataFeature()
{
return new Data.Models.Metadata.Feature
@@ -1246,10 +1238,10 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("tag", device.Tag);
Assert.Equal(Data.Models.Metadata.DeviceType.PunchTape, device.DeviceType);
Extension[]? extensions = device.Extension;
Assert.NotNull(extensions);
Extension? extension = Assert.Single(extensions);
ValidateExtension(extension);
string[]? extensionNames = device.ExtensionName;
Assert.NotNull(extensionNames);
string? extensionName = Assert.Single(extensionNames);
Assert.Equal("name", extensionName);
}
private static void ValidateDeviceRef(DeviceRef? deviceRef)
@@ -1364,12 +1356,6 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.True(driver.Unofficial);
}
private static void ValidateExtension(Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("name", extension.Name);
}
private static void ValidateFeature(Feature? feature)
{
Assert.NotNull(feature);

View File

@@ -767,10 +767,10 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("tag", device.Tag);
Assert.Equal(Data.Models.Metadata.DeviceType.PunchTape, device.DeviceType);
Data.Models.Metadata.Extension[]? extensions = device.Extension;
Assert.NotNull(extensions);
Data.Models.Metadata.Extension? extension = Assert.Single(extensions);
ValidateMetadataExtension(extension);
string[]? extensionNames = device.ExtensionName;
Assert.NotNull(extensionNames);
string? extensionName = Assert.Single(extensionNames);
Assert.Equal("name", extensionName);
}
private static void ValidateMetadataDeviceRef(Data.Models.Metadata.DeviceRef? deviceRef)
@@ -890,12 +890,6 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.True(driver.Unofficial);
}
private static void ValidateMetadataExtension(Data.Models.Metadata.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("name", extension.Name);
}
private static void ValidateMetadataFeature(Data.Models.Metadata.Feature? feature)
{
Assert.NotNull(feature);

View File

@@ -315,9 +315,6 @@ namespace SabreTools.Metadata.DatFiles.Formats
case Data.Models.Metadata.ItemType.Driver:
datItem = datItemObj.ToObject<Driver>();
break;
case Data.Models.Metadata.ItemType.Extension:
datItem = datItemObj.ToObject<Extension>();
break;
case Data.Models.Metadata.ItemType.Feature:
datItem = datItemObj.ToObject<Feature>();
break;

View File

@@ -31,7 +31,6 @@ namespace SabreTools.Metadata.DatItems
[XmlInclude(typeof(DiskArea))]
[XmlInclude(typeof(Display))]
[XmlInclude(typeof(Driver))]
[XmlInclude(typeof(Extension))]
[XmlInclude(typeof(Feature))]
[XmlInclude(typeof(Info))]
[XmlInclude(typeof(Input))]

View File

@@ -1,7 +1,5 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
using SabreTools.Metadata.Filter;
namespace SabreTools.Metadata.DatItems.Formats
{
@@ -19,10 +17,11 @@ namespace SabreTools.Metadata.DatItems.Formats
set => _internal.DeviceType = value;
}
public Extension[]? Extension { get; set; }
[JsonIgnore]
public bool ExtensionSpecified => Extension is not null && Extension.Length > 0;
public string[]? ExtensionName
{
get => _internal.ExtensionName;
set => _internal.ExtensionName = value;
}
public string? FixedImage
{
@@ -70,12 +69,7 @@ namespace SabreTools.Metadata.DatItems.Formats
public Device() : base() { }
public Device(Data.Models.Metadata.Device item) : base(item)
{
// Handle subitems
if (item.Extension is not null)
Extension = Array.ConvertAll(item.Extension, extension => new Extension(extension));
}
public Device(Data.Models.Metadata.Device item) : base(item) { }
public Device(Data.Models.Metadata.Device item, Machine machine, Source source) : this(item)
{
@@ -102,14 +96,7 @@ namespace SabreTools.Metadata.DatItems.Formats
/// <inheritdoc/>
public override Data.Models.Metadata.Device GetInternalClone()
{
var deviceItem = _internal.Clone() as Data.Models.Metadata.Device ?? new();
if (Extension is not null)
deviceItem.Extension = Array.ConvertAll(Extension, extension => extension.GetInternalClone()); ;
return deviceItem;
}
=> _internal.Clone() as Data.Models.Metadata.Device ?? new();
#endregion
@@ -131,28 +118,5 @@ namespace SabreTools.Metadata.DatItems.Formats
}
#endregion
#region Manipulation
/// <inheritdoc/>
public override bool PassesFilter(FilterRunner filterRunner)
{
if (Machine is not null && !Machine.PassesFilter(filterRunner))
return false;
// TODO: Extension
return filterRunner.Run(_internal);
}
/// <inheritdoc/>
public override bool PassesFilterDB(FilterRunner filterRunner)
{
// TODO: Extension
return filterRunner.Run(_internal);
}
#endregion
}
}

View File

@@ -1,80 +0,0 @@
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Metadata.DatItems.Formats
{
/// <summary>
/// Represents a matchable extension
/// </summary>
[JsonObject("extension"), XmlRoot("extension")]
public sealed class Extension : DatItem<Data.Models.Metadata.Extension>
{
#region Properties
/// <inheritdoc>/>
public override Data.Models.Metadata.ItemType ItemType
=> Data.Models.Metadata.ItemType.Extension;
public string? Name
{
get => _internal.Name;
set => _internal.Name = value;
}
#endregion
#region Constructors
public Extension() : base() { }
public Extension(Data.Models.Metadata.Extension item) : base(item) { }
public Extension(Data.Models.Metadata.Extension item, Machine machine, Source source) : this(item)
{
Source = source;
CopyMachineInformation(machine);
}
#endregion
#region Accessors
/// <inheritdoc/>
public override string? GetName() => Name;
/// <inheritdoc/>
public override void SetName(string? name) => Name = name;
#endregion
#region Cloning Methods
/// <inheritdoc/>
public override object Clone() => new Extension(GetInternalClone());
/// <inheritdoc/>
public override Data.Models.Metadata.Extension GetInternalClone()
=> _internal.Clone() as Data.Models.Metadata.Extension ?? new();
#endregion
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(DatItem? other)
{
// If the other item is null
if (other is null)
return false;
// If the type matches
if (other is Extension otherExtension)
return _internal.Equals(otherExtension._internal);
// Everything else fails
return false;
}
#endregion
}
}

View File

@@ -803,6 +803,7 @@ namespace SabreTools.Metadata.Filter.Test
[Theory]
[InlineData("device.devicetype", "punchcard")]
// [InlineData("device.extension.name", "name")] // TODO: Figure out how to deal with string arrays
[InlineData("device.fixedimage", "fixedimage")]
[InlineData("device.instance.briefname", "briefname")]
[InlineData("device.instance.name", "name")]
@@ -815,6 +816,7 @@ namespace SabreTools.Metadata.Filter.Test
Device obj = new Device
{
DeviceType = DeviceType.PunchCard,
ExtensionName = ["name"],
FixedImage = "fixedimage",
InstanceBriefName = "briefname",
InstanceName = "name",
@@ -1078,24 +1080,6 @@ namespace SabreTools.Metadata.Filter.Test
#endregion
#region Extension
[Theory]
[InlineData("extension.name", "name")]
public void Matches_Extension(string itemField, string value)
{
var filter = new FilterObject(itemField, value, Operation.Equals);
Extension obj = new Extension
{
Name = "name",
};
bool actual = filter.Matches(obj);
Assert.True(actual);
}
#endregion
#region Feature
[Theory]

View File

@@ -194,6 +194,7 @@ namespace SabreTools.Metadata.Filter
private static readonly string[] _deviceKeys =
[
"devicetype",
"extension.name",
"fixedimage",
"instance.briefname",
"instance.name",
@@ -321,14 +322,6 @@ namespace SabreTools.Metadata.Filter
"unofficial",
];
/// <summary>
/// Known keys for Extension
/// </summary>
private static readonly string[] _extensionKeys =
[
"name",
];
/// <summary>
/// Known keys for Feature/PartFeature
/// </summary>
@@ -1031,7 +1024,6 @@ namespace SabreTools.Metadata.Filter
"diskarea" => _diskAreaKeys,
"display" => _displayKeys,
"driver" => _driverKeys,
"extension" => _extensionKeys,
"feature" or "partfeature" => _featureKeys,
"game" or "machine" or "resource" or "set" => _machineKeys,
"header" => _headerKeys,

View File

@@ -397,7 +397,6 @@ namespace SabreTools.Metadata.Filter
case DiskArea item: return GetCheckValue(item, fieldName, out checkValue);
case Display item: return GetCheckValue(item, fieldName, out checkValue);
case Driver item: return GetCheckValue(item, fieldName, out checkValue);
case Extension item: return GetCheckValue(item, fieldName, out checkValue);
case Feature item: return GetCheckValue(item, fieldName, out checkValue);
case Header item: return GetCheckValue(item, fieldName, out checkValue);
case Info item: return GetCheckValue(item, fieldName, out checkValue);
@@ -906,6 +905,10 @@ namespace SabreTools.Metadata.Filter
case "devicetype":
checkValue = obj.DeviceType?.AsStringValue();
return true;
// TODO: Figure out how to deal with string arrays
// case "extension.name":
// checkValue = obj.ExtensionName;
// return true;
case "fixedimage":
checkValue = obj.FixedImage;
return true;
@@ -1231,24 +1234,6 @@ namespace SabreTools.Metadata.Filter
}
}
/// <summary>
/// Get the check value for a field
/// </summary>
private static bool GetCheckValue(Extension obj, string fieldName, out string? checkValue)
{
switch (fieldName)
{
case "name":
checkValue = obj.Name;
return true;
// If the key doesn't exist, we count it as null
default:
checkValue = null;
return false;
}
}
/// <summary>
/// Get the check value for a field
/// </summary>

View File

@@ -338,9 +338,9 @@ namespace SabreTools.Serialization.CrossModel
};
}
var extensions = item.Extension;
var extensions = item.ExtensionName;
if (extensions is not null && extensions.Length > 0)
device.Extension = Array.ConvertAll(extensions, ConvertFromInternalModel);
device.Extension = Array.ConvertAll(extensions, name => new Extension { Name = name });
return device;
}
@@ -504,18 +504,6 @@ namespace SabreTools.Serialization.CrossModel
return driver;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Extension"/> to <see cref="Extension"/>
/// </summary>
private static Extension ConvertFromInternalModel(Data.Models.Metadata.Extension item)
{
var extension = new Extension
{
Name = item.Name,
};
return extension;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Feature"/> to <see cref="Feature"/>
/// </summary>

View File

@@ -279,7 +279,7 @@ namespace SabreTools.Serialization.CrossModel
};
if (item.Extension is not null && item.Extension.Length > 0)
device.Extension = Array.ConvertAll(item.Extension, ConvertToInternalModel);
device.ExtensionName = Array.ConvertAll(item.Extension, extension => extension.Name ?? string.Empty);
return device;
}
@@ -421,18 +421,6 @@ namespace SabreTools.Serialization.CrossModel
return driver;
}
/// <summary>
/// Convert from <see cref="Extension"/> to <see cref="Models.Metadata.Extension"/>
/// </summary>
private static Data.Models.Metadata.Extension ConvertToInternalModel(Extension item)
{
var extension = new Data.Models.Metadata.Extension
{
Name = item.Name,
};
return extension;
}
/// <summary>
/// Convert from <see cref="Feature"/> to <see cref="Models.Metadata.Feature"/>
/// </summary>