diff --git a/src/Apis/Bing/BingVisualSearch.cs b/src/Apis/Bing/BingVisualSearch.cs
index e582462..d7b0f43 100644
--- a/src/Apis/Bing/BingVisualSearch.cs
+++ b/src/Apis/Bing/BingVisualSearch.cs
@@ -56,7 +56,7 @@ public BingVisualSearch(HttpClient httpClient)
}
///
- public async Task> ReverseImageSearchAsync(string url,
+ public async Task> ReverseImageSearchAsync(string url,
BingSafeSearchLevel safeSearch = BingSafeSearchLevel.Moderate, string? language = null,
CancellationToken cancellationToken = default)
{
@@ -83,19 +83,18 @@ public async Task> ReverseImageSearch
throw new BingException(message, imageCategory);
}
- var root = document.RootElement.Clone();
-
- var rawItems = root
+ return document.RootElement
.GetProperty("tags")
.EnumerateArray()
.Select(x => x.GetPropertyOrDefault("actions"))
.SelectMany(x => x.EnumerateArrayOrEmpty())
- .FirstOrDefault(x => x.GetPropertyOrDefault("actionType").GetStringOrDefault() == "VisualSearch")
+ .FirstOrDefault(x => x.TryGetProperty("actionType", out var actionTye) && actionTye.ValueEquals("VisualSearch"u8))
.GetPropertyOrDefault("data")
.GetPropertyOrDefault("value")
- .EnumerateArrayOrEmpty();
-
- return rawItems.Select(item => item.Deserialize()!);
+ .EnumerateArrayOrEmpty()
+ .Select(item => item.Deserialize()!)
+ .ToArray()
+ .AsReadOnly();
}
///
@@ -112,7 +111,7 @@ public void Dispose()
private static HttpRequestMessage BuildRequest(string url, string invokedSkill, BingSafeSearchLevel safeSearch = BingSafeSearchLevel.Moderate, string? language = null)
{
- string jsonRequest = $$"""{"imageInfo":{"url":"{{url}}","source":"Url"},"knowledgeRequest":{"invokedSkills":["{{invokedSkill}}"]}}""";
+ string jsonRequest = $$$"""{"imageInfo":{"url":"{{{url}}}","source":"Url"},"knowledgeRequest":{"invokedSkills":["{{{invokedSkill}}}"]}}""";
var content = new MultipartFormDataContent
{
{ new StringContent(jsonRequest), "knowledgeRequest" }
diff --git a/src/Apis/Bing/IBingVisualSearch.cs b/src/Apis/Bing/IBingVisualSearch.cs
index 994b399..01dae9b 100644
--- a/src/Apis/Bing/IBingVisualSearch.cs
+++ b/src/Apis/Bing/IBingVisualSearch.cs
@@ -16,8 +16,8 @@ public interface IBingVisualSearch
/// The safe search level.
/// The language of the results.
/// The cancellation token.
- /// A representing the asynchronous search operation. The result contains an of search results.
- Task> ReverseImageSearchAsync(string url,
+ /// A representing the asynchronous search operation. The result contains a read-only list of search results.
+ Task> ReverseImageSearchAsync(string url,
BingSafeSearchLevel safeSearch = BingSafeSearchLevel.Moderate, string? language = null,
CancellationToken cancellationToken = default);
}
\ No newline at end of file
diff --git a/src/Modules/ImageModule.cs b/src/Modules/ImageModule.cs
index 7c123d1..14009aa 100644
--- a/src/Modules/ImageModule.cs
+++ b/src/Modules/ImageModule.cs
@@ -337,13 +337,12 @@ public virtual async Task BingAsync(string url, bool multiImages,
}
bool isNsfw = Context.Channel.IsNsfw();
- IBingReverseImageSearchResult[] results;
+ IReadOnlyList results;
_logger.LogInformation("Sending Bing reverse image search request (URL: {Url}, is NSFW: {IsNsfw}, language: {Language})", url, isNsfw, interaction.GetLanguageCode());
try
{
- results = (await _bingVisualSearch.ReverseImageSearchAsync(url, isNsfw ? BingSafeSearchLevel.Off : BingSafeSearchLevel.Strict, interaction.GetLanguageCode()))
- .ToArray();
+ results = await _bingVisualSearch.ReverseImageSearchAsync(url, isNsfw ? BingSafeSearchLevel.Off : BingSafeSearchLevel.Strict, interaction.GetLanguageCode());
}
catch (BingException e)
{
@@ -351,15 +350,15 @@ public virtual async Task BingAsync(string url, bool multiImages,
return FergunResult.FromError(e.ImageCategory is null ? e.Message : _localizer[$"Bing{e.ImageCategory}"], ephemeral, interaction);
}
- _logger.LogDebug("Bing reverse image search result count: {Count}", results.Length);
+ _logger.LogDebug("Bing reverse image search result count: {Count}", results.Count);
- if (results.Length == 0)
+ if (results.Count == 0)
{
return FergunResult.FromError(_localizer["NoResults"], ephemeral, interaction);
}
int count = multiImages ? 4 : 1;
- int maxIndex = (int)Math.Ceiling((double)results.Length / count) - 1;
+ int maxIndex = (int)Math.Ceiling((double)results.Count / count) - 1;
var paginator = new LazyPaginatorBuilder()
.WithPageFactory(GeneratePage)
diff --git a/tests/Fergun.Tests/Apis/BingVisualSearchTests.cs b/tests/Fergun.Tests/Apis/BingVisualSearchTests.cs
index 5f09b67..076309d 100644
--- a/tests/Fergun.Tests/Apis/BingVisualSearchTests.cs
+++ b/tests/Fergun.Tests/Apis/BingVisualSearchTests.cs
@@ -1,6 +1,5 @@
using System;
using System.Drawing;
-using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Fergun.Apis.Bing;
@@ -19,7 +18,7 @@ public class BingVisualSearchTests
[InlineData("https://r.bing.com/rp/NFrQjXWivF4omoTPSU03A6aosg0.jpg", BingSafeSearchLevel.Strict, "es")]
public async Task ReverseImageSearchAsync_Returns_Results(string url, BingSafeSearchLevel safeSearch, string? language)
{
- var results = (await _bingVisualSearch.ReverseImageSearchAsync(url, safeSearch, language)).ToArray();
+ var results = await _bingVisualSearch.ReverseImageSearchAsync(url, safeSearch, language);
Assert.NotNull(results);
Assert.NotEmpty(results);
diff --git a/tests/Fergun.Tests/Utils.cs b/tests/Fergun.Tests/Utils.cs
index 526eb8e..7981031 100644
--- a/tests/Fergun.Tests/Utils.cs
+++ b/tests/Fergun.Tests/Utils.cs
@@ -127,8 +127,8 @@ public static IBingVisualSearch CreateMockedBingVisualSearchApi(Faker? faker = n
faker ??= new Faker();
var bingMock = new Mock();
- bingMock.Setup(x => x.ReverseImageSearchAsync(It.Is(s => s == string.Empty), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Enumerable.Empty);
- bingMock.Setup(x => x.ReverseImageSearchAsync(It.Is(s => !string.IsNullOrEmpty(s)), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(() => faker.MakeLazy(50, () => CreateMockedBingReverseImageSearchResult(faker)));
+ bingMock.Setup(x => x.ReverseImageSearchAsync(It.Is(s => s == string.Empty), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Array.Empty);
+ bingMock.Setup(x => x.ReverseImageSearchAsync(It.Is(s => !string.IsNullOrEmpty(s)), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(() => faker.Make(50, () => CreateMockedBingReverseImageSearchResult(faker)).AsReadOnly());
bingMock.Setup(x => x.ReverseImageSearchAsync(It.Is(s => s == "https://example.com/error"), It.IsAny(), It.IsAny(), It.IsAny())).ThrowsAsync(new BingException("Error message."));
return bingMock.Object;