📄
GitHubSearchProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System; using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Net.Http.Json; using System.Runtime.CompilerServices; using System.Threading; using MSearch.Domain; namespace MSearch.SearchProviders.GitHub; internal sealed class GitHubSearchProvider(HttpClient httpClient, string type) : ISearchProvider { public async IAsyncEnumerable<SearchResult> Search( SearchQuery query, [EnumeratorCancellation] CancellationToken cancellationToken ) { var response = await httpClient.GetAsync( $"search/{type}?q={Uri.EscapeDataString(query.Term)}", cancellationToken ); if (response.StatusCode is HttpStatusCode.NotFound) { yield break; } var data = await response.Content.ReadFromJsonAsync( GitHubJsonSerializerContext.Default.GithubResponse, cancellationToken ); if (data is null) { yield break; } foreach (var item in data.Items) { if (Map(item) is { } result) { yield return result; } } } private static SearchResult? Map(GitHubItem item) => (item.Name ?? item.Title) is string title && (item.Description ?? item.Body) is string summary ? new(title, summary, new(item.Url)) : null; }