using System; using static PKHeX.Core.RibbonParseFlags; namespace PKHeX.Core; /// /// Stores info about if a ribbon is valid or not. /// public readonly record struct RibbonResult { // TWO BYTES USED private readonly byte Value; private readonly RibbonParseFlags Flags; /// /// True: ribbon is missing -- should have the ribbon. /// False: ribbon is invalid -- should not have the ribbon. /// public bool IsMissing => (Flags & Missing) != 0; private RibbonParseFlags Type => Flags & ~Missing; public RibbonResult(RibbonIndex index, bool missing = false) { Value = (byte)index; Flags = missing ? MissingM : Mainline; } public RibbonResult(RibbonIndex3 index, bool missing = false) { Value = (byte)index; Flags = missing ? Missing3 : Index3; } public RibbonResult(RibbonIndex4 index, bool missing = false) { Value = (byte)index; Flags = missing ? Missing4 : Index4; } public bool Equals(RibbonIndex index) => Type == Mainline && Value == (byte)index; public bool Equals(RibbonIndex3 index) => Type == Index3 && Value == (byte)index; public bool Equals(RibbonIndex4 index) => Type == Index4 && Value == (byte)index; /// /// Property Name that the ribbon can be get/set with, or looked up for localization. /// public string PropertyName => Type switch { Mainline => ((RibbonIndex)Value).GetPropertyName(), Index3 => ((RibbonIndex3)Value).GetPropertyName(), Index4 => ((RibbonIndex4)Value).GetPropertyName(), _ => throw new ArgumentOutOfRangeException(), }; /// /// Updates the ribbon state depending on the and state. /// public void Fix(RibbonVerifierArguments args) { switch (Type) { case Mainline: ((RibbonIndex)Value).Fix(args, IsMissing); break; case Index3: ((RibbonIndex3)Value).Fix(args, IsMissing); break; case Index4: ((RibbonIndex4)Value).Fix(args, IsMissing); break; default: throw new ArgumentOutOfRangeException(); } } } [Flags] public enum RibbonParseFlags : byte { None = 0, Mainline, Index3, Index4, Missing = 0x80, MissingM = Missing | Mainline, Missing3 = Missing | Index3, Missing4 = Missing | Index4, }