From 62b2fd3325e043bf655c4b48d47cd9aad8ccc32f Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 3 Apr 2026 13:48:43 -0400 Subject: [PATCH] Original is cloneable and comparable --- .../MetadataExtensions.cs | 6 +-- SabreTools.Data.Models/Metadata/Original.cs | 40 +++++++++++++++---- SabreTools.Data.Models/OpenMSX/Original.cs | 3 +- .../DatFileTests.FromMetadata.cs | 2 +- .../DatFile.ToMetadata.cs | 7 ++-- .../Formats/Original.cs | 4 +- SabreTools.Metadata.DatItems/Formats/Rom.cs | 2 +- SabreTools.Metadata.Filter/FilterObject.cs | 3 ++ .../DictionaryBaseExtensions.cs | 2 +- .../OpenMSXTests.cs | 4 +- .../OpenMSX.Deserializer.cs | 2 +- .../OpenMSX.Serializer.cs | 2 +- .../OpenMSXTests.cs | 4 +- SabreTools.Serialization.Readers/OpenMSX.cs | 3 +- SabreTools.Serialization.Writers/OpenMSX.cs | 2 +- 15 files changed, 56 insertions(+), 30 deletions(-) diff --git a/SabreTools.Data.Extensions/MetadataExtensions.cs b/SabreTools.Data.Extensions/MetadataExtensions.cs index 38e5831a..174b67bf 100644 --- a/SabreTools.Data.Extensions/MetadataExtensions.cs +++ b/SabreTools.Data.Extensions/MetadataExtensions.cs @@ -174,6 +174,8 @@ namespace SabreTools.Data.Extensions return info.Clone() as Info; else if (self is Instance instance) return instance.Clone() as Instance; + else if (self is Original original) + return original.Clone() as Original; else if (self is RamOption ramOption) return ramOption.Clone() as RamOption; else if (self is SharedFeat sharedFeat) @@ -301,10 +303,6 @@ namespace SabreTools.Data.Extensions cloneMachine.Runnable = selfMachine.Runnable; cloneMachine.Supported = selfMachine.Supported; } - else if (self is Original selfOriginal && clone is Original cloneOriginal) - { - cloneOriginal.Content = selfOriginal.Content; - } else if (self is Part selfPart && clone is Part clonePart) { clonePart.Interface = selfPart.Interface; diff --git a/SabreTools.Data.Models/Metadata/Original.cs b/SabreTools.Data.Models/Metadata/Original.cs index 01bd3243..ff507aef 100644 --- a/SabreTools.Data.Models/Metadata/Original.cs +++ b/SabreTools.Data.Models/Metadata/Original.cs @@ -1,24 +1,50 @@ +using System; using System.Xml.Serialization; using Newtonsoft.Json; namespace SabreTools.Data.Models.Metadata { [JsonObject("original"), XmlRoot("original")] - public class Original : DatItem + public class Original : DatItem, ICloneable, IEquatable { #region Properties public string? Content { get; set; } - #endregion - - #region Keys - - /// bool - public const string ValueKey = "value"; + public bool? Value { get; set; } #endregion public Original() => ItemType = ItemType.Original; + + /// + public object Clone() + { + var obj = new Original(); + + obj.Content = Content; + obj.Value = Value; + + return obj; + } + + /// + public bool Equals(Original? other) + { + // Null never matches + if (other is null) + return false; + + // Properties + if ((Content is null) ^ (other.Content is null)) + return false; + else if (Content is not null && !Content.Equals(other.Content, StringComparison.OrdinalIgnoreCase)) + return false; + + if (Value != other.Value) + return false; + + return true; + } } } diff --git a/SabreTools.Data.Models/OpenMSX/Original.cs b/SabreTools.Data.Models/OpenMSX/Original.cs index 131f61ce..e7ecf0fe 100644 --- a/SabreTools.Data.Models/OpenMSX/Original.cs +++ b/SabreTools.Data.Models/OpenMSX/Original.cs @@ -6,9 +6,8 @@ namespace SabreTools.Data.Models.OpenMSX [XmlRoot("original")] public class Original { - /// Boolean? [XmlAttribute("value")] - public string? Value { get; set; } + public bool? Value { get; set; } [XmlText] public string? Content { get; set; } diff --git a/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs b/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs index d28bbfbc..ff4ce2ab 100644 --- a/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs +++ b/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs @@ -697,7 +697,7 @@ namespace SabreTools.Metadata.DatFiles.Test return new Data.Models.Metadata.Original { Content = "content", - [Data.Models.Metadata.Original.ValueKey] = true, + Value = true, }; } diff --git a/SabreTools.Metadata.DatFiles/DatFile.ToMetadata.cs b/SabreTools.Metadata.DatFiles/DatFile.ToMetadata.cs index 03dfb8e0..4d27a5fa 100644 --- a/SabreTools.Metadata.DatFiles/DatFile.ToMetadata.cs +++ b/SabreTools.Metadata.DatFiles/DatFile.ToMetadata.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using SabreTools.Data.Extensions; using SabreTools.Metadata.DatItems; using OpenMSXSubType = SabreTools.Data.Models.Metadata.OpenMSXSubType; @@ -983,7 +982,7 @@ namespace SabreTools.Metadata.DatFiles { var newOriginal = new Data.Models.Metadata.Original { - [Data.Models.Metadata.Original.ValueKey] = romOriginal.Value.FromYesNo(), + Value = romOriginal.Value, Content = romOriginal.Content, }; dumpRom[Data.Models.Metadata.Dump.OriginalKey] = newOriginal; @@ -1011,7 +1010,7 @@ namespace SabreTools.Metadata.DatFiles { var newOriginal = new Data.Models.Metadata.Original { - [Data.Models.Metadata.Original.ValueKey] = megaRomOriginal.Value.FromYesNo(), + Value = megaRomOriginal.Value, Content = megaRomOriginal.Content, }; dumpMegaRom[Data.Models.Metadata.Dump.OriginalKey] = newOriginal; @@ -1039,7 +1038,7 @@ namespace SabreTools.Metadata.DatFiles { var newOriginal = new Data.Models.Metadata.Original { - [Data.Models.Metadata.Original.ValueKey] = sccPlusCartOriginal.Value.FromYesNo(), + Value = sccPlusCartOriginal.Value, Content = sccPlusCartOriginal.Content, }; dumpSccPlusCart[Data.Models.Metadata.Dump.OriginalKey] = newOriginal; diff --git a/SabreTools.Metadata.DatItems/Formats/Original.cs b/SabreTools.Metadata.DatItems/Formats/Original.cs index ed0038f1..0b654191 100644 --- a/SabreTools.Metadata.DatItems/Formats/Original.cs +++ b/SabreTools.Metadata.DatItems/Formats/Original.cs @@ -25,8 +25,8 @@ namespace SabreTools.Metadata.DatItems.Formats [JsonProperty("value"), XmlElement("value")] public bool? Value { - get => _internal.ReadBool(Data.Models.Metadata.Original.ValueKey); - set => _internal[Data.Models.Metadata.Original.ValueKey] = value; + get => _internal.Value; + set => _internal.Value = value; } #endregion diff --git a/SabreTools.Metadata.DatItems/Formats/Rom.cs b/SabreTools.Metadata.DatItems/Formats/Rom.cs index 6a412e9f..b84929ed 100644 --- a/SabreTools.Metadata.DatItems/Formats/Rom.cs +++ b/SabreTools.Metadata.DatItems/Formats/Rom.cs @@ -191,7 +191,7 @@ namespace SabreTools.Metadata.DatItems.Formats { Write("ORIGINAL", new Original { - Value = original.ReadBool(Data.Models.Metadata.Original.ValueKey), + Value = original.Value, Content = original.Content, }); } diff --git a/SabreTools.Metadata.Filter/FilterObject.cs b/SabreTools.Metadata.Filter/FilterObject.cs index 8bb2900c..a85958b9 100644 --- a/SabreTools.Metadata.Filter/FilterObject.cs +++ b/SabreTools.Metadata.Filter/FilterObject.cs @@ -752,6 +752,9 @@ namespace SabreTools.Metadata.Filter case Original item when fieldName == "content": checkValue = item.Content; return true; + case Original item when fieldName == "value": + checkValue = item.Value.FromYesNo(); + return true; case Part item when fieldName == "interface": checkValue = item.Interface; diff --git a/SabreTools.Metadata/DictionaryBaseExtensions.cs b/SabreTools.Metadata/DictionaryBaseExtensions.cs index 55352261..e406cd7d 100644 --- a/SabreTools.Metadata/DictionaryBaseExtensions.cs +++ b/SabreTools.Metadata/DictionaryBaseExtensions.cs @@ -291,7 +291,7 @@ namespace SabreTools.Metadata } else if (self is Original selfOriginal && other is Original otherOriginal) { - if (selfOriginal.Content != otherOriginal.Content) + if (!selfOriginal.Equals(otherOriginal)) return false; } else if (self is Part selfPart && other is Part otherPart) diff --git a/SabreTools.Serialization.CrossModel.Test/OpenMSXTests.cs b/SabreTools.Serialization.CrossModel.Test/OpenMSXTests.cs index eef7cc22..7faa8d00 100644 --- a/SabreTools.Serialization.CrossModel.Test/OpenMSXTests.cs +++ b/SabreTools.Serialization.CrossModel.Test/OpenMSXTests.cs @@ -36,7 +36,7 @@ namespace SabreTools.Serialization.CrossModel.Test { var original = new Data.Models.OpenMSX.Original { - Value = "value", + Value = true, Content = "content", }; @@ -137,7 +137,7 @@ namespace SabreTools.Serialization.CrossModel.Test private static void Validate(Data.Models.OpenMSX.Original? original) { Assert.NotNull(original); - Assert.Equal("value", original.Value); + Assert.Equal(true, original.Value); Assert.Equal("content", original.Content); } diff --git a/SabreTools.Serialization.CrossModel/OpenMSX.Deserializer.cs b/SabreTools.Serialization.CrossModel/OpenMSX.Deserializer.cs index 3572044c..2f8e2a8e 100644 --- a/SabreTools.Serialization.CrossModel/OpenMSX.Deserializer.cs +++ b/SabreTools.Serialization.CrossModel/OpenMSX.Deserializer.cs @@ -103,7 +103,7 @@ namespace SabreTools.Serialization.CrossModel { var original = new Original { - Value = item.ReadString(Data.Models.Metadata.Original.ValueKey), + Value = item.Value, Content = item.Content, }; return original; diff --git a/SabreTools.Serialization.CrossModel/OpenMSX.Serializer.cs b/SabreTools.Serialization.CrossModel/OpenMSX.Serializer.cs index 63e096e5..f7d815de 100644 --- a/SabreTools.Serialization.CrossModel/OpenMSX.Serializer.cs +++ b/SabreTools.Serialization.CrossModel/OpenMSX.Serializer.cs @@ -103,7 +103,7 @@ namespace SabreTools.Serialization.CrossModel { var original = new Data.Models.Metadata.Original { - [Data.Models.Metadata.Original.ValueKey] = item.Value, + Value = item.Value, Content = item.Content, }; return original; diff --git a/SabreTools.Serialization.Readers.Test/OpenMSXTests.cs b/SabreTools.Serialization.Readers.Test/OpenMSXTests.cs index c80c6616..ad33402d 100644 --- a/SabreTools.Serialization.Readers.Test/OpenMSXTests.cs +++ b/SabreTools.Serialization.Readers.Test/OpenMSXTests.cs @@ -102,7 +102,7 @@ namespace SabreTools.Serialization.Readers.Test { var original = new Data.Models.OpenMSX.Original { - Value = "value", + Value = true, Content = "content", }; @@ -203,7 +203,7 @@ namespace SabreTools.Serialization.Readers.Test private static void Validate(Data.Models.OpenMSX.Original? original) { Assert.NotNull(original); - Assert.Equal("value", original.Value); + Assert.Equal(true, original.Value); Assert.Equal("content", original.Content); } diff --git a/SabreTools.Serialization.Readers/OpenMSX.cs b/SabreTools.Serialization.Readers/OpenMSX.cs index 015f92f1..a8b93211 100644 --- a/SabreTools.Serialization.Readers/OpenMSX.cs +++ b/SabreTools.Serialization.Readers/OpenMSX.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Xml; +using SabreTools.Data.Extensions; using SabreTools.Data.Models.OpenMSX; namespace SabreTools.Serialization.Readers @@ -163,7 +164,7 @@ namespace SabreTools.Serialization.Readers { var obj = new Original(); - obj.Value = reader.GetAttribute("value"); + obj.Value = reader.GetAttribute("value").AsYesNo(); obj.Content = reader.ReadElementContentAsString(); return obj; diff --git a/SabreTools.Serialization.Writers/OpenMSX.cs b/SabreTools.Serialization.Writers/OpenMSX.cs index b788ae11..95a6d699 100644 --- a/SabreTools.Serialization.Writers/OpenMSX.cs +++ b/SabreTools.Serialization.Writers/OpenMSX.cs @@ -115,7 +115,7 @@ namespace SabreTools.Serialization.Writers { writer.WriteStartElement("original"); - writer.WriteOptionalAttributeString("value", obj.Value); + writer.WriteOptionalAttributeString("value", obj.Value?.ToString().ToLowerInvariant()); if (obj.Content is not null) writer.WriteRaw(obj.Content);