loadsmith_thunderstore/
registry.rs1use std::pin::Pin;
2
3use loadsmith_core::{PackageId, PackageRef};
4use loadsmith_registry::{Registry, ResolvedVersion, VersionInfo};
5
6use crate::{Error, in_memory::InMemoryIndex, sqlite::SqliteIndex};
7
8#[derive(Debug, Clone)]
21pub struct ThunderstoreRegistry {
22 _client: thunderstore::Client,
23 index: Index,
24}
25
26#[derive(Debug, Clone)]
27enum Index {
28 InMemory(InMemoryIndex),
29 Sqlite(SqliteIndex),
30}
31
32impl ThunderstoreRegistry {
33 fn new(client: thunderstore::Client, index: Index) -> Self {
34 Self {
35 _client: client,
36 index,
37 }
38 }
39
40 pub fn in_memory(client: thunderstore::Client, index: InMemoryIndex) -> Self {
53 Self::new(client, Index::InMemory(index))
54 }
55
56 pub fn sqlite(client: thunderstore::Client, index: SqliteIndex) -> Self {
70 Self::new(client, Index::Sqlite(index))
71 }
72
73 pub async fn update(&self, community: impl Into<String>) -> Result<(), Error> {
90 match &self.index {
91 Index::InMemory(in_memory_index) => in_memory_index.update(community).await,
92 Index::Sqlite(sqlite_index) => sqlite_index.update(community.into()).await,
93 }
94 }
95}
96
97impl Default for ThunderstoreRegistry {
98 fn default() -> Self {
99 let client = thunderstore::Client::default();
100 Self::in_memory(client.clone(), InMemoryIndex::new(client))
101 }
102}
103
104impl Registry for ThunderstoreRegistry {
105 fn version_info<'a>(
106 &'a self,
107 id: &'a PackageId,
108 _metadata: Option<&'a serde_json::Value>,
109 ) -> Pin<Box<dyn Future<Output = loadsmith_registry::Result<Vec<VersionInfo>>> + 'a>> {
110 Box::pin(async move {
111 match &self.index {
112 Index::InMemory(in_memory_index) => in_memory_index.version_info(id).await,
113 Index::Sqlite(sqlite_index) => sqlite_index.version_info(id),
114 }
115 .map_err(loadsmith_registry::Error::other)?
116 .ok_or(loadsmith_registry::Error::PackageNotFound)
117 })
118 }
119
120 fn resolve<'a>(
121 &'a self,
122 ref_: &'a PackageRef,
123 _metadata: Option<&'a serde_json::Value>,
124 ) -> Pin<Box<dyn Future<Output = loadsmith_registry::Result<ResolvedVersion>> + 'a>> {
125 Box::pin(async move {
126 match &self.index {
127 Index::InMemory(in_memory_index) => in_memory_index.resolve(ref_).await,
128 Index::Sqlite(sqlite_index) => sqlite_index.resolve(ref_),
129 }
130 .map_err(loadsmith_registry::Error::other)?
131 .ok_or(loadsmith_registry::Error::VersionNotFound)
132 })
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::*;
139
140 #[tokio::test]
141 #[ignore = "requires network access"]
142 async fn get_package() {
143 let registry = ThunderstoreRegistry::default();
144 registry.update("rounds").await.unwrap();
145
146 let package = PackageId::new("BepInEx-BepInExPack_ROUNDS");
147
148 let versions = registry.version_info(&package, None).await.unwrap();
149
150 println!("{versions:#?}");
151 }
152}