Skip to content

Commit 7998e83

Browse files
committed
extract registry api to subcrate
1 parent 46513aa commit 7998e83

File tree

17 files changed

+207
-169
lines changed

17 files changed

+207
-169
lines changed

Cargo.lock

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ tracing = "0.1.37"
4646
url = { version = "2.1.1", features = ["serde"] }
4747

4848
[dependencies]
49-
docs_rs_fastly = { path = "crates/lib/docs_rs_fastly" }
5049
docs_rs_env_vars = { path = "crates/lib/docs_rs_env_vars" }
50+
docs_rs_fastly = { path = "crates/lib/docs_rs_fastly" }
5151
docs_rs_headers = { path = "crates/lib/docs_rs_headers" }
5252
docs_rs_logging = { path = "crates/lib/docs_rs_logging" }
5353
docs_rs_opentelemetry = { path = "crates/lib/docs_rs_opentelemetry" }
54+
docs_rs_registry_api = { path = "crates/lib/docs_rs_registry_api" }
5455
docs_rs_types = { path = "crates/lib/docs_rs_types" }
5556
docs_rs_uri = { path = "crates/lib/docs_rs_uri" }
5657
docs_rs_utils = { path = "crates/lib/docs_rs_utils" }
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "docs_rs_registry_api"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
anyhow = { workspace = true }
8+
bincode = { workspace = true }
9+
chrono = { workspace = true }
10+
docs_rs_env_vars = { path = "../docs_rs_env_vars" }
11+
docs_rs_types = { path = "../docs_rs_types" }
12+
docs_rs_utils = { path = "../docs_rs_utils" }
13+
reqwest = { workspace = true }
14+
serde = { workspace = true }
15+
sqlx = { workspace = true }
16+
tracing = { workspace = true }
17+
url = { workspace = true }

src/registry_api.rs renamed to crates/lib/docs_rs_registry_api/src/api.rs

Lines changed: 15 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
use crate::{APP_USER_AGENT, error::Result};
2-
use anyhow::{Context, anyhow, bail};
1+
use crate::{
2+
Config,
3+
models::{CrateData, CrateOwner, OwnerKind, ReleaseData, Search, SearchCrate, SearchMeta},
4+
};
5+
use anyhow::{Context, Result, anyhow, bail};
36
use chrono::{DateTime, Utc};
47
use docs_rs_types::Version;
5-
use docs_rs_utils::retry_async;
8+
use docs_rs_utils::{APP_USER_AGENT, retry_async};
69
use reqwest::header::{ACCEPT, HeaderValue, USER_AGENT};
7-
use serde::{Deserialize, Serialize};
8-
use std::fmt;
10+
use serde::Deserialize;
911
use tracing::instrument;
1012
use url::Url;
1113

@@ -16,84 +18,14 @@ pub struct RegistryApi {
1618
client: reqwest::Client,
1719
}
1820

19-
#[derive(Debug)]
20-
pub struct CrateData {
21-
pub(crate) owners: Vec<CrateOwner>,
22-
}
23-
24-
#[derive(Debug)]
25-
pub(crate) struct ReleaseData {
26-
pub(crate) release_time: DateTime<Utc>,
27-
pub(crate) yanked: bool,
28-
pub(crate) downloads: i32,
29-
}
30-
31-
impl Default for ReleaseData {
32-
fn default() -> ReleaseData {
33-
ReleaseData {
34-
release_time: Utc::now(),
35-
yanked: false,
36-
downloads: 0,
37-
}
38-
}
39-
}
40-
41-
#[derive(Debug, Clone)]
42-
pub struct CrateOwner {
43-
pub(crate) avatar: String,
44-
pub(crate) login: String,
45-
pub(crate) kind: OwnerKind,
46-
}
47-
48-
#[derive(
49-
Debug,
50-
Clone,
51-
Copy,
52-
PartialEq,
53-
Eq,
54-
PartialOrd,
55-
Ord,
56-
Serialize,
57-
Deserialize,
58-
sqlx::Type,
59-
bincode::Encode,
60-
)]
61-
#[sqlx(type_name = "owner_kind", rename_all = "lowercase")]
62-
#[serde(rename_all = "lowercase")]
63-
pub enum OwnerKind {
64-
User,
65-
Team,
66-
}
67-
68-
impl fmt::Display for OwnerKind {
69-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70-
match self {
71-
Self::User => f.write_str("user"),
72-
Self::Team => f.write_str("team"),
73-
}
21+
impl RegistryApi {
22+
pub fn from_config(config: &Config) -> Result<Self> {
23+
Self::new(
24+
config.registry_api_host.clone(),
25+
config.crates_io_api_call_retries,
26+
)
7427
}
75-
}
76-
77-
#[derive(Deserialize, Debug)]
7828

79-
pub(crate) struct SearchCrate {
80-
pub(crate) name: String,
81-
}
82-
83-
#[derive(Deserialize, Debug)]
84-
85-
pub(crate) struct SearchMeta {
86-
pub(crate) next_page: Option<String>,
87-
pub(crate) prev_page: Option<String>,
88-
}
89-
90-
#[derive(Deserialize, Debug)]
91-
pub(crate) struct Search {
92-
pub(crate) crates: Vec<SearchCrate>,
93-
pub(crate) meta: SearchMeta,
94-
}
95-
96-
impl RegistryApi {
9729
pub fn new(api_base: Url, max_retries: u32) -> Result<Self> {
9830
let headers = vec![
9931
(USER_AGENT, HeaderValue::from_static(APP_USER_AGENT)),
@@ -124,11 +56,7 @@ impl RegistryApi {
12456
}
12557

12658
#[instrument(skip(self))]
127-
pub(crate) async fn get_release_data(
128-
&self,
129-
name: &str,
130-
version: &Version,
131-
) -> Result<ReleaseData> {
59+
pub async fn get_release_data(&self, name: &str, version: &Version) -> Result<ReleaseData> {
13260
let (release_time, yanked, downloads) = self
13361
.get_release_time_yanked_downloads(name, version)
13462
.await
@@ -256,7 +184,7 @@ impl RegistryApi {
256184
}
257185

258186
/// Fetch crates from the registry's API
259-
pub(crate) async fn search(&self, query_params: &str) -> Result<Search> {
187+
pub async fn search(&self, query_params: &str) -> Result<Search> {
260188
#[derive(Deserialize, Debug)]
261189
struct SearchError {
262190
detail: String,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use docs_rs_env_vars::env;
2+
use url::Url;
3+
4+
#[derive(Debug)]
5+
pub struct Config {
6+
pub registry_api_host: Url,
7+
8+
// amount of retries for external API calls, mostly crates.io
9+
pub crates_io_api_call_retries: u32,
10+
}
11+
12+
impl Config {
13+
pub fn from_environment() -> anyhow::Result<Self> {
14+
Ok(Self {
15+
crates_io_api_call_retries: env("DOCSRS_CRATESIO_API_CALL_RETRIES", 3u32)?,
16+
registry_api_host: env(
17+
"DOCSRS_REGISTRY_API_HOST",
18+
"https://crates.io".parse().unwrap(),
19+
)?,
20+
})
21+
}
22+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
mod api;
2+
mod config;
3+
mod models;
4+
5+
pub use api::RegistryApi;
6+
pub use config::Config;
7+
pub use models::{CrateData, CrateOwner, OwnerKind, ReleaseData, Search};
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use chrono::{DateTime, Utc};
2+
use serde::{Deserialize, Serialize};
3+
use std::fmt;
4+
5+
#[derive(Debug)]
6+
pub struct CrateData {
7+
pub owners: Vec<CrateOwner>,
8+
}
9+
10+
#[derive(Debug)]
11+
pub struct ReleaseData {
12+
pub release_time: DateTime<Utc>,
13+
pub yanked: bool,
14+
pub downloads: i32,
15+
}
16+
17+
impl Default for ReleaseData {
18+
fn default() -> ReleaseData {
19+
ReleaseData {
20+
release_time: Utc::now(),
21+
yanked: false,
22+
downloads: 0,
23+
}
24+
}
25+
}
26+
27+
#[derive(Debug, Clone)]
28+
pub struct CrateOwner {
29+
pub avatar: String,
30+
pub login: String,
31+
pub kind: OwnerKind,
32+
}
33+
34+
#[derive(
35+
Debug,
36+
Clone,
37+
Copy,
38+
PartialEq,
39+
Eq,
40+
PartialOrd,
41+
Ord,
42+
Serialize,
43+
Deserialize,
44+
sqlx::Type,
45+
bincode::Encode,
46+
)]
47+
#[sqlx(type_name = "owner_kind", rename_all = "lowercase")]
48+
#[serde(rename_all = "lowercase")]
49+
pub enum OwnerKind {
50+
User,
51+
Team,
52+
}
53+
54+
impl fmt::Display for OwnerKind {
55+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56+
match self {
57+
Self::User => f.write_str("user"),
58+
Self::Team => f.write_str("team"),
59+
}
60+
}
61+
}
62+
63+
#[derive(Deserialize, Debug)]
64+
pub struct SearchCrate {
65+
pub name: String,
66+
}
67+
68+
#[derive(Deserialize, Debug)]
69+
pub struct SearchMeta {
70+
pub next_page: Option<String>,
71+
pub prev_page: Option<String>,
72+
}
73+
74+
#[derive(Deserialize, Debug)]
75+
pub struct Search {
76+
pub crates: Vec<SearchCrate>,
77+
pub meta: SearchMeta,
78+
}

src/config.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@ use std::{
66
path::{self, Path, PathBuf},
77
time::Duration,
88
};
9-
use url::Url;
109

1110
#[derive(Debug, derive_builder::Builder)]
1211
#[builder(pattern = "owned")]
1312
pub struct Config {
1413
pub prefix: PathBuf,
1514
pub registry_index_path: PathBuf,
1615
pub registry_url: Option<String>,
17-
pub registry_api_host: Url,
1816

1917
/// How long to wait between registry checks
2018
pub(crate) delay_between_registry_fetches: Duration,
@@ -53,9 +51,6 @@ pub struct Config {
5351
// constant_time_eq for comparisons!)
5452
pub(crate) cratesio_token: Option<String>,
5553

56-
// amount of retries for external API calls, mostly crates.io
57-
pub crates_io_api_call_retries: u32,
58-
5954
// request timeout in seconds
6055
pub(crate) request_timeout: Option<Duration>,
6156
pub(crate) report_request_timeouts: bool,
@@ -135,6 +130,7 @@ pub struct Config {
135130

136131
pub(crate) fastly: docs_rs_fastly::Config,
137132
pub(crate) opentelemetry: docs_rs_opentelemetry::Config,
133+
pub(crate) registry_api: docs_rs_registry_api::Config,
138134
}
139135

140136
impl Config {
@@ -171,13 +167,8 @@ impl Config {
171167
"DOCSRS_DELAY_BETWEEN_REGISTRY_FETCHES",
172168
60,
173169
)?))
174-
.crates_io_api_call_retries(env("DOCSRS_CRATESIO_API_CALL_RETRIES", 3u32)?)
175170
.registry_index_path(env("REGISTRY_INDEX_PATH", prefix.join("crates.io-index"))?)
176171
.registry_url(maybe_env("REGISTRY_URL")?)
177-
.registry_api_host(env(
178-
"DOCSRS_REGISTRY_API_HOST",
179-
"https://crates.io".parse().unwrap(),
180-
)?)
181172
.prefix(prefix.clone())
182173
.database_url(require_env("DOCSRS_DATABASE_URL")?)
183174
.max_pool_size(env("DOCSRS_MAX_POOL_SIZE", 90u32)?)
@@ -237,7 +228,8 @@ impl Config {
237228
docs_rs_fastly::Config::from_environment()
238229
.context("error reading fastly config from environment")?,
239230
)
240-
.opentelemetry(docs_rs_opentelemetry::Config::from_environment()?))
231+
.opentelemetry(docs_rs_opentelemetry::Config::from_environment()?)
232+
.registry_api(docs_rs_registry_api::Config::from_environment()?))
241233
}
242234

243235
pub fn max_file_size_for(&self, path: impl AsRef<Path>) -> usize {

src/context.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::{
2-
AsyncBuildQueue, AsyncStorage, BuildQueue, Config, RegistryApi, Storage, db::Pool,
2+
AsyncBuildQueue, AsyncStorage, BuildQueue, Config, Storage, db::Pool,
33
repositories::RepositoryStatsUpdater,
44
};
55
use anyhow::Result;
66
use docs_rs_fastly::Cdn;
77
use docs_rs_opentelemetry::{AnyMeterProvider, get_meter_provider};
8+
use docs_rs_registry_api::RegistryApi;
89
use std::sync::Arc;
910
use tokio::runtime;
1011

@@ -82,10 +83,7 @@ impl Context {
8283
async_storage,
8384
cdn,
8485
pool: pool.clone(),
85-
registry_api: Arc::new(RegistryApi::new(
86-
config.registry_api_host.clone(),
87-
config.crates_io_api_call_retries,
88-
)?),
86+
registry_api: Arc::new(RegistryApi::from_config(&config.registry_api)?),
8987
repository_stats_updater: Arc::new(RepositoryStatsUpdater::new(&config, pool)),
9088
runtime,
9189
config,

0 commit comments

Comments
 (0)