summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs45
-rw-r--r--src/SMAPI.Web/Framework/Clients/GenericModDownload.cs14
-rw-r--r--src/SMAPI.Web/Framework/IModDownload.cs5
-rw-r--r--src/SMAPI.Web/Framework/ModSiteManager.cs12
4 files changed, 52 insertions, 24 deletions
diff --git a/src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs b/src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs
index 960caf96..7c2cc73c 100644
--- a/src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs
+++ b/src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs
@@ -54,35 +54,44 @@ namespace StardewModdingAPI.Toolkit.Framework.UpdateData
public UpdateKey(ModSiteKey site, string? id, string? subkey)
: this(UpdateKey.GetString(site, id, subkey), site, id, subkey) { }
+ /// <summary>
+ /// Split a string into two at a delimiter. If the delimiter does not appear in the string then the second
+ /// value of the returned tuple is null. Both returned strings are trimmed of whitespace.
+ /// </summary>
+ /// <param name="s">The string to split.</param>
+ /// <param name="delimiter">The character on which to split.</param>
+ /// <param name="keepDelimiter">
+ /// If <c>true</c> then the second string returned will include the delimiter character
+ /// (provided that the string is not <c>null</c>)
+ /// </param>
+ /// <returns>
+ /// A pair containing the string consisting of all characters in <paramref name="s"/> before the first
+ /// occurrence of <paramref name="delimiter"/>, and a string consisting of all characters in <paramref name="s"/>
+ /// after the first occurrence of <paramref name="delimiter"/> or <c>null</c> if the delimiter does not
+ /// exist in s. Both strings are trimmed of whitespace.
+ /// </returns>
+ private static (string, string?) Bifurcate(string s, char delimiter, bool keepDelimiter = false) {
+ int pos = s.IndexOf(delimiter);
+ if (pos < 0)
+ return (s.Trim(), null);
+ return (s.Substring(0, pos).Trim(), s.Substring(pos + (keepDelimiter ? 0 : 1)).Trim());
+ }
+
/// <summary>Parse a raw update key.</summary>
/// <param name="raw">The raw update key to parse.</param>
public static UpdateKey Parse(string? raw)
{
+ if (raw is null)
+ return new UpdateKey(raw, ModSiteKey.Unknown, null, null);
// extract site + ID
- string? rawSite;
- string? id;
- {
- string[]? parts = raw?.Trim().Split(':');
- if (parts?.Length != 2)
- return new UpdateKey(raw, ModSiteKey.Unknown, null, null);
-
- rawSite = parts[0].Trim();
- id = parts[1].Trim();
- }
+ (string rawSite, string? id) = Bifurcate(raw, ':');
if (string.IsNullOrWhiteSpace(id))
id = null;
// extract subkey
string? subkey = null;
if (id != null)
- {
- string[] parts = id.Split('@');
- if (parts.Length == 2)
- {
- id = parts[0].Trim();
- subkey = $"@{parts[1]}".Trim();
- }
- }
+ (id, subkey) = Bifurcate(id, '@', true);
// parse
if (!Enum.TryParse(rawSite, true, out ModSiteKey site))
diff --git a/src/SMAPI.Web/Framework/Clients/GenericModDownload.cs b/src/SMAPI.Web/Framework/Clients/GenericModDownload.cs
index 548f17c3..b37e5cda 100644
--- a/src/SMAPI.Web/Framework/Clients/GenericModDownload.cs
+++ b/src/SMAPI.Web/Framework/Clients/GenericModDownload.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace StardewModdingAPI.Web.Framework.Clients
{
/// <summary>Generic metadata about a file download on a mod page.</summary>
@@ -29,5 +31,17 @@ namespace StardewModdingAPI.Web.Framework.Clients
this.Description = description;
this.Version = version;
}
+
+ /// <summary>
+ /// Return true if the subkey matches this download. A subkey matches if it appears as
+ /// a substring in the name or description.
+ /// </summary>
+ /// <param name="subkey">the subkey</param>
+ /// <returns><c>true</c> if <paramref name="subkey"/> matches this download, otherwise <c>false</c></returns>
+ /// <exception cref="System.NotImplementedException"></exception>
+ public bool MatchesSubkey(string subkey) {
+ return this.Name.Contains(subkey, StringComparison.OrdinalIgnoreCase) == true
+ || this.Description?.Contains(subkey, StringComparison.OrdinalIgnoreCase) == true;
+ }
}
}
diff --git a/src/SMAPI.Web/Framework/IModDownload.cs b/src/SMAPI.Web/Framework/IModDownload.cs
index fe171785..13739f8f 100644
--- a/src/SMAPI.Web/Framework/IModDownload.cs
+++ b/src/SMAPI.Web/Framework/IModDownload.cs
@@ -14,5 +14,10 @@ namespace StardewModdingAPI.Web.Framework
/// <summary>The download's file version.</summary>
string? Version { get; }
+
+ /// <summary>Return <c>true</c> iff the subkey matches this download</summary>
+ /// <param name="subkey">the subkey</param>
+ /// <returns><c>true</c> if <paramref name="subkey"/> matches this download, otherwise <c>false</c></returns>
+ bool MatchesSubkey(string subkey);
}
}
diff --git a/src/SMAPI.Web/Framework/ModSiteManager.cs b/src/SMAPI.Web/Framework/ModSiteManager.cs
index 674b9ffc..70070d63 100644
--- a/src/SMAPI.Web/Framework/ModSiteManager.cs
+++ b/src/SMAPI.Web/Framework/ModSiteManager.cs
@@ -119,7 +119,7 @@ namespace StardewModdingAPI.Web.Framework
preview = null;
// parse all versions from the mod page
- IEnumerable<(string? name, string? description, ISemanticVersion? version)> GetAllVersions()
+ IEnumerable<(IModDownload? download, ISemanticVersion? version)> GetAllVersions()
{
if (mod != null)
{
@@ -132,14 +132,14 @@ namespace StardewModdingAPI.Web.Framework
// get mod version
ISemanticVersion? modVersion = ParseAndMapVersion(mod.Version);
if (modVersion != null)
- yield return (name: null, description: null, version: ParseAndMapVersion(mod.Version));
+ yield return (download: null, version: ParseAndMapVersion(mod.Version));
// get file versions
foreach (IModDownload download in mod.Downloads)
{
ISemanticVersion? cur = ParseAndMapVersion(download.Version);
if (cur != null)
- yield return (download.Name, download.Description, cur);
+ yield return (download, cur);
}
}
}
@@ -148,13 +148,13 @@ namespace StardewModdingAPI.Web.Framework
.ToArray();
// get main + preview versions
- void TryGetVersions([NotNullWhen(true)] out ISemanticVersion? mainVersion, out ISemanticVersion? previewVersion, Func<(string? name, string? description, ISemanticVersion? version), bool>? filter = null)
+ void TryGetVersions([NotNullWhen(true)] out ISemanticVersion? mainVersion, out ISemanticVersion? previewVersion, Func<(IModDownload? download, ISemanticVersion? version), bool>? filter = null)
{
mainVersion = null;
previewVersion = null;
// get latest main + preview version
- foreach ((string? name, string? description, ISemanticVersion? version) entry in versions)
+ foreach ((IModDownload? download, ISemanticVersion? version) entry in versions)
{
if (entry.version is null || filter?.Invoke(entry) == false)
continue;
@@ -178,7 +178,7 @@ namespace StardewModdingAPI.Web.Framework
}
if (subkey is not null)
- TryGetVersions(out main, out preview, entry => entry.name?.Contains(subkey, StringComparison.OrdinalIgnoreCase) == true || entry.description?.Contains(subkey, StringComparison.OrdinalIgnoreCase) == true);
+ TryGetVersions(out main, out preview, entry => entry.download?.MatchesSubkey(subkey) == true);
if (main is null)
TryGetVersions(out main, out preview);