diff --git a/SabreTools.Filtering/Cleaner.cs b/SabreTools.Filtering/Cleaner.cs index 5134bc2b..0d1df113 100644 --- a/SabreTools.Filtering/Cleaner.cs +++ b/SabreTools.Filtering/Cleaner.cs @@ -4,8 +4,10 @@ using System.Linq; using System.Text.RegularExpressions; using SabreTools.Core; +using SabreTools.Core.Tools; using SabreTools.DatFiles; using SabreTools.DatItems; +using SabreTools.Logging; namespace SabreTools.Filtering { @@ -114,6 +116,15 @@ namespace SabreTools.Filtering /// public bool Trim { get; set; } + #endregion + + #region Logging + + /// + /// Logging object + /// + private Logger logger = new Logger(); + #endregion #region Cleaning @@ -331,6 +342,80 @@ namespace SabreTools.Filtering #region Filtering + /// + /// Populate the filters objects using a set of key:value filters + /// + /// List of key:value where ~key/!key is negated + public void PopulateFromList(List filters) + { + // Instantiate the filters, if necessary + DatHeaderFilter ??= new DatHeaderFilter(); + MachineFilter ??= new MachineFilter(); + DatItemFilter ??= new DatItemFilter(); + + foreach (string filterPair in filters) + { + (string field, string value, bool negate) = ProcessFilterPair(filterPair); + + // If we don't even have a possible filter pair + if (field == null && value == null) + continue; + + // DatHeader fields + DatHeaderField datHeaderField = field.AsDatHeaderField(); + if (datHeaderField != DatHeaderField.NULL) + { + DatHeaderFilter.SetFilter(datHeaderField, value, negate); + continue; + } + + // Machine fields + MachineField machineField = field.AsMachineField(); + if (machineField != MachineField.NULL) + { + MachineFilter.SetFilter(machineField, value, negate); + continue; + } + + // DatItem fields + DatItemField datItemField = field.AsDatItemField(); + if (datItemField != DatItemField.NULL) + { + DatItemFilter.SetFilter(datItemField, value, negate); + continue; + } + + // If we didn't match anything, log an error + logger.Warning($"The value {field} did not match any known field names. Please check the wiki for more details on supported field names."); + } + } + + /// + /// Split the parts of a filter statement + /// + /// key:value where ~key/!key is negated + private (string field, string value, bool negate) ProcessFilterPair(string filter) + { + // If we don't even have a possible filter pair + if (!filter.Contains(":")) + { + logger.Warning($"'{filter}` is not a valid filter string. Valid filter strings are of the form 'key:value'. Please refer to README.1ST or the help feature for more details."); + return (null, null, false); + } + + string filterTrimmed = filter.Trim('"', ' ', '\t'); + bool negate = filterTrimmed.StartsWith("!") + || filterTrimmed.StartsWith("~") + || filterTrimmed.StartsWith("not-"); + filterTrimmed = filterTrimmed.TrimStart('!', '~'); + filterTrimmed = filterTrimmed.StartsWith("not-") ? filterTrimmed[4..] : filterTrimmed; + + string filterFieldString = filterTrimmed.Split(':')[0].ToLowerInvariant().Trim('"', ' ', '\t'); + string filterValue = filterTrimmed[(filterFieldString.Length + 1)..].Trim('"', ' ', '\t'); + + return (filterFieldString, filterValue, negate); + } + /// /// Check to see if a DatItem passes the filters /// diff --git a/SabreTools.Filtering/DatHeaderFilter.cs b/SabreTools.Filtering/DatHeaderFilter.cs index 3dafc3b5..b242df24 100644 --- a/SabreTools.Filtering/DatHeaderFilter.cs +++ b/SabreTools.Filtering/DatHeaderFilter.cs @@ -25,25 +25,6 @@ namespace SabreTools.Filtering #region Filter Population - /// - /// Populate the filters object using a set of key:value filters - /// - /// List of key:value where ~key/!key is negated - public override void PopulateFromList(List filters) - { - foreach (string filterPair in filters) - { - (string field, string value, bool negate) = ProcessFilterPair(filterPair); - - // If we don't even have a possible filter pair - if (field == null && value == null) - continue; - - DatHeaderField filterField = field.AsDatHeaderField(); - SetFilter(filterField, value, negate); - } - } - /// /// Set multiple filters from key /// diff --git a/SabreTools.Filtering/DatItemFilter.cs b/SabreTools.Filtering/DatItemFilter.cs index 7c76fa45..998cc31e 100644 --- a/SabreTools.Filtering/DatItemFilter.cs +++ b/SabreTools.Filtering/DatItemFilter.cs @@ -208,25 +208,6 @@ namespace SabreTools.Filtering #region Filter Population - /// - /// Populate the filters object using a set of key:value filters - /// - /// List of key:value where ~key/!key is negated - public override void PopulateFromList(List filters) - { - foreach (string filterPair in filters) - { - (string field, string value, bool negate) = ProcessFilterPair(filterPair); - - // If we don't even have a possible filter pair - if (field == null && value == null) - continue; - - DatItemField filterField = field.AsDatItemField(); - SetFilter(filterField, value, negate); - } - } - /// /// Set multiple filters from key /// diff --git a/SabreTools.Filtering/Filter.cs b/SabreTools.Filtering/Filter.cs index 0294eeeb..f7ec3d38 100644 --- a/SabreTools.Filtering/Filter.cs +++ b/SabreTools.Filtering/Filter.cs @@ -33,12 +33,6 @@ namespace SabreTools.Filtering #region Filter Population - /// - /// Populate the filters object using a set of key:value filters - /// - /// List of key:value where ~key/!key is negated - public abstract void PopulateFromList(List filters); - /// /// Split the parts of a filter statement /// diff --git a/SabreTools.Filtering/MachineFilter.cs b/SabreTools.Filtering/MachineFilter.cs index 34f33b21..38639001 100644 --- a/SabreTools.Filtering/MachineFilter.cs +++ b/SabreTools.Filtering/MachineFilter.cs @@ -112,25 +112,6 @@ namespace SabreTools.Filtering #region Filter Population - /// - /// Populate the filters object using a set of key:value filters - /// - /// List of key:value where ~key/!key is negated - public override void PopulateFromList(List filters) - { - foreach (string filterPair in filters) - { - (string field, string value, bool negate) = ProcessFilterPair(filterPair); - - // If we don't even have a possible filter pair - if (field == null && value == null) - continue; - - MachineField filterField = field.AsMachineField(); - SetFilter(filterField, value, negate); - } - } - /// /// Set multiple filters from key /// diff --git a/SabreTools/Features/BaseFeature.cs b/SabreTools/Features/BaseFeature.cs index 1e74267e..5e0b914e 100644 --- a/SabreTools/Features/BaseFeature.cs +++ b/SabreTools/Features/BaseFeature.cs @@ -2698,9 +2698,7 @@ Some special strings that can be used: // Populate filters List filterPairs = GetList(features, FilterListValue); - cleaner.DatHeaderFilter.PopulateFromList(filterPairs); - cleaner.DatItemFilter.PopulateFromList(filterPairs); - cleaner.MachineFilter.PopulateFromList(filterPairs); + cleaner.PopulateFromList(filterPairs); // Include 'of" in game filters cleaner.MachineFilter.IncludeOfInGame = GetBoolean(features, MatchOfTagsValue);