use std::path::PathBuf;
use std::time::Duration;
pub const DEFAULT_CRATES_IO_ENDPOINT: &str = "https://crates.io";
pub const DEFAULT_GITHUB_ENDPOINT: &str = "https://api.github.com";
pub const DEFAULT_RAW_GITHUB_ENDPOINT: &str = "https://raw.githubusercontent.com";
pub const DEFAULT_INDEX_URL: &str =
"https://raw.githubusercontent.com/lordmacu/nexo-plugin-index/main/index.json";
pub const DEFAULT_CACHE_TTL: Duration = Duration::from_secs(24 * 3600);
pub const DEFAULT_HTTP_TIMEOUT: Duration = Duration::from_secs(10);
pub const DEFAULT_OFFICIAL_OWNERS: &[&str] = &["lordmacu", "nexo-rs"];
#[derive(Debug, Clone)]
pub struct DiscoveryConfig {
pub state_dir: PathBuf,
pub cache_ttl: Duration,
pub crates_io_endpoint: String,
pub github_endpoint: String,
pub raw_github_endpoint: String,
pub index_url: String,
pub http_timeout: Duration,
pub official_owners: Vec<String>,
pub daemon_version: semver::Version,
pub github_token: Option<String>,
}
impl DiscoveryConfig {
pub fn with_defaults(state_dir: PathBuf, daemon_version: semver::Version) -> Self {
Self {
state_dir,
cache_ttl: DEFAULT_CACHE_TTL,
crates_io_endpoint: DEFAULT_CRATES_IO_ENDPOINT.into(),
github_endpoint: DEFAULT_GITHUB_ENDPOINT.into(),
raw_github_endpoint: DEFAULT_RAW_GITHUB_ENDPOINT.into(),
index_url: DEFAULT_INDEX_URL.into(),
http_timeout: DEFAULT_HTTP_TIMEOUT,
official_owners: DEFAULT_OFFICIAL_OWNERS
.iter()
.map(|s| (*s).to_string())
.collect(),
daemon_version,
github_token: None,
}
}
pub fn cache_file_path(&self) -> PathBuf {
self.state_dir
.join("plugin-discovery")
.join("catalogue.json")
}
}
#[cfg(test)]
mod tests {
use super::*;
fn cfg() -> DiscoveryConfig {
DiscoveryConfig::with_defaults(
PathBuf::from("/tmp/nexo-state"),
semver::Version::parse("0.2.0").unwrap(),
)
}
#[test]
fn defaults_match_baked_constants() {
let c = cfg();
assert_eq!(c.cache_ttl, DEFAULT_CACHE_TTL);
assert_eq!(c.crates_io_endpoint, DEFAULT_CRATES_IO_ENDPOINT);
assert_eq!(c.github_endpoint, DEFAULT_GITHUB_ENDPOINT);
assert_eq!(c.index_url, DEFAULT_INDEX_URL);
assert_eq!(c.http_timeout, DEFAULT_HTTP_TIMEOUT);
assert!(c.github_token.is_none());
}
#[test]
fn official_owners_seeded_from_constant() {
let c = cfg();
assert!(c.official_owners.iter().any(|o| o == "lordmacu"));
assert!(c.official_owners.iter().any(|o| o == "nexo-rs"));
}
#[test]
fn cache_file_path_lives_under_plugin_discovery_subdir() {
let c = cfg();
let p = c.cache_file_path();
assert!(
p.ends_with("plugin-discovery/catalogue.json"),
"unexpected cache path: {}",
p.display()
);
}
}