-
Notifications
You must be signed in to change notification settings - Fork 808
Expand file tree
/
Copy pathCratesIOClient.cs
More file actions
102 lines (88 loc) · 3.42 KB
/
CratesIOClient.cs
File metadata and controls
102 lines (88 loc) · 3.42 KB
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System.Text.Json;
using UniGetUI.Core.Data;
using UniGetUI.Core.Tools;
namespace UniGetUI.PackageEngine.Managers.CargoManager;
internal record CargoManifest
{
public CargoManifestCategory[]? categories { get; init; }
public required CargoManifestCrate crate { get; init; }
public required CargoManifestVersion[] versions { get; init; }
}
internal record CargoManifestCategory
{
public required string category { get; init; }
public required string description { get; init; }
public required string id { get; init; }
}
internal record CargoManifestCrate
{
public string[]? categories { get; init; }
public string? description { get; init; }
public string? documentation { get; init; }
public double? downloads { get; init; }
public string? homepage { get; init; }
public string[]? keywords { get; init; }
public required string max_stable_version { get; init; }
public required string max_version { get; init; }
public required string name { get; init; }
public required string newest_version { get; init; }
public string? repository { get; init; }
public string? updated_at { get; init; }
}
internal record CargoManifestVersion
{
public string[]? bin_names { get; init; }
public required string checksum { get; init; }
public double? crate_size { get; init; }
public string? created_at { get; init; }
public required string dl_path { get; init; }
public string? license { get; init; }
public required string num { get; init; }
public CargoManifestPublisher? published_by { get; init; }
public string? updated_at { get; init; }
public bool yanked { get; init; }
}
internal record CargoManifestVersionWrapper
{
public required CargoManifestVersion version { get; init; }
}
internal class CargoManifestPublisher
{
public string? avatar { get; init; }
public required string name { get; init; }
public string? url { get; init; }
}
internal class CratesIOClient
{
public const string ApiUrl = "https://crates.io/api/v1";
public static Tuple<Uri, CargoManifest> GetManifest(string packageId)
{
var manifestUrl = new Uri($"{ApiUrl}/crates/{packageId}");
var manifest = Fetch<CargoManifest>(manifestUrl);
if (manifest.crate is null)
{
throw new NullResponseException($"Null response for package {packageId}");
}
return Tuple.Create(manifestUrl, manifest);
}
public static CargoManifestVersion GetManifestVersion(string packageId, string version)
{
var manifestUrl = new Uri($"{ApiUrl}/crates/{packageId}/{version}");
var manifest = Fetch<CargoManifestVersionWrapper>(manifestUrl);
if (manifest.version is null)
{
throw new NullResponseException($"Null response for package {packageId}");
}
return manifest.version;
}
private static T Fetch<T>(Uri url)
{
HttpClient client = new(CoreTools.GenericHttpClientParameters);
client.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString);
var manifestStr = client.GetStringAsync(url).GetAwaiter().GetResult();
var manifest = JsonSerializer.Deserialize<T>(manifestStr, options: SerializationHelpers.DefaultOptions)
?? throw new NullResponseException($"Null response for request to {url}");
return manifest;
}
}
public class NullResponseException(string message) : Exception(message);